From 7edb9a2101416f8d48492a7447ff3f693d459f4e Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 9 Oct 2024 16:04:04 +0200 Subject: [PATCH 01/18] Bump github.com/go-acme/lego to v4.19.2 --- docs/content/https/acme.md | 67 +++++++- go.mod | 143 ++++++++------- go.sum | 315 ++++++++++++++++++++-------------- integration/grpc_test.go | 4 +- pkg/provider/acme/provider.go | 16 +- 5 files changed, 331 insertions(+), 214 deletions(-) diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index 07f65b5c3..927cbd695 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -370,6 +370,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) | | [Hosttech](https://www.hosttech.eu) | `hosttech` | `HOSTTECH_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hosttech) | | [http.net](https://www.http.net/) | `httpnet` | `HTTPNET_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/httpnet) | +| [Huawei Cloud](https://huaweicloud.com) | `huaweicloud` | `HUAWEICLOUD_ACCESS_KEY_ID`, `HUAWEICLOUD_SECRET_ACCESS_KEY`, `HUAWEICLOUD_REGION` | [Additional configuration](https://go-acme.github.io/lego/dns/huaweicloud) | | [Hurricane Electric](https://dns.he.net) | `hurricane` | `HURRICANE_TOKENS` [^6] | [Additional configuration](https://go-acme.github.io/lego/dns/hurricane) | | [HyperOne](https://www.hyperone.com) | `hyperone` | `HYPERONE_PASSPORT_LOCATION`, `HYPERONE_LOCATION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/hyperone) | | [IBM Cloud (SoftLayer)](https://www.ibm.com/cloud/) | `ibmcloud` | `SOFTLAYER_USERNAME`, `SOFTLAYER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ibmcloud) | @@ -424,6 +425,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [Scaleway](https://www.scaleway.com) | `scaleway` | `SCW_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) | | [Selectel v2](https://selectel.ru/en/) | `selectelv2` | `SELECTELV2_ACCOUNT_ID`, `SELECTELV2_PASSWORD`, `SELECTELV2_PROJECT_ID`, `SELECTELV2_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/selectelv2) | | [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | +| [SelfHost.(de/eu)](https://www.selfhost.de) | `selfhostde` | `SELFHOSTDE_USERNAME`, `SELFHOSTDE_PASSWORD`, `SELFHOSTDE_RECORDS_MAPPING` | [Additional configuration](https://go-acme.github.io/lego/dns/selfhostde) | | [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) | | [Shellrent](https://www.shellrent.com) | `shellrent` | `SHELLRENT_USERNAME`, `SHELLRENT_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/shellrent) | | [Simply.com](https://www.simply.com/en/domains/) | `simply` | `SIMPLY_ACCOUNT_NAME`, `SIMPLY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/simply) | @@ -460,11 +462,6 @@ For complete details, refer to your provider's _Additional configuration_ link. [^5]: The `Global API Key` needs to be used, not the `Origin CA Key`. [^6]: As explained in the [LEGO hurricane configuration](https://go-acme.github.io/lego/dns/hurricane/#credentials), each domain or wildcard (record name) needs a token. So each update of record name must be followed by an update of the `HURRICANE_TOKENS` variable, and a restart of Traefik. -!!! info "`delayBeforeCheck`" - By default, the `provider` verifies the TXT record _before_ letting ACME verify. - You can delay this operation by specifying a delay (in seconds) with `delayBeforeCheck` (value must be greater than zero). - This option is useful when internal networks block external DNS queries. - #### `resolvers` Use custom DNS servers to resolve the FQDN authority. @@ -494,6 +491,66 @@ certificatesResolvers: --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53 ``` +#### `delayBeforeCheck` + +By default, the `provider` verifies the TXT record _before_ letting ACME verify. + +You can delay this operation by specifying a delay (in seconds) with `delayBeforeCheck` (value must be greater than zero). + +This option is useful when internal networks block external DNS queries. + +```yaml tab="File (YAML)" +certificatesResolvers: + myresolver: + acme: + # ... + dnsChallenge: + # ... + delayBeforeCheck: 2s +``` + +```toml tab="File (TOML)" +[certificatesResolvers.myresolver.acme] + # ... + [certificatesResolvers.myresolver.acme.dnsChallenge] + # ... + delayBeforeCheck = "2s" +``` + +```bash tab="CLI" +# ... +--certificatesresolvers.myresolver.acme.dnschallenge.delayBeforeCheck=2s +``` + +#### `disablePropagationCheck` + +**Not recommended** + +Disable the TXT records propagation checks before notifying ACME that the DNS challenge is ready. + +```yaml tab="File (YAML)" +certificatesResolvers: + myresolver: + acme: + # ... + dnsChallenge: + # ... + disablePropagationCheck: true +``` + +```toml tab="File (TOML)" +[certificatesResolvers.myresolver.acme] + # ... + [certificatesResolvers.myresolver.acme.dnsChallenge] + # ... + disablePropagationCheck = true +``` + +```bash tab="CLI" +# ... +--certificatesresolvers.myresolver.acme.dnschallenge.disablePropagationCheck=true +``` + #### Wildcard Domains [ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates. diff --git a/go.mod b/go.mod index efd9b01b1..c9188afe1 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/fatih/structs v1.1.0 github.com/fsnotify/fsnotify v1.7.0 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 // No tag on the repo. - github.com/go-acme/lego/v4 v4.18.0 + github.com/go-acme/lego/v4 v4.19.2 github.com/go-kit/kit v0.13.0 github.com/go-kit/log v0.2.1 github.com/golang/protobuf v1.5.4 @@ -39,7 +39,7 @@ require ( github.com/kvtools/valkeyrie v1.0.0 github.com/kvtools/zookeeper v1.0.2 github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f // No tag on the repo. - github.com/miekg/dns v1.1.59 + github.com/miekg/dns v1.1.62 github.com/mitchellh/copystructure v1.2.0 github.com/mitchellh/hashstructure v1.0.0 github.com/mitchellh/mapstructure v1.5.0 @@ -71,9 +71,9 @@ require ( golang.org/x/mod v0.21.0 golang.org/x/net v0.29.0 golang.org/x/text v0.18.0 - golang.org/x/time v0.5.0 + golang.org/x/time v0.6.0 golang.org/x/tools v0.25.0 - google.golang.org/grpc v1.63.1 + google.golang.org/grpc v1.66.1 gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.26.3 @@ -86,13 +86,15 @@ require ( ) require ( - cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/auth v0.9.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect + cloud.google.com/go/compute/metadata v0.5.1 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect @@ -122,30 +124,30 @@ require ( github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.62.712 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.63.15 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c // indirect - github.com/aws/aws-sdk-go-v2 v1.27.2 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.18 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.18 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 // indirect - github.com/aws/aws-sdk-go-v2/service/lightsail v1.38.3 // indirect - github.com/aws/aws-sdk-go-v2/service/route53 v1.40.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 // indirect - github.com/aws/smithy-go v1.20.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.30.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.33 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.32 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 // indirect + github.com/aws/aws-sdk-go-v2/service/lightsail v1.40.6 // indirect + github.com/aws/aws-sdk-go-v2/service/route53 v1.43.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 // indirect + github.com/aws/smithy-go v1.20.4 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/civo/civogo v0.3.11 // indirect - github.com/cloudflare/cloudflare-go v0.97.0 // indirect + github.com/cloudflare/cloudflare-go v0.104.0 // indirect github.com/containerd/containerd v1.7.20 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect @@ -166,12 +168,13 @@ require ( github.com/elastic/go-windows v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/exoscale/egoscale v0.102.3 // indirect + github.com/exoscale/egoscale/v3 v3.1.5 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.0.1 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -179,13 +182,15 @@ require ( github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect - github.com/go-resty/resty/v2 v2.11.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.16.0 // indirect + github.com/go-resty/resty/v2 v2.13.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/go-viper/mapstructure/v2 v2.0.0 // indirect + github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-zookeeper/zk v1.0.3 // indirect github.com/goccy/go-json v0.10.3 // indirect - github.com/gofrs/flock v0.12.0 // indirect - github.com/gofrs/uuid v4.4.0+incompatible // indirect + github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect @@ -195,11 +200,11 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect - github.com/google/s2a-go v0.1.7 // indirect + github.com/google/s2a-go v0.1.8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.3 // indirect - github.com/gophercloud/gophercloud v1.12.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect + github.com/googleapis/gax-go/v2 v2.13.0 // indirect + github.com/gophercloud/gophercloud v1.14.0 // indirect github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect @@ -210,8 +215,10 @@ require ( github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.114 // indirect github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect @@ -226,7 +233,8 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect github.com/labbsr0x/goh v1.0.1 // indirect - github.com/linode/linodego v1.28.0 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/linode/linodego v1.40.0 // indirect github.com/liquidweb/liquidweb-cli v0.6.9 // indirect github.com/liquidweb/liquidweb-go v1.6.4 // indirect github.com/looplab/fsm v0.1.0 // indirect @@ -260,16 +268,17 @@ require ( github.com/nrdcg/mailinabox v0.2.0 // indirect github.com/nrdcg/namesilo v0.2.1 // indirect github.com/nrdcg/nodion v0.1.0 // indirect - github.com/nrdcg/porkbun v0.3.0 // indirect + github.com/nrdcg/porkbun v0.4.0 // indirect github.com/nzdjb/go-metaname v1.0.0 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/ginkgo/v2 v2.20.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect - github.com/oracle/oci-go-sdk/v65 v65.63.1 // indirect + github.com/oracle/oci-go-sdk/v65 v65.73.0 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect - github.com/ovh/go-ovh v1.5.1 // indirect + github.com/ovh/go-ovh v1.6.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect @@ -283,7 +292,9 @@ require ( github.com/sacloud/go-http v0.1.8 // indirect github.com/sacloud/iaas-api-go v1.12.0 // indirect github.com/sacloud/packages-go v0.0.10 // indirect - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 // indirect github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect github.com/segmentio/fasthash v1.0.3 // indirect github.com/selectel/domains-go v1.1.0 // indirect @@ -295,53 +306,59 @@ require ( github.com/softlayer/softlayer-go v1.1.5 // indirect github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect github.com/sony/gobreaker v0.5.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.898 // indirect - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.898 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1002 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1002 // indirect github.com/tinylib/msgp v1.1.8 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/transip/gotransip/v6 v6.23.0 // indirect - github.com/ultradns/ultradns-go-sdk v1.6.1-20231103022937-8589b6a // indirect + github.com/transip/gotransip/v6 v6.26.0 // indirect + github.com/ultradns/ultradns-go-sdk v1.7.0-20240913052650-970ca9a // indirect github.com/vinyldns/go-vinyldns v0.9.16 // indirect - github.com/vultr/govultr/v3 v3.9.0 // indirect - github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e // indirect - github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 // indirect + github.com/vultr/govultr/v3 v3.9.1 // indirect + github.com/yandex-cloud/go-genproto v0.0.0-20240911120709-1fa0cb6f47c2 // indirect + github.com/yandex-cloud/go-sdk v0.0.0-20240911121212-e4e74d0d02f5 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.elastic.co/apm/module/apmhttp/v2 v2.4.8 // indirect go.elastic.co/fastjson v1.1.0 // indirect - go.etcd.io/etcd/api/v3 v3.5.6 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect - go.etcd.io/etcd/client/v3 v3.5.6 // indirect + go.etcd.io/etcd/api/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.mongodb.org/mongo-driver v1.12.1 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/mock v0.4.0 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.9.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.21.0 // indirect go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.172.0 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/api v0.197.0 // indirect + google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/ns1/ns1-go.v2 v2.9.1 // indirect + gopkg.in/ns1/ns1-go.v2 v2.12.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect diff --git a/go.sum b/go.sum index f1534fff2..25aca9d85 100644 --- a/go.sum +++ b/go.sum @@ -18,14 +18,18 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/auth v0.9.3 h1:VOEUIAADkkLtyfr3BLa3R8Ed/j6w1jTBmARx+wb5w5U= +cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk= +cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= +cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= 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/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.1 h1:NM6oZeZNlYjiwYje+sYFjEpP0Q0zCan1bmQW/KmIrGs= +cloud.google.com/go/compute/metadata v0.5.1/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= 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= @@ -47,12 +51,12 @@ github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 h1:Dy3M9aegiI7d7PF1LUdjbVigJReo+QOceYs github.com/AdamSLevy/jsonrpc2/v14 v14.1.0/go.mod h1:ZakZtbCXxCz82NJvq7MoREtiQesnDfrtF6RFUGzQfLo= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 h1:lpOxwrQ919lCZoNCd69rVt8u1eLZuMORrGXqy8sNf3c= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0/go.mod h1:fSvRkb8d26z9dbL40Uf/OO6Vo9iExtZK3D0ulRV+8M0= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= @@ -155,8 +159,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.712 h1:lM7JnA9dEdDFH9XOgRNQMDTQnOjlLkDTNA7c0aWTQ30= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.712/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= +github.com/aliyun/alibaba-cloud-sdk-go v1.63.15 h1:r2uwBUQhLhcPzaWz9tRJqc8MjYwHb+oF2+Q6467BF14= +github.com/aliyun/alibaba-cloud-sdk-go v1.63.15/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -169,36 +173,36 @@ github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+z github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.44.327 h1:ZS8oO4+7MOBLhkdwIhgtVeDzCeWOlTfKJS7EgggbIEY= github.com/aws/aws-sdk-go v1.44.327/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8= -github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk= -github.com/aws/aws-sdk-go-v2/config v1.27.18/go.mod h1:0xz6cgdX55+kmppvPm2IaKzIXOheGJhAufacPJaXZ7c= -github.com/aws/aws-sdk-go-v2/credentials v1.17.18 h1:D/ALDWqK4JdY3OFgA2thcPO1c9aYTT5STS/CvnkqY1c= -github.com/aws/aws-sdk-go-v2/credentials v1.17.18/go.mod h1:JuitCWq+F5QGUrmMPsk945rop6bB57jdscu+Glozdnc= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 h1:dDgptDO9dxeFkXy+tEgVkzSClHZje/6JkPW5aZyEvrQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5/go.mod h1:gjvE2KBUgUQhcv89jqxrIxH9GaKs1JbZzWejj/DaHGA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 h1:cy8ahBJuhtM8GTTSyOkfy6WVPV1IE+SS5/wfXUYuulw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9/go.mod h1:CZBXGLaJnEZI6EVNcPd7a6B5IC5cA/GkRWtu9fp3S6Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 h1:A4SYk07ef04+vxZToz9LWvAXl9LW0NClpPpMsi31cz0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9/go.mod h1:5jJcHuwDagxN+ErjQ3PU3ocf6Ylc/p9x+BLO/+X4iXw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 h1:o4T+fKxA3gTMcluBNZZXE9DNaMkJuUL1O3mffCUjoJo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11/go.mod h1:84oZdJ+VjuJKs9v1UTC9NaodRZRseOXCTgku+vQJWR8= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.38.3 h1:YdA5QgoYa2wNblkWyZfPlLLYsAEKCwLfdMxpWu16wpM= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.38.3/go.mod h1:T0LiPG5vKHZ7DmOq4Cmw0Kku3tMkaR9AknskS2hUXvI= -github.com/aws/aws-sdk-go-v2/service/route53 v1.40.10 h1:J9uHribwEgHmesH5r0enxsZYyiGBWd2AaExSW2SydqE= -github.com/aws/aws-sdk-go-v2/service/route53 v1.40.10/go.mod h1:tdzmlLwRjsHJjd4XXoSSnubCkVdRa39y4jCp4RACMkY= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 h1:gEYM2GSpr4YNWc6hCd5nod4+d4kd9vWIAWrmGuLdlMw= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.11/go.mod h1:gVvwPdPNYehHSP9Rs7q27U1EU+3Or2ZpXvzAYJNh63w= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 h1:iXjh3uaH3vsVcnyZX7MqCoCfcyxIrVE9iOQruRaWPrQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5/go.mod h1:5ZXesEuy/QcO0WUnt+4sDkxhdXRHTu2yG0uCSH8B6os= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 h1:M/1u4HBpwLuMtjlxuI2y6HoVLzF5e2mfxHCg7ZVMYmk= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.12/go.mod h1:kcfd+eTdEi/40FIbLq4Hif3XMXnl5b/+t/KTfLt9xIk= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/aws-sdk-go-v2 v1.30.5 h1:mWSRTwQAb0aLE17dSzztCVJWI9+cRMgqebndjwDyK0g= +github.com/aws/aws-sdk-go-v2 v1.30.5/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= +github.com/aws/aws-sdk-go-v2/config v1.27.33 h1:Nof9o/MsmH4oa0s2q9a0k7tMz5x/Yj5k06lDODWz3BU= +github.com/aws/aws-sdk-go-v2/config v1.27.33/go.mod h1:kEqdYzRb8dd8Sy2pOdEbExTTF5v7ozEXX0McgPE7xks= +github.com/aws/aws-sdk-go-v2/credentials v1.17.32 h1:7Cxhp/BnT2RcGy4VisJ9miUPecY+lyE9I8JvcZofn9I= +github.com/aws/aws-sdk-go-v2/credentials v1.17.32/go.mod h1:P5/QMF3/DCHbXGEGkdbilXHsyTBX5D3HSwcrSc9p20I= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 h1:pfQ2sqNpMVK6xz2RbqLEL0GH87JOwSxPV2rzm8Zsb74= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13/go.mod h1:NG7RXPUlqfsCLLFfi0+IpKN4sCB9D9fw/qTaSB+xRoU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17/go.mod h1:aLJpZlCmjE+V+KtN1q1uyZkfnUWpQGpbsn89XPKyzfU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 h1:rfprUlsdzgl7ZL2KlXiUAoJnI/VxfHCvDFr2QDFj6u4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19/go.mod h1:SCWkEdRq8/7EK60NcvvQ6NXKuTcchAD4ROAsC37VEZE= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.40.6 h1:ea6TO3HgVeVTB2Ie1djyBFWBOc9CohpKbo/QZbGTCJQ= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.40.6/go.mod h1:D2TUTD3v6AWmE5LzdCXLWNFtoYbSf6IEjKh1ggbuVdw= +github.com/aws/aws-sdk-go-v2/service/route53 v1.43.2 h1:957e1/SwXIfPi/0OUJkH9YnPZRe9G6Kisd/xUhF7AUE= +github.com/aws/aws-sdk-go-v2/service/route53 v1.43.2/go.mod h1:343vcjcyOTuHTBBgUrOxPM36/jE96qLZnGL447ldrB0= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 h1:pIaGg+08llrP7Q5aiz9ICWbY8cqhTkyy+0SHvfzQpTc= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.7/go.mod h1:eEygMHnTKH/3kNp9Jr1n3PdejuSNcgwLe1dWgQtO0VQ= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 h1:/Cfdu0XV3mONYKaOt1Gr0k1KvQzkzPyiKUdlWJqy+J4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7/go.mod h1:bCbAxKDqNvkHxRaIMnyVPXPo+OaPRwvmgzMxbz1VKSA= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 h1:NKTa1eqZYw8tiHSRGpP0VtTdub/8KNk8sDkNPFaOKDE= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.7/go.mod h1:NXi1dIAGteSaRLqYgarlhP/Ij0cFT+qmCwiJqWh/U5o= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -223,8 +227,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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= @@ -233,8 +237,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/civo/civogo v0.3.11 h1:mON/fyrV946Sbk6paRtOSGsN+asCgCmHCgArf5xmGxM= github.com/civo/civogo v0.3.11/go.mod h1:7+GeeFwc4AYTULaEshpT2vIcl3Qq8HPoxA17viX3l6g= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.97.0 h1:feZRGiRF1EbljnNIYdt8014FnOLtC3CCvgkLXu915ks= -github.com/cloudflare/cloudflare-go v0.97.0/go.mod h1:JXRwuTfHpe5xFg8xytc2w0XC6LcrFsBVMS4WlVaiGg8= +github.com/cloudflare/cloudflare-go v0.104.0 h1:R/lB0dZupaZbOgibAH/BRrkFbZ6Acn/WsKg2iX2xXuY= +github.com/cloudflare/cloudflare-go v0.104.0/go.mod h1:pfUQ4PIG4ISI0/Mmc21Bp86UnFU0ktmPf3iTgbSL+cM= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -352,8 +356,8 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/exoscale/egoscale v0.102.3 h1:DYqN2ipoLKpiFoprRGQkp2av/Ze7sUYYlGhi1N62tfY= -github.com/exoscale/egoscale v0.102.3/go.mod h1:RPf2Gah6up+6kAEayHTQwqapzXlm93f0VQas/UEGU5c= +github.com/exoscale/egoscale/v3 v3.1.5 h1:Nsfmqiq/CQJM3Ukqg9/u4rc9Q0QBeTQc3JFPMpFkhJg= +github.com/exoscale/egoscale/v3 v3.1.5/go.mod h1:GHKucK/J26v8PGWztGdhxWNMjrjG9PbelxKCJ4YI11Q= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -374,6 +378,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= 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/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= @@ -382,8 +388,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/go-acme/lego/v4 v4.18.0 h1:2hH8KcdRBSb+p5o9VZIm61GAOXYALgILUCSs1Q+OYsk= -github.com/go-acme/lego/v4 v4.18.0/go.mod h1:Blkg3izvXpl3zxk7WKngIuwR2I/hvYVP3vRnvgBp7m8= +github.com/go-acme/lego/v4 v4.19.2 h1:Y8hrmMvWETdqzzkRly7m98xtPJJivWFsgWi8fcvZo+Y= +github.com/go-acme/lego/v4 v4.19.2/go.mod h1:wtDe3dDkmV4/oI2nydpNXSJpvV10J9RCyZ6MbYxNtlQ= 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= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= @@ -391,8 +397,8 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 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-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= 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.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= @@ -433,20 +439,28 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= -github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= +github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= +github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= +github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= -github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= +github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= @@ -457,10 +471,8 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/flock v0.12.0 h1:xHW8t8GPAiGtqz7KxiSqfOEXwpOaqhpYZrTE2MQBgXY= -github.com/gofrs/flock v0.12.0/go.mod h1:FirDy1Ing0mI2+kB6wk+vyyAH+e6xiE+EYA0jnzV9jc= -github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= -github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -514,6 +526,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= @@ -567,26 +580,26 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= +github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= +github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= 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.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= +github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= 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/gophercloud/gophercloud v1.3.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= -github.com/gophercloud/gophercloud v1.12.0 h1:Jrz16vPAL93l80q16fp8NplrTCp93y7rZh2P3Q4Yq7g= -github.com/gophercloud/gophercloud v1.12.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= +github.com/gophercloud/gophercloud v1.14.0 h1:Bt9zQDhPrbd4qX7EILGmy+i7GP35cc+AAL2+wIJpUE8= +github.com/gophercloud/gophercloud v1.14.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 h1:sH7xkTfYzxIEgzq1tDHIMKRh1vThOEOGNsettdEeLbE= github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56/go.mod h1:VSalo4adEk+3sNkmVJLnhHoOyOYYS8sTWLG4mv5BKto= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -659,6 +672,8 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= @@ -674,6 +689,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.114 h1:X3E16S6AUZsQKhJIQ5kNnylnp0GtSy2YhIbxfvDavtU= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.114/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI= 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= github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E= @@ -741,6 +758,7 @@ github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.17.11-0.20241004063537-dbd6c381492a h1:cwHOqPB4H4iQq8177kf2SxpjNbcjJ2m3lNwKIe28Hqg= github.com/klauspost/compress v1.17.11-0.20241004063537-dbd6c381492a/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= @@ -782,6 +800,8 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= github.com/lestrrat-go/codegen v1.0.2/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= @@ -789,8 +809,8 @@ github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++ github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= github.com/lestrrat-go/jwx v1.2.7/go.mod h1:bw24IXWbavc0R2RsOtpXL7RtMyP589yZ1+L7kd09ZGA= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/linode/linodego v1.28.0 h1:lzxxJebsYg5cCWRNDLyL2StW3sfMyAwf/FYfxFjFrlk= -github.com/linode/linodego v1.28.0/go.mod h1:5oAsx+uinHtVo6U77nXXXtox7MWzUW6aEkTOKXxA9uo= +github.com/linode/linodego v1.40.0 h1:7ESY0PwK94hoggoCtIroT1Xk6b1flrFBNZ6KwqbTqlI= +github.com/linode/linodego v1.40.0/go.mod h1:NsUw4l8QrLdIofRg1NYFBbW5ZERnmbZykVBszPZLORM= github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs= github.com/liquidweb/liquidweb-cli v0.6.9 h1:acbIvdRauiwbxIsOCEMXGwF75aSJDbDiyAWPjVnwoYM= github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wdvmwu8aL9TLmA/eQ= @@ -854,8 +874,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N 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= github.com/miekg/dns v1.1.47/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mimuret/golang-iij-dpf v0.9.1 h1:Gj6EhHJkOhr+q2RnvRPJsPMcjuVnWPSccEHyoEehU34= github.com/mimuret/golang-iij-dpf v0.9.1/go.mod h1:sl9KyOkESib9+KRD3HaGpgi1xk7eoN2+d96LCLsME2M= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -901,6 +921,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -931,8 +952,8 @@ github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/nrdcg/nodion v0.1.0 h1:zLKaqTn2X0aDuBHHfyA1zFgeZfiCpmu/O9DM73okavw= github.com/nrdcg/nodion v0.1.0/go.mod h1:inbuh3neCtIWlMPZHtEpe43TmRXxHV6+hk97iCZicms= -github.com/nrdcg/porkbun v0.3.0 h1:jnRV7j2zd3hmh+tSDOGetJyy3+WklaMxbs7HtTTmWMs= -github.com/nrdcg/porkbun v0.3.0/go.mod h1:jh1DKz96jGHW+NCdG3AmTbbnQeBlNUz1KeSgeN/cBVw= +github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw= +github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -978,12 +999,12 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.5 h1:UwtQQx2pyPIgWYHRg+epgdx1/HnBQTgN3/oIYEJTQzU= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/oracle/oci-go-sdk/v65 v65.63.1 h1:dYL7sk9L1+C9LCmoq+zjPMNteuJJfk54YExq/4pV9xQ= -github.com/oracle/oci-go-sdk/v65 v65.63.1/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0= +github.com/oracle/oci-go-sdk/v65 v65.73.0 h1:C7uel6CoKk4A1KPkdhFBAyvVyFRTHAmX8m0o64RmfPg= +github.com/oracle/oci-go-sdk/v65 v65.73.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0= github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= -github.com/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI= -github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= +github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI= +github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -992,6 +1013,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= @@ -1028,7 +1051,6 @@ github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1089,8 +1111,12 @@ github.com/sacloud/iaas-api-go v1.12.0 h1:kqXFn3HzCiawlX6hVJb1GVqcSJqcmiGHB4Zp14 github.com/sacloud/iaas-api-go v1.12.0/go.mod h1:SZLXeWOdXk3WReIS557sbU1gkOgrE4rseIBQV1B3b7o= github.com/sacloud/packages-go v0.0.10 h1:UiQGjy8LretewkRhsuna1TBM9Vz/l9FoYpQx+D+AOck= github.com/sacloud/packages-go v0.0.10/go.mod h1:f8QITBh9z4IZc4yE9j21Q8b0sXEMwRlRmhhjWeDVTYs= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27 h1:yGAraK1uUjlhSXgNMIy8o/J4LFNcy7yeipBqt9N9mVg= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 h1:yoKAVkEVwAqbGbR8n87rHQ1dulL25rKloGadb3vm770= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30/go.mod h1:sH0u6fq6x4R5M7WxkoQFY/o7UaiItec0o1LinLCJNq8= 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/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg= @@ -1133,6 +1159,8 @@ github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVd github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1140,6 +1168,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= @@ -1157,6 +1187,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1176,20 +1208,25 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.898 h1:ERwcXqhc94L9cFxtiI0pvt7IJtlHl/p/Jayl3mLw+ms= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.898/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.898 h1:LoYv5u+gUoFpU/AmIuTRG/2KiEkdm9gCC0dTvk8WITQ= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.898/go.mod h1:c1j6YQ+vCbeA8kJ59Im4UnMd1GxovlpPBDhGZoewfn8= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1002 h1:RE84sHFFx6t24DJvSnF9fS1DzBNv9OpctzHK3t7AY+I= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1002/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1002 h1:QwE0dRkAAbdf+eACnkNULgDn9ZKUJpPWRyXdqJolP5E= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1002/go.mod h1:WdC0FYbqYhJwQ3kbqri6hVP5HAEp+rzX9FToItTAzUg= github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHPS+/alvLJU/DRxTD/ME= github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E= github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -1200,8 +1237,8 @@ github.com/traefik/paerser v0.2.1 h1:LFgeak1NmjEHF53c9ENdXdL1UMkF/lD5t+7Evsz4hH4 github.com/traefik/paerser v0.2.1/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24= github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E= github.com/traefik/yaegi v0.16.1/go.mod h1:4eVhbPb3LnD2VigQjhYbEJ69vDRFdT2HQNrXx8eEwUY= -github.com/transip/gotransip/v6 v6.23.0 h1:PsTdjortrEZ8IFFifEryzjVjOy9SgK4ahlnhKBBIQgA= -github.com/transip/gotransip/v6 v6.23.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c= +github.com/transip/gotransip/v6 v6.26.0 h1:Aejfvh8rSp8Mj2GX/RpdBjMCv+Iy/DmgfNgczPDP550= +github.com/transip/gotransip/v6 v6.26.0/go.mod h1:x0/RWGRK/zob817O3tfO2xhFoP1vu8YOHORx6Jpk80s= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -1211,8 +1248,8 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= -github.com/ultradns/ultradns-go-sdk v1.6.1-20231103022937-8589b6a h1:w4PK5/N9kq8PfNxBv8a5t1bqlYRrVT7XzT7iTPTtiPk= -github.com/ultradns/ultradns-go-sdk v1.6.1-20231103022937-8589b6a/go.mod h1:Xwz7o+ExFtxR/i0aJDnTXuiccQJlOxDgNe6FsZC4TzQ= +github.com/ultradns/ultradns-go-sdk v1.7.0-20240913052650-970ca9a h1:R6IR+Vj/RnGZLnX8PpPQsbbQthctO7Ah2q4tj5eoe2o= +github.com/ultradns/ultradns-go-sdk v1.7.0-20240913052650-970ca9a/go.mod h1:BZr7Qs3ku1ckpqed8tCRSqTlp8NAeZfAVpfx4OzXMss= 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= @@ -1229,16 +1266,20 @@ github.com/vulcand/oxy/v2 v2.0.0 h1:V+scHhd2xBjO8ojBRgxCM+OdZxRA/YTs8M70w5tdNy8= github.com/vulcand/oxy/v2 v2.0.0/go.mod h1:uIAz3sYafO7i+V3SC8oDlMn/lt1i9aWcyXuXqVswKzE= 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/v3 v3.9.0 h1:63V/22mpfquRA5DenJ9EF0VozHg0k+X4dhUWcDXHPyc= -github.com/vultr/govultr/v3 v3.9.0/go.mod h1:Rd8ebpXm7jxH3MDmhnEs+zrlYW212ouhx+HeUMfHm2o= +github.com/vultr/govultr/v3 v3.9.1 h1:uxSIb8Miel7tqTs3ee+z3t+JelZikwqBBsZzCOPBy/8= +github.com/vultr/govultr/v3 v3.9.1/go.mod h1:Rd8ebpXm7jxH3MDmhnEs+zrlYW212ouhx+HeUMfHm2o= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e h1:jLIqA7M9qY31g/Nw/5htVD0DFbxmLnlFZcHKJiG3osI= -github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE= -github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 h1:wtzLQJmghkSUb1YkeFphIh7ST7NNVDaVOJZSAJcjMdw= -github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4/go.mod h1:9d1MV6u4lK715YXnZceKqhP4L0bKBKmv4mSLnVSjJaM= +github.com/yandex-cloud/go-genproto v0.0.0-20240911120709-1fa0cb6f47c2 h1:WgeEP+8WizCQyccJNHOMLONq23qVAzYHtyg5qTdUWmg= +github.com/yandex-cloud/go-genproto v0.0.0-20240911120709-1fa0cb6f47c2/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE= +github.com/yandex-cloud/go-sdk v0.0.0-20240911121212-e4e74d0d02f5 h1:Q4LvUMF4kzaGtopoIdXReL9/qGtmzOewBhF3dQvuHMU= +github.com/yandex-cloud/go-sdk v0.0.0-20240911121212-e4e74d0d02f5/go.mod h1:9dt2V80cfJGRZA+5SKP3Ky+R/DxH02XfKObi2Uy2uPc= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1260,14 +1301,17 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A= -go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= +go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= -go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= +go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E= -go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk= +go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= +go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1277,20 +1321,20 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= @@ -1308,8 +1352,8 @@ go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/ratelimit v0.3.0 h1:IdZd9wqvFXnvLvSEBo0KPcGfkoBGNkpTHlrE3Rcjkjw= go.uber.org/ratelimit v0.3.0/go.mod h1:So5LG7CV1zWpY1sHe+DXTJqQvOx+FFPFaAs2SnoyBaI= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1336,6 +1380,7 @@ golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -1343,12 +1388,14 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1434,6 +1481,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1456,7 +1504,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1471,8 +1520,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -1586,8 +1635,9 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1599,8 +1649,9 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1612,12 +1663,13 @@ 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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1628,8 +1680,9 @@ golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxb 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.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1735,8 +1788,8 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.172.0 h1:/1OcMZGPmW1rX2LCu2CmGUD1KXK1+pfzxotxyRUCCdk= -google.golang.org/api v0.172.0/go.mod h1:+fJZq6QXWfa9pXhnIzsjx4yI22d4aI9ZpLb58gvXjis= +google.golang.org/api v0.197.0 h1:x6CwqQLsFiA5JKAiGyGBjc2bNtHtLddhJCE2IKuhhcQ= +google.golang.org/api v0.197.0/go.mod h1:AuOuo20GoQ331nq7DquGHlU6d+2wN2fZ8O0ta60nRNw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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= @@ -1788,12 +1841,12 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU= +google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= +google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1818,8 +1871,8 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.63.1 h1:pNClQmvdlyNUiwFETOux/PYqfhmA7BrswEdGRnib1fA= -google.golang.org/grpc v1.63.1/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= +google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1834,8 +1887,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 h1:AUe/ZF7xm6vYnigPe+TY54DmfWYJxhMRaw/TfvrbzvE= gopkg.in/DataDog/dd-trace-go.v1 v1.56.1/go.mod h1:KDLJ3CWVOSuVVwu+0ZR5KZo2rP6c7YyBV3v387dIpUU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1858,8 +1911,8 @@ gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/ns1/ns1-go.v2 v2.9.1 h1:3/QYzUazRCSE49d3sh1Q+X7IrDp/I7OqR/M7dKA0Oks= -gopkg.in/ns1/ns1-go.v2 v2.9.1/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc= +gopkg.in/ns1/ns1-go.v2 v2.12.0 h1:cqdqQoTx17JmTusfxh5m3e2b36jfUzFAZedv89pFX18= +gopkg.in/ns1/ns1-go.v2 v2.12.0/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc= 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/integration/grpc_test.go b/integration/grpc_test.go index 0e493fd7e..4aebe3e1e 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -93,7 +93,7 @@ func getHelloClientGRPC() (helloworld.GreeterClient, func() error, error) { roots := x509.NewCertPool() roots.AppendCertsFromPEM(LocalhostCert) credsClient := credentials.NewClientTLSFromCert(roots, "") - conn, err := grpc.Dial("127.0.0.1:4443", grpc.WithTransportCredentials(credsClient)) + conn, err := grpc.NewClient("127.0.0.1:4443", grpc.WithTransportCredentials(credsClient)) if err != nil { return nil, func() error { return nil }, err } @@ -101,7 +101,7 @@ func getHelloClientGRPC() (helloworld.GreeterClient, func() error, error) { } func getHelloClientGRPCh2c() (helloworld.GreeterClient, func() error, error) { - conn, err := grpc.Dial("127.0.0.1:8081", grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient("127.0.0.1:8081", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, func() error { return nil }, err } diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index 2d68a3b3d..66d817993 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -298,19 +298,9 @@ func (p *Provider) getClient() (*lego.Client, error) { } err = client.Challenge.SetDNS01Provider(provider, - dns01.CondOption(len(p.DNSChallenge.Resolvers) > 0, dns01.AddRecursiveNameservers(p.DNSChallenge.Resolvers)), - dns01.WrapPreCheck(func(domain, fqdn, value string, check dns01.PreCheckFunc) (bool, error) { - if p.DNSChallenge.DelayBeforeCheck > 0 { - logger.Debugf("Delaying %d rather than validating DNS propagation now.", p.DNSChallenge.DelayBeforeCheck) - time.Sleep(time.Duration(p.DNSChallenge.DelayBeforeCheck)) - } - - if p.DNSChallenge.DisablePropagationCheck { - return true, nil - } - - return check(fqdn, value) - }), + dns01.CondOption(len(p.DNSChallenge.Resolvers) > 0, + dns01.AddRecursiveNameservers(p.DNSChallenge.Resolvers)), + dns01.PropagationWait(time.Duration(p.DNSChallenge.DelayBeforeCheck), p.DNSChallenge.DisablePropagationCheck), ) if err != nil { return nil, err From ef168b801c43080b373190967c27b48631a009ed Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Thu, 10 Oct 2024 16:04:04 +0200 Subject: [PATCH 02/18] Refactor compress handler to make it generic Co-authored-by: Romain --- pkg/middlewares/compress/compress.go | 33 +++++- .../compress/compression_handler.go | 103 ++++++++---------- .../compress/compression_handler_test.go | 81 +++++++++----- 3 files changed, 125 insertions(+), 92 deletions(-) diff --git a/pkg/middlewares/compress/compress.go b/pkg/middlewares/compress/compress.go index 3ccac9f2d..fc8fe8d96 100644 --- a/pkg/middlewares/compress/compress.go +++ b/pkg/middlewares/compress/compress.go @@ -8,7 +8,9 @@ import ( "net/http" "slices" + "github.com/andybalholm/brotli" "github.com/klauspost/compress/gzhttp" + "github.com/klauspost/compress/zstd" "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/middlewares" "go.opentelemetry.io/otel/trace" @@ -78,12 +80,12 @@ func New(ctx context.Context, next http.Handler, conf dynamic.Compress, name str var err error - c.zstdHandler, err = c.newCompressionHandler(zstdName, name) + c.zstdHandler, err = c.newZstdHandler(name) if err != nil { return nil, err } - c.brotliHandler, err = c.newCompressionHandler(brotliName, name) + c.brotliHandler, err = c.newBrotliHandler(name) if err != nil { return nil, err } @@ -174,13 +176,34 @@ func (c *compress) newGzipHandler() (http.Handler, error) { return wrapper(c.next), nil } -func (c *compress) newCompressionHandler(algo string, middlewareName string) (http.Handler, error) { - cfg := Config{MinSize: c.minSize, Algorithm: algo, MiddlewareName: middlewareName} +func (c *compress) newBrotliHandler(middlewareName string) (http.Handler, error) { + cfg := Config{MinSize: c.minSize, MiddlewareName: middlewareName} if len(c.includes) > 0 { cfg.IncludedContentTypes = c.includes } else { cfg.ExcludedContentTypes = c.excludes } - return NewCompressionHandler(cfg, c.next) + newBrotliWriter := func(rw http.ResponseWriter) (CompressionWriter, string, error) { + return brotli.NewWriter(rw), brotliName, nil + } + return NewCompressionHandler(cfg, newBrotliWriter, c.next) +} + +func (c *compress) newZstdHandler(middlewareName string) (http.Handler, error) { + cfg := Config{MinSize: c.minSize, MiddlewareName: middlewareName} + if len(c.includes) > 0 { + cfg.IncludedContentTypes = c.includes + } else { + cfg.ExcludedContentTypes = c.excludes + } + + newZstdWriter := func(rw http.ResponseWriter) (CompressionWriter, string, error) { + writer, err := zstd.NewWriter(rw) + if err != nil { + return nil, "", fmt.Errorf("creating zstd writer: %w", err) + } + return writer, zstdName, nil + } + return NewCompressionHandler(cfg, newZstdWriter, c.next) } diff --git a/pkg/middlewares/compress/compression_handler.go b/pkg/middlewares/compress/compression_handler.go index a8f08ec83..1c5065ca7 100644 --- a/pkg/middlewares/compress/compression_handler.go +++ b/pkg/middlewares/compress/compression_handler.go @@ -10,8 +10,6 @@ import ( "net/http" "sync" - "github.com/andybalholm/brotli" - "github.com/klauspost/compress/zstd" "github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares/observability" ) @@ -24,6 +22,30 @@ const ( contentType = "Content-Type" ) +// CompressionWriter compresses the written bytes. +type CompressionWriter interface { + // Write data to the encoder. + // Input data will be buffered and as the buffer fills up + // content will be compressed and written to the output. + // When done writing, use Close to flush the remaining output + // and write CRC if requested. + Write(p []byte) (n int, err error) + // Flush will send the currently written data to output + // and block until everything has been written. + // This should only be used on rare occasions where pushing the currently queued data is critical. + Flush() error + // Close closes the underlying writers if/when appropriate. + // Note that the compressed writer should not be closed if we never used it, + // as it would otherwise send some extra "end of compression" bytes. + // Close also makes sure to flush whatever was left to write from the buffer. + Close() error + // Reset reinitializes the state of the encoder, allowing it to be reused. + Reset(w io.Writer) +} + +// NewCompressionWriter returns a new CompressionWriter with its corresponding algorithm. +type NewCompressionWriter func(rw http.ResponseWriter) (CompressionWriter, string, error) + // Config is the Brotli handler configuration. type Config struct { // ExcludedContentTypes is the list of content types for which we should not compress. @@ -34,8 +56,6 @@ type Config struct { IncludedContentTypes []string // MinSize is the minimum size (in bytes) required to enable compression. MinSize int - // Algorithm used for the compression (currently Brotli and Zstandard) - Algorithm string // MiddlewareName use for logging purposes MiddlewareName string } @@ -46,15 +66,13 @@ type CompressionHandler struct { excludedContentTypes []parsedContentType includedContentTypes []parsedContentType next http.Handler - writerPool sync.Pool + + writerPool sync.Pool + newWriter NewCompressionWriter } // NewCompressionHandler returns a new compressing handler. -func NewCompressionHandler(cfg Config, next http.Handler) (http.Handler, error) { - if cfg.Algorithm == "" { - return nil, errors.New("compression algorithm undefined") - } - +func NewCompressionHandler(cfg Config, newWriter NewCompressionWriter, next http.Handler) (http.Handler, error) { if cfg.MinSize < 0 { return nil, errors.New("minimum size must be greater than or equal to zero") } @@ -88,6 +106,7 @@ func NewCompressionHandler(cfg Config, next http.Handler) (http.Handler, error) excludedContentTypes: excludedContentTypes, includedContentTypes: includedContentTypes, next: next, + newWriter: newWriter, }, nil } @@ -117,70 +136,38 @@ func (c *CompressionHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) c.next.ServeHTTP(responseWriter, r) } -type compression interface { - // Write data to the encoder. - // Input data will be buffered and as the buffer fills up - // content will be compressed and written to the output. - // When done writing, use Close to flush the remaining output - // and write CRC if requested. - Write(p []byte) (n int, err error) - // Flush will send the currently written data to output - // and block until everything has been written. - // This should only be used on rare occasions where pushing the currently queued data is critical. - Flush() error - // Close closes the underlying writers if/when appropriate. - // Note that the compressed writer should not be closed if we never used it, - // as it would otherwise send some extra "end of compression" bytes. - // Close also makes sure to flush whatever was left to write from the buffer. - Close() error - // Reset reinitializes the state of the encoder, allowing it to be reused. - Reset(w io.Writer) -} - -type compressionWriter struct { - compression - alg string -} - -func (c *CompressionHandler) getCompressionWriter(rw io.Writer) (*compressionWriter, error) { - if writer, ok := c.writerPool.Get().(*compressionWriter); ok { - writer.compression.Reset(rw) +func (c *CompressionHandler) getCompressionWriter(rw http.ResponseWriter) (*compressionWriterWrapper, error) { + if writer, ok := c.writerPool.Get().(*compressionWriterWrapper); ok { + writer.Reset(rw) return writer, nil } - return newCompressionWriter(c.cfg.Algorithm, rw) + + writer, algo, err := c.newWriter(rw) + if err != nil { + return nil, fmt.Errorf("creating compression writer: %w", err) + } + return &compressionWriterWrapper{CompressionWriter: writer, algo: algo}, nil } -func (c *CompressionHandler) putCompressionWriter(writer *compressionWriter) { +func (c *CompressionHandler) putCompressionWriter(writer *compressionWriterWrapper) { writer.Reset(nil) c.writerPool.Put(writer) } -func newCompressionWriter(algo string, in io.Writer) (*compressionWriter, error) { - switch algo { - case brotliName: - return &compressionWriter{compression: brotli.NewWriter(in), alg: algo}, nil - - case zstdName: - writer, err := zstd.NewWriter(in) - if err != nil { - return nil, fmt.Errorf("creating zstd writer: %w", err) - } - return &compressionWriter{compression: writer, alg: algo}, nil - - default: - return nil, fmt.Errorf("unknown compression algo: %s", algo) - } +type compressionWriterWrapper struct { + CompressionWriter + algo string } -func (c *compressionWriter) ContentEncoding() string { - return c.alg +func (c *compressionWriterWrapper) ContentEncoding() string { + return c.algo } // TODO: check whether we want to implement content-type sniffing (as gzip does) // TODO: check whether we should support Accept-Ranges (as gzip does, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges) type responseWriter struct { rw http.ResponseWriter - compressionWriter *compressionWriter + compressionWriter *compressionWriterWrapper minSize int excludedContentTypes []parsedContentType diff --git a/pkg/middlewares/compress/compression_handler_test.go b/pkg/middlewares/compress/compression_handler_test.go index 1df9e9588..c702500d7 100644 --- a/pkg/middlewares/compress/compression_handler_test.go +++ b/pkg/middlewares/compress/compression_handler_test.go @@ -162,7 +162,7 @@ func Test_NoBody(t *testing.T) { require.NoError(t, err) }) - h := mustNewCompressionHandler(t, Config{MinSize: 1024, Algorithm: zstdName}, next) + h := mustNewCompressionHandler(t, Config{MinSize: 1024}, zstdName, next) req := httptest.NewRequest(http.MethodGet, "/", nil) req.Header.Set(acceptEncoding, "zstd") @@ -181,8 +181,7 @@ func Test_NoBody(t *testing.T) { func Test_MinSize(t *testing.T) { cfg := Config{ - MinSize: 128, - Algorithm: zstdName, + MinSize: 128, } var bodySize int @@ -197,7 +196,7 @@ func Test_MinSize(t *testing.T) { } }) - h := mustNewCompressionHandler(t, cfg, next) + h := mustNewCompressionHandler(t, cfg, zstdName, next) req, _ := http.NewRequest(http.MethodGet, "/whatever", &bytes.Buffer{}) req.Header.Add(acceptEncoding, "zstd") @@ -224,7 +223,7 @@ func Test_MultipleWriteHeader(t *testing.T) { rw.WriteHeader(http.StatusNotFound) }) - h := mustNewCompressionHandler(t, Config{MinSize: 1024, Algorithm: zstdName}, next) + h := mustNewCompressionHandler(t, Config{MinSize: 1024}, zstdName, next) req := httptest.NewRequest(http.MethodGet, "/", nil) req.Header.Set(acceptEncoding, "zstd") @@ -239,12 +238,14 @@ func Test_FlushBeforeWrite(t *testing.T) { testCases := []struct { desc string cfg Config + algo string readerBuilder func(io.Reader) (io.Reader, error) acceptEncoding string }{ { desc: "brotli", - cfg: Config{MinSize: 1024, Algorithm: brotliName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: brotliName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return brotli.NewReader(reader), nil }, @@ -252,7 +253,8 @@ func Test_FlushBeforeWrite(t *testing.T) { }, { desc: "zstd", - cfg: Config{MinSize: 1024, Algorithm: zstdName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: zstdName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return zstd.NewReader(reader) }, @@ -272,7 +274,7 @@ func Test_FlushBeforeWrite(t *testing.T) { require.NoError(t, err) }) - srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, next)) + srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, test.algo, next)) defer srv.Close() req, err := http.NewRequest(http.MethodGet, srv.URL, http.NoBody) @@ -302,12 +304,14 @@ func Test_FlushAfterWrite(t *testing.T) { testCases := []struct { desc string cfg Config + algo string readerBuilder func(io.Reader) (io.Reader, error) acceptEncoding string }{ { desc: "brotli", - cfg: Config{MinSize: 1024, Algorithm: brotliName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: brotliName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return brotli.NewReader(reader), nil }, @@ -315,7 +319,8 @@ func Test_FlushAfterWrite(t *testing.T) { }, { desc: "zstd", - cfg: Config{MinSize: 1024, Algorithm: zstdName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: zstdName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return zstd.NewReader(reader) }, @@ -338,7 +343,7 @@ func Test_FlushAfterWrite(t *testing.T) { } }) - srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, next)) + srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, test.algo, next)) defer srv.Close() req, err := http.NewRequest(http.MethodGet, srv.URL, http.NoBody) @@ -368,12 +373,14 @@ func Test_FlushAfterWriteNil(t *testing.T) { testCases := []struct { desc string cfg Config + algo string readerBuilder func(io.Reader) (io.Reader, error) acceptEncoding string }{ { desc: "brotli", - cfg: Config{MinSize: 1024, Algorithm: brotliName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: brotliName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return brotli.NewReader(reader), nil }, @@ -381,7 +388,8 @@ func Test_FlushAfterWriteNil(t *testing.T) { }, { desc: "zstd", - cfg: Config{MinSize: 1024, Algorithm: zstdName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: zstdName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return zstd.NewReader(reader) }, @@ -400,7 +408,7 @@ func Test_FlushAfterWriteNil(t *testing.T) { rw.(http.Flusher).Flush() }) - srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, next)) + srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, test.algo, next)) defer srv.Close() req, err := http.NewRequest(http.MethodGet, srv.URL, http.NoBody) @@ -430,12 +438,14 @@ func Test_FlushAfterAllWrites(t *testing.T) { testCases := []struct { desc string cfg Config + algo string readerBuilder func(io.Reader) (io.Reader, error) acceptEncoding string }{ { desc: "brotli", - cfg: Config{MinSize: 1024, Algorithm: brotliName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: brotliName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return brotli.NewReader(reader), nil }, @@ -443,7 +453,8 @@ func Test_FlushAfterAllWrites(t *testing.T) { }, { desc: "zstd", - cfg: Config{MinSize: 1024, Algorithm: zstdName, MiddlewareName: "Test"}, + cfg: Config{MinSize: 1024, MiddlewareName: "Test"}, + algo: zstdName, readerBuilder: func(reader io.Reader) (io.Reader, error) { return zstd.NewReader(reader) }, @@ -461,7 +472,7 @@ func Test_FlushAfterAllWrites(t *testing.T) { rw.(http.Flusher).Flush() }) - srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, next)) + srv := httptest.NewServer(mustNewCompressionHandler(t, test.cfg, test.algo, next)) defer srv.Close() req, err := http.NewRequest(http.MethodGet, srv.URL, http.NoBody) @@ -556,7 +567,6 @@ func Test_ExcludedContentTypes(t *testing.T) { cfg := Config{ MinSize: 1024, ExcludedContentTypes: test.excludedContentTypes, - Algorithm: zstdName, } next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { @@ -568,7 +578,7 @@ func Test_ExcludedContentTypes(t *testing.T) { require.NoError(t, err) }) - h := mustNewCompressionHandler(t, cfg, next) + h := mustNewCompressionHandler(t, cfg, zstdName, next) req, _ := http.NewRequest(http.MethodGet, "/whatever", nil) req.Header.Set(acceptEncoding, zstdName) @@ -667,7 +677,6 @@ func Test_IncludedContentTypes(t *testing.T) { cfg := Config{ MinSize: 1024, IncludedContentTypes: test.includedContentTypes, - Algorithm: zstdName, } next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { @@ -679,7 +688,7 @@ func Test_IncludedContentTypes(t *testing.T) { require.NoError(t, err) }) - h := mustNewCompressionHandler(t, cfg, next) + h := mustNewCompressionHandler(t, cfg, zstdName, next) req, _ := http.NewRequest(http.MethodGet, "/whatever", nil) req.Header.Set(acceptEncoding, zstdName) @@ -778,7 +787,6 @@ func Test_FlushExcludedContentTypes(t *testing.T) { cfg := Config{ MinSize: 1024, ExcludedContentTypes: test.excludedContentTypes, - Algorithm: zstdName, } next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { @@ -803,7 +811,7 @@ func Test_FlushExcludedContentTypes(t *testing.T) { } }) - h := mustNewCompressionHandler(t, cfg, next) + h := mustNewCompressionHandler(t, cfg, zstdName, next) req, _ := http.NewRequest(http.MethodGet, "/whatever", nil) req.Header.Set(acceptEncoding, zstdName) @@ -903,7 +911,6 @@ func Test_FlushIncludedContentTypes(t *testing.T) { cfg := Config{ MinSize: 1024, IncludedContentTypes: test.includedContentTypes, - Algorithm: zstdName, } next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { @@ -928,7 +935,7 @@ func Test_FlushIncludedContentTypes(t *testing.T) { } }) - h := mustNewCompressionHandler(t, cfg, next) + h := mustNewCompressionHandler(t, cfg, zstdName, next) req, _ := http.NewRequest(http.MethodGet, "/whatever", nil) req.Header.Set(acceptEncoding, zstdName) @@ -959,10 +966,26 @@ func Test_FlushIncludedContentTypes(t *testing.T) { } } -func mustNewCompressionHandler(t *testing.T, cfg Config, next http.Handler) http.Handler { +func mustNewCompressionHandler(t *testing.T, cfg Config, algo string, next http.Handler) http.Handler { t.Helper() - w, err := NewCompressionHandler(cfg, next) + var writer NewCompressionWriter + switch algo { + case zstdName: + writer = func(rw http.ResponseWriter) (CompressionWriter, string, error) { + writer, err := zstd.NewWriter(rw) + require.NoError(t, err) + return writer, zstdName, nil + } + case brotliName: + writer = func(rw http.ResponseWriter) (CompressionWriter, string, error) { + return brotli.NewWriter(rw), brotliName, nil + } + default: + assert.Failf(t, "unknown compression algorithm: %s", algo) + } + + w, err := NewCompressionHandler(cfg, writer, next) require.NoError(t, err) return w @@ -981,7 +1004,7 @@ func newTestBrotliHandler(t *testing.T, body []byte) http.Handler { require.NoError(t, err) }) - return mustNewCompressionHandler(t, Config{MinSize: 1024, Algorithm: brotliName, MiddlewareName: "Compress"}, next) + return mustNewCompressionHandler(t, Config{MinSize: 1024, MiddlewareName: "Compress"}, brotliName, next) } func newTestZstandardHandler(t *testing.T, body []byte) http.Handler { @@ -997,7 +1020,7 @@ func newTestZstandardHandler(t *testing.T, body []byte) http.Handler { require.NoError(t, err) }) - return mustNewCompressionHandler(t, Config{MinSize: 1024, Algorithm: zstdName, MiddlewareName: "Compress"}, next) + return mustNewCompressionHandler(t, Config{MinSize: 1024, MiddlewareName: "Compress"}, zstdName, next) } func Test_ParseContentType_equals(t *testing.T) { From f54f28921b728ca675c0aac7650f705720302984 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com> Date: Fri, 11 Oct 2024 12:10:04 +0200 Subject: [PATCH 03/18] Add missing RBAC in the migration guide --- docs/content/migration/v3.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/content/migration/v3.md b/docs/content/migration/v3.md index 64ac460e5..d4cf9fc3e 100644 --- a/docs/content/migration/v3.md +++ b/docs/content/migration/v3.md @@ -125,10 +125,18 @@ the `grcroutes` and `grpcroutes/status` rights have to be added. Starting with v3.2, the Kubernetes Gateway Provider now supports [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/). Therefore, in the corresponding RBACs (see [KubernetesGateway](../reference/dynamic-configuration/kubernetes-gateway.md#rbac) provider RBACs), -the `backendtlspolicies` and `backendtlspolicies/status` rights have to be added. +the `configmaps`, `backendtlspolicies` and `backendtlspolicies/status` rights have to be added. ```yaml ... + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch - apiGroups: - gateway.networking.k8s.io resources: From ef5aa129c7c48408da3a43ad74113b009602b8e4 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com> Date: Fri, 11 Oct 2024 12:12:05 +0200 Subject: [PATCH 04/18] Fix broken links in Kubernetes Gateway provider page --- docs/content/providers/kubernetes-gateway.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/providers/kubernetes-gateway.md b/docs/content/providers/kubernetes-gateway.md index e6afcc404..d1a7a38cf 100644 --- a/docs/content/providers/kubernetes-gateway.md +++ b/docs/content/providers/kubernetes-gateway.md @@ -30,7 +30,7 @@ For more details, check out the conformance [report](https://github.com/kubernet kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml ``` -2. Install/update the Traefik [RBAC](../reference/dynamic-configuration/kubernetes-gateway.md#rbac). +2. Install the additional Traefik RBAC required for Gateway API. ```bash # Install Traefik RBACs. From 6e1f5dc0713bd74ffb599b4fc0213bc1cfbd5f2e Mon Sep 17 00:00:00 2001 From: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:24:03 +0200 Subject: [PATCH 05/18] Fix instructions for downloading CRDs of Gateway API v1.2 --- docs/content/providers/kubernetes-gateway.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/providers/kubernetes-gateway.md b/docs/content/providers/kubernetes-gateway.md index 072a4c47f..a6291db0d 100644 --- a/docs/content/providers/kubernetes-gateway.md +++ b/docs/content/providers/kubernetes-gateway.md @@ -27,7 +27,7 @@ For more details, check out the conformance [report](https://github.com/kubernet ```bash # Install Gateway API CRDs from the Standard channel. - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml + kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml ``` 2. Install/update the Traefik [RBAC](../reference/dynamic-configuration/kubernetes-gateway.md#rbac). @@ -275,7 +275,7 @@ providers: ```bash # Install Gateway API CRDs from the Experimental channel. - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/experimental-install.yaml + kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml ``` ### `labelselector` From 83871f27dd563cf6abec658d30a3b5dd1f904a31 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 17 Oct 2024 09:12:04 +0200 Subject: [PATCH 06/18] Add an option to preserve server path --- .../reference/dynamic-configuration/file.toml | 2 + .../reference/dynamic-configuration/file.yaml | 2 + .../reference/dynamic-configuration/kv-ref.md | 2 + docs/content/routing/services/index.md | 34 +++++- pkg/config/dynamic/http_config.go | 9 +- pkg/proxy/fast/builder.go | 4 +- pkg/proxy/fast/proxy.go | 9 +- pkg/proxy/fast/proxy_test.go | 28 ++++- pkg/proxy/fast/proxy_websocket_test.go | 6 +- pkg/proxy/httputil/builder.go | 4 +- pkg/proxy/httputil/builder_test.go | 2 +- pkg/proxy/httputil/proxy.go | 67 +++++++++--- pkg/proxy/httputil/proxy_test.go | 102 ++++++++++++++++++ pkg/proxy/httputil/proxy_websocket_test.go | 8 +- pkg/proxy/smart_builder.go | 6 +- pkg/proxy/smart_builder_test.go | 2 +- pkg/server/router/router_test.go | 2 +- pkg/server/routerfactory_test.go | 2 +- pkg/server/service/service.go | 4 +- 19 files changed, 251 insertions(+), 44 deletions(-) create mode 100644 pkg/proxy/httputil/proxy_test.go diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 18fc9bc84..065d3ca16 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -59,10 +59,12 @@ [[http.services.Service02.loadBalancer.servers]] url = "foobar" weight = 42 + preservePath = true [[http.services.Service02.loadBalancer.servers]] url = "foobar" weight = 42 + preservePath = true [http.services.Service02.loadBalancer.healthCheck] scheme = "foobar" mode = "foobar" diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index d0b0fc0fb..08cb9c385 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -66,8 +66,10 @@ http: servers: - url: foobar weight: 42 + preservePath: true - url: foobar weight: 42 + preservePath: true healthCheck: scheme: foobar mode: foobar diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index 01de7ee69..a2f24a805 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -256,8 +256,10 @@ THIS FILE MUST NOT BE EDITED BY HAND | `traefik/http/services/Service02/loadBalancer/healthCheck/timeout` | `42s` | | `traefik/http/services/Service02/loadBalancer/passHostHeader` | `true` | | `traefik/http/services/Service02/loadBalancer/responseForwarding/flushInterval` | `42s` | +| `traefik/http/services/Service02/loadBalancer/servers/0/preservePath` | `true` | | `traefik/http/services/Service02/loadBalancer/servers/0/url` | `foobar` | | `traefik/http/services/Service02/loadBalancer/servers/0/weight` | `42` | +| `traefik/http/services/Service02/loadBalancer/servers/1/preservePath` | `true` | | `traefik/http/services/Service02/loadBalancer/servers/1/url` | `foobar` | | `traefik/http/services/Service02/loadBalancer/servers/1/weight` | `42` | | `traefik/http/services/Service02/loadBalancer/serversTransport` | `foobar` | diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 8e4cc41f0..b58ac814a 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -116,12 +116,8 @@ Each service has a load-balancer, even if there is only one server to forward tr #### Servers Servers declare a single instance of your program. -The `url` option point to a specific instance. -!!! info "" - Paths in the servers' `url` have no effect. - If you want the requests to be sent to a specific path on your servers, - configure your [`routers`](../routers/index.md) to use a corresponding [middleware](../../middlewares/overview.md) (e.g. the [AddPrefix](../../middlewares/http/addprefix.md) or [ReplacePath](../../middlewares/http/replacepath.md)) middlewares. +The `url` option point to a specific instance. ??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)" @@ -173,6 +169,34 @@ The `weight` option allows for weighted load balancing on the servers. weight = 1 ``` +The `preservePath` option allows to preserve the URL path. + +!!! info "Health Check" + + When a [health check](#health-check) is configured for the server, the path is not preserved. + +??? example "A Service with One Server and PreservePath -- Using the [File Provider](../../providers/file.md)" + + ```yaml tab="YAML" + ## Dynamic configuration + http: + services: + my-service: + loadBalancer: + servers: + - url: "http://private-ip-server-1/base" + preservePath: true + ``` + + ```toml tab="TOML" + ## Dynamic configuration + [http.services] + [http.services.my-service.loadBalancer] + [[http.services.my-service.loadBalancer.servers]] + url = "http://private-ip-server-1/base" + preservePath = true + ``` + #### Load-balancing For now, only round robin load balancing is supported: diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index d347df81e..e29bdd30a 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -244,10 +244,11 @@ func (r *ResponseForwarding) SetDefaults() { // Server holds the server configuration. type Server struct { - URL string `json:"url,omitempty" toml:"url,omitempty" yaml:"url,omitempty" label:"-"` - Weight *int `json:"weight,omitempty" toml:"weight,omitempty" yaml:"weight,omitempty" label:"weight"` - Scheme string `json:"-" toml:"-" yaml:"-" file:"-"` - Port string `json:"-" toml:"-" yaml:"-" file:"-"` + URL string `json:"url,omitempty" toml:"url,omitempty" yaml:"url,omitempty" label:"-"` + Weight *int `json:"weight,omitempty" toml:"weight,omitempty" yaml:"weight,omitempty" label:"weight" export:"true"` + PreservePath bool `json:"preservePath,omitempty" toml:"preservePath,omitempty" yaml:"preservePath,omitempty" label:"-" export:"true"` + Scheme string `json:"-" toml:"-" yaml:"-" file:"-"` + Port string `json:"-" toml:"-" yaml:"-" file:"-"` } // SetDefaults Default values for a Server. diff --git a/pkg/proxy/fast/builder.go b/pkg/proxy/fast/builder.go index f330d6756..c53363dad 100644 --- a/pkg/proxy/fast/builder.go +++ b/pkg/proxy/fast/builder.go @@ -68,7 +68,7 @@ func (r *ProxyBuilder) Update(newConfigs map[string]*dynamic.ServersTransport) { } // Build builds a new ReverseProxy with the given configuration. -func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, passHostHeader bool) (http.Handler, error) { +func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, passHostHeader, preservePath bool) (http.Handler, error) { proxyURL, err := r.proxy(&http.Request{URL: targetURL}) if err != nil { return nil, fmt.Errorf("getting proxy: %w", err) @@ -90,7 +90,7 @@ func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, passHostHeader } pool := r.getPool(cfgName, cfg, tlsConfig, targetURL, proxyURL) - return NewReverseProxy(targetURL, proxyURL, r.debug, passHostHeader, responseHeaderTimeout, pool) + return NewReverseProxy(targetURL, proxyURL, r.debug, passHostHeader, preservePath, responseHeaderTimeout, pool) } func (r *ProxyBuilder) getPool(cfgName string, config *dynamic.ServersTransport, tlsConfig *tls.Config, targetURL *url.URL, proxyURL *url.URL) *connPool { diff --git a/pkg/proxy/fast/proxy.go b/pkg/proxy/fast/proxy.go index e61a32ad8..388a4d73c 100644 --- a/pkg/proxy/fast/proxy.go +++ b/pkg/proxy/fast/proxy.go @@ -121,11 +121,12 @@ type ReverseProxy struct { targetURL *url.URL passHostHeader bool + preservePath bool responseHeaderTimeout time.Duration } // NewReverseProxy creates a new ReverseProxy. -func NewReverseProxy(targetURL *url.URL, proxyURL *url.URL, debug, passHostHeader bool, responseHeaderTimeout time.Duration, connPool *connPool) (*ReverseProxy, error) { +func NewReverseProxy(targetURL, proxyURL *url.URL, debug, passHostHeader, preservePath bool, responseHeaderTimeout time.Duration, connPool *connPool) (*ReverseProxy, error) { var proxyAuth string if proxyURL != nil && proxyURL.User != nil && targetURL.Scheme == "http" { username := proxyURL.User.Username() @@ -136,6 +137,7 @@ func NewReverseProxy(targetURL *url.URL, proxyURL *url.URL, debug, passHostHeade return &ReverseProxy{ debug: debug, passHostHeader: passHostHeader, + preservePath: preservePath, targetURL: targetURL, proxyAuth: proxyAuth, connPool: connPool, @@ -207,6 +209,11 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { u2.Path = u.Path u2.RawPath = u.RawPath + + if p.preservePath { + u2.Path, u2.RawPath = proxyhttputil.JoinURLPath(p.targetURL, u) + } + u2.RawQuery = strings.ReplaceAll(u.RawQuery, ";", "&") outReq.SetHost(u2.Host) diff --git a/pkg/proxy/fast/proxy_test.go b/pkg/proxy/fast/proxy_test.go index ee75ae0db..f4593d9ce 100644 --- a/pkg/proxy/fast/proxy_test.go +++ b/pkg/proxy/fast/proxy_test.go @@ -230,7 +230,7 @@ func TestProxyFromEnvironment(t *testing.T) { return u, nil } - reverseProxy, err := builder.Build("foo", testhelpers.MustParseURL(backendURL), false) + reverseProxy, err := builder.Build("foo", testhelpers.MustParseURL(backendURL), false, false) require.NoError(t, err) reverseProxyServer := httptest.NewServer(reverseProxy) @@ -252,6 +252,32 @@ func TestProxyFromEnvironment(t *testing.T) { } } +func TestPreservePath(t *testing.T) { + var callCount int + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + callCount++ + assert.Equal(t, "/base/foo/bar", req.URL.Path) + assert.Equal(t, "/base/foo%2Fbar", req.URL.RawPath) + })) + t.Cleanup(server.Close) + + builder := NewProxyBuilder(&transportManagerMock{}, static.FastProxyConfig{}) + + serverURL, err := url.JoinPath(server.URL, "base") + require.NoError(t, err) + + proxyHandler, err := builder.Build("", testhelpers.MustParseURL(serverURL), true, true) + require.NoError(t, err) + + req := httptest.NewRequest(http.MethodGet, "/foo%2Fbar", http.NoBody) + res := httptest.NewRecorder() + + proxyHandler.ServeHTTP(res, req) + + assert.Equal(t, 1, callCount) + assert.Equal(t, http.StatusOK, res.Code) +} + func newCertificate(t *testing.T, domain string) *tls.Certificate { t.Helper() diff --git a/pkg/proxy/fast/proxy_websocket_test.go b/pkg/proxy/fast/proxy_websocket_test.go index ff2e273e9..8297ac485 100644 --- a/pkg/proxy/fast/proxy_websocket_test.go +++ b/pkg/proxy/fast/proxy_websocket_test.go @@ -362,7 +362,7 @@ func TestWebSocketRequestWithHeadersInResponseWriter(t *testing.T) { u := parseURI(t, srv.URL) - f, err := NewReverseProxy(u, nil, true, false, 0, newConnPool(1, 0, func() (net.Conn, error) { + f, err := NewReverseProxy(u, nil, true, false, false, 0, newConnPool(1, 0, func() (net.Conn, error) { return net.Dial("tcp", u.Host) })) require.NoError(t, err) @@ -434,7 +434,7 @@ func TestWebSocketUpgradeFailed(t *testing.T) { defer srv.Close() u := parseURI(t, srv.URL) - f, err := NewReverseProxy(u, nil, true, false, 0, newConnPool(1, 0, func() (net.Conn, error) { + f, err := NewReverseProxy(u, nil, true, false, false, 0, newConnPool(1, 0, func() (net.Conn, error) { return net.Dial("tcp", u.Host) })) require.NoError(t, err) @@ -676,7 +676,7 @@ func createProxyWithForwarder(t *testing.T, uri string, pool *connPool) *httptes t.Helper() u := parseURI(t, uri) - proxy, err := NewReverseProxy(u, nil, false, true, 0, pool) + proxy, err := NewReverseProxy(u, nil, false, true, false, 0, pool) require.NoError(t, err) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { diff --git a/pkg/proxy/httputil/builder.go b/pkg/proxy/httputil/builder.go index ee88bd0c3..64360517a 100644 --- a/pkg/proxy/httputil/builder.go +++ b/pkg/proxy/httputil/builder.go @@ -38,7 +38,7 @@ func NewProxyBuilder(transportManager TransportManager, semConvMetricsRegistry * func (r *ProxyBuilder) Update(_ map[string]*dynamic.ServersTransport) {} // Build builds a new httputil.ReverseProxy with the given configuration. -func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, shouldObserve, passHostHeader bool, flushInterval time.Duration) (http.Handler, error) { +func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, shouldObserve, passHostHeader, preservePath bool, flushInterval time.Duration) (http.Handler, error) { roundTripper, err := r.transportManager.GetRoundTripper(cfgName) if err != nil { return nil, fmt.Errorf("getting RoundTripper: %w", err) @@ -50,5 +50,5 @@ func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, shouldObserve, roundTripper = newObservabilityRoundTripper(r.semConvMetricsRegistry, roundTripper) } - return buildSingleHostProxy(targetURL, passHostHeader, flushInterval, roundTripper, r.bufferPool), nil + return buildSingleHostProxy(targetURL, passHostHeader, preservePath, flushInterval, roundTripper, r.bufferPool), nil } diff --git a/pkg/proxy/httputil/builder_test.go b/pkg/proxy/httputil/builder_test.go index 8033635d2..f7ff93902 100644 --- a/pkg/proxy/httputil/builder_test.go +++ b/pkg/proxy/httputil/builder_test.go @@ -23,7 +23,7 @@ func TestEscapedPath(t *testing.T) { roundTrippers: map[string]http.RoundTripper{"default": &http.Transport{}}, } - p, err := NewProxyBuilder(transportManager, nil).Build("default", testhelpers.MustParseURL(srv.URL), false, true, 0) + p, err := NewProxyBuilder(transportManager, nil).Build("default", testhelpers.MustParseURL(srv.URL), false, true, false, 0) require.NoError(t, err) proxy := httptest.NewServer(http.HandlerFunc(p.ServeHTTP)) diff --git a/pkg/proxy/httputil/proxy.go b/pkg/proxy/httputil/proxy.go index e0401ea1f..8ed35c23a 100644 --- a/pkg/proxy/httputil/proxy.go +++ b/pkg/proxy/httputil/proxy.go @@ -15,15 +15,17 @@ import ( "golang.org/x/net/http/httpguts" ) -// StatusClientClosedRequest non-standard HTTP status code for client disconnection. -const StatusClientClosedRequest = 499 +const ( + // StatusClientClosedRequest non-standard HTTP status code for client disconnection. + StatusClientClosedRequest = 499 -// StatusClientClosedRequestText non-standard HTTP status for client disconnection. -const StatusClientClosedRequestText = "Client Closed Request" + // StatusClientClosedRequestText non-standard HTTP status for client disconnection. + StatusClientClosedRequestText = "Client Closed Request" +) -func buildSingleHostProxy(target *url.URL, passHostHeader bool, flushInterval time.Duration, roundTripper http.RoundTripper, bufferPool httputil.BufferPool) http.Handler { +func buildSingleHostProxy(target *url.URL, passHostHeader bool, preservePath bool, flushInterval time.Duration, roundTripper http.RoundTripper, bufferPool httputil.BufferPool) http.Handler { return &httputil.ReverseProxy{ - Director: directorBuilder(target, passHostHeader), + Director: directorBuilder(target, passHostHeader, preservePath), Transport: roundTripper, FlushInterval: flushInterval, BufferPool: bufferPool, @@ -31,7 +33,7 @@ func buildSingleHostProxy(target *url.URL, passHostHeader bool, flushInterval ti } } -func directorBuilder(target *url.URL, passHostHeader bool) func(req *http.Request) { +func directorBuilder(target *url.URL, passHostHeader bool, preservePath bool) func(req *http.Request) { return func(outReq *http.Request) { outReq.URL.Scheme = target.Scheme outReq.URL.Host = target.Host @@ -46,6 +48,11 @@ func directorBuilder(target *url.URL, passHostHeader bool) func(req *http.Reques outReq.URL.Path = u.Path outReq.URL.RawPath = u.RawPath + + if preservePath { + outReq.URL.Path, outReq.URL.RawPath = JoinURLPath(target, u) + } + // If a plugin/middleware adds semicolons in query params, they should be urlEncoded. outReq.URL.RawQuery = strings.ReplaceAll(u.RawQuery, ";", "&") outReq.RequestURI = "" // Outgoing request should not have RequestURI @@ -54,7 +61,7 @@ func directorBuilder(target *url.URL, passHostHeader bool) func(req *http.Reques outReq.ProtoMajor = 1 outReq.ProtoMinor = 1 - // Do not pass client Host header unless optsetter PassHostHeader is set. + // Do not pass client Host header unless option PassHostHeader is set. if !passHostHeader { outReq.Host = outReq.URL.Host } @@ -106,6 +113,13 @@ func ErrorHandler(w http.ResponseWriter, req *http.Request, err error) { } } +func statusText(statusCode int) string { + if statusCode == StatusClientClosedRequest { + return StatusClientClosedRequestText + } + return http.StatusText(statusCode) +} + // ComputeStatusCode computes the HTTP status code according to the given error. func ComputeStatusCode(err error) int { switch { @@ -127,9 +141,38 @@ func ComputeStatusCode(err error) int { return http.StatusInternalServerError } -func statusText(statusCode int) string { - if statusCode == StatusClientClosedRequest { - return StatusClientClosedRequestText +// JoinURLPath computes the joined path and raw path of the given URLs. +// From https://github.com/golang/go/blob/b521ebb55a9b26c8824b219376c7f91f7cda6ec2/src/net/http/httputil/reverseproxy.go#L221 +func JoinURLPath(a, b *url.URL) (path, rawpath string) { + if a.RawPath == "" && b.RawPath == "" { + return singleJoiningSlash(a.Path, b.Path), "" } - return http.StatusText(statusCode) + + // Same as singleJoiningSlash, but uses EscapedPath to determine + // whether a slash should be added + apath := a.EscapedPath() + bpath := b.EscapedPath() + + aslash := strings.HasSuffix(apath, "/") + bslash := strings.HasPrefix(bpath, "/") + + switch { + case aslash && bslash: + return a.Path + b.Path[1:], apath + bpath[1:] + case !aslash && !bslash: + return a.Path + "/" + b.Path, apath + "/" + bpath + } + return a.Path + b.Path, apath + bpath +} + +func singleJoiningSlash(a, b string) string { + aslash := strings.HasSuffix(a, "/") + bslash := strings.HasPrefix(b, "/") + switch { + case aslash && bslash: + return a + b[1:] + case !aslash && !bslash: + return a + "/" + b + } + return a + b } diff --git a/pkg/proxy/httputil/proxy_test.go b/pkg/proxy/httputil/proxy_test.go new file mode 100644 index 000000000..3d970fc53 --- /dev/null +++ b/pkg/proxy/httputil/proxy_test.go @@ -0,0 +1,102 @@ +package httputil + +import ( + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/traefik/traefik/v3/pkg/testhelpers" +) + +func Test_directorBuilder(t *testing.T) { + tests := []struct { + name string + target *url.URL + passHostHeader bool + preservePath bool + incomingURL string + expectedScheme string + expectedHost string + expectedPath string + expectedRawPath string + expectedQuery string + }{ + { + name: "Basic proxy", + target: testhelpers.MustParseURL("http://example.com"), + passHostHeader: false, + preservePath: false, + incomingURL: "http://localhost/test?param=value", + expectedScheme: "http", + expectedHost: "example.com", + expectedPath: "/test", + expectedQuery: "param=value", + }, + { + name: "HTTPS target", + target: testhelpers.MustParseURL("https://secure.example.com"), + passHostHeader: false, + preservePath: false, + incomingURL: "http://localhost/secure", + expectedScheme: "https", + expectedHost: "secure.example.com", + expectedPath: "/secure", + }, + { + name: "PassHostHeader", + target: testhelpers.MustParseURL("http://example.com"), + passHostHeader: true, + preservePath: false, + incomingURL: "http://original.host/test", + expectedScheme: "http", + expectedHost: "original.host", + expectedPath: "/test", + }, + { + name: "Preserve path", + target: testhelpers.MustParseURL("http://example.com/base"), + passHostHeader: false, + preservePath: true, + incomingURL: "http://localhost/foo%2Fbar", + expectedScheme: "http", + expectedHost: "example.com", + expectedPath: "/base/foo/bar", + expectedRawPath: "/base/foo%2Fbar", + }, + { + name: "Handle semicolons in query", + target: testhelpers.MustParseURL("http://example.com"), + passHostHeader: false, + preservePath: false, + incomingURL: "http://localhost/test?param1=value1;param2=value2", + expectedScheme: "http", + expectedHost: "example.com", + expectedPath: "/test", + expectedQuery: "param1=value1¶m2=value2", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + director := directorBuilder(test.target, test.passHostHeader, test.preservePath) + + req := httptest.NewRequest(http.MethodGet, test.incomingURL, http.NoBody) + director(req) + + assert.Equal(t, test.expectedScheme, req.URL.Scheme) + assert.Equal(t, test.expectedHost, req.Host) + assert.Equal(t, test.expectedPath, req.URL.Path) + assert.Equal(t, test.expectedRawPath, req.URL.RawPath) + assert.Equal(t, test.expectedQuery, req.URL.RawQuery) + assert.Empty(t, req.RequestURI) + assert.Equal(t, "HTTP/1.1", req.Proto) + assert.Equal(t, 1, req.ProtoMajor) + assert.Equal(t, 1, req.ProtoMinor) + assert.False(t, !test.passHostHeader && req.Host != req.URL.Host) + }) + } +} diff --git a/pkg/proxy/httputil/proxy_websocket_test.go b/pkg/proxy/httputil/proxy_websocket_test.go index dc6fa8c82..5472bcce0 100644 --- a/pkg/proxy/httputil/proxy_websocket_test.go +++ b/pkg/proxy/httputil/proxy_websocket_test.go @@ -298,9 +298,8 @@ func TestWebSocketRequestWithHeadersInResponseWriter(t *testing.T) { }, } - p, err := NewProxyBuilder(transportManager, nil).Build("default@internal", testhelpers.MustParseURL(srv.URL), false, true, 0) + p, err := NewProxyBuilder(transportManager, nil).Build("default@internal", testhelpers.MustParseURL(srv.URL), false, true, false, 0) require.NoError(t, err) - proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL = testhelpers.MustParseURL(srv.URL) w.Header().Set("HEADER-KEY", "HEADER-VALUE") @@ -355,9 +354,8 @@ func TestWebSocketUpgradeFailed(t *testing.T) { }, } - p, err := NewProxyBuilder(transportManager, nil).Build("default@internal", testhelpers.MustParseURL(srv.URL), false, true, 0) + p, err := NewProxyBuilder(transportManager, nil).Build("default@internal", testhelpers.MustParseURL(srv.URL), false, true, false, 0) require.NoError(t, err) - proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { path := req.URL.Path // keep the original path @@ -588,7 +586,7 @@ func createProxyWithForwarder(t *testing.T, uri string, transport http.RoundTrip roundTrippers: map[string]http.RoundTripper{"fwd": transport}, } - p, err := NewProxyBuilder(transportManager, nil).Build("fwd", u, false, true, 0) + p, err := NewProxyBuilder(transportManager, nil).Build("fwd", u, false, true, false, 0) require.NoError(t, err) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { diff --git a/pkg/proxy/smart_builder.go b/pkg/proxy/smart_builder.go index 1abadcca7..08b247c53 100644 --- a/pkg/proxy/smart_builder.go +++ b/pkg/proxy/smart_builder.go @@ -45,7 +45,7 @@ func (b *SmartBuilder) Update(newConfigs map[string]*dynamic.ServersTransport) { } // Build builds an HTTP proxy for the given URL using the ServersTransport with the given name. -func (b *SmartBuilder) Build(configName string, targetURL *url.URL, shouldObserve, passHostHeader bool, flushInterval time.Duration) (http.Handler, error) { +func (b *SmartBuilder) Build(configName string, targetURL *url.URL, shouldObserve, passHostHeader, preservePath bool, flushInterval time.Duration) (http.Handler, error) { serversTransport, err := b.transportManager.Get(configName) if err != nil { return nil, fmt.Errorf("getting ServersTransport: %w", err) @@ -55,7 +55,7 @@ func (b *SmartBuilder) Build(configName string, targetURL *url.URL, shouldObserv // For the https scheme we cannot guess if the backend communication will use HTTP2, // thus we check if HTTP/2 is disabled to use the fast proxy implementation when this is possible. if targetURL.Scheme == "h2c" || (targetURL.Scheme == "https" && !serversTransport.DisableHTTP2) { - return b.proxyBuilder.Build(configName, targetURL, shouldObserve, passHostHeader, flushInterval) + return b.proxyBuilder.Build(configName, targetURL, shouldObserve, passHostHeader, preservePath, flushInterval) } - return b.fastProxyBuilder.Build(configName, targetURL, passHostHeader) + return b.fastProxyBuilder.Build(configName, targetURL, passHostHeader, preservePath) } diff --git a/pkg/proxy/smart_builder_test.go b/pkg/proxy/smart_builder_test.go index d1c29ddd8..c03bd19f3 100644 --- a/pkg/proxy/smart_builder_test.go +++ b/pkg/proxy/smart_builder_test.go @@ -101,7 +101,7 @@ func TestSmartBuilder_Build(t *testing.T) { httpProxyBuilder := httputil.NewProxyBuilder(transportManager, nil) proxyBuilder := NewSmartBuilder(transportManager, httpProxyBuilder, test.fastProxyConfig) - proxyHandler, err := proxyBuilder.Build("test", targetURL, false, false, time.Second) + proxyHandler, err := proxyBuilder.Build("test", targetURL, false, false, false, time.Second) require.NoError(t, err) rw := httptest.NewRecorder() diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index b545bd2da..70808e9c6 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -897,7 +897,7 @@ func BenchmarkService(b *testing.B) { type proxyBuilderMock struct{} -func (p proxyBuilderMock) Build(_ string, _ *url.URL, _, _ bool, _ time.Duration) (http.Handler, error) { +func (p proxyBuilderMock) Build(_ string, _ *url.URL, _, _, _ bool, _ time.Duration) (http.Handler, error) { return http.HandlerFunc(func(responseWriter http.ResponseWriter, req *http.Request) {}), nil } diff --git a/pkg/server/routerfactory_test.go b/pkg/server/routerfactory_test.go index 6c0861d38..2b3d6fe1f 100644 --- a/pkg/server/routerfactory_test.go +++ b/pkg/server/routerfactory_test.go @@ -254,7 +254,7 @@ func TestInternalServices(t *testing.T) { type proxyBuilderMock struct{} -func (p proxyBuilderMock) Build(_ string, _ *url.URL, _, _ bool, _ time.Duration) (http.Handler, error) { +func (p proxyBuilderMock) Build(_ string, _ *url.URL, _, _, _ bool, _ time.Duration) (http.Handler, error) { return http.HandlerFunc(func(responseWriter http.ResponseWriter, req *http.Request) {}), nil } diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index e37ecdf09..349c03179 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -42,7 +42,7 @@ const ( // ProxyBuilder builds reverse proxy handlers. type ProxyBuilder interface { - Build(cfgName string, targetURL *url.URL, shouldObserve, passHostHeader bool, flushInterval time.Duration) (http.Handler, error) + Build(cfgName string, targetURL *url.URL, shouldObserve, passHostHeader, preservePath bool, flushInterval time.Duration) (http.Handler, error) Update(configs map[string]*dynamic.ServersTransport) } @@ -338,7 +338,7 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName qualifiedSvcName := provider.GetQualifiedName(ctx, serviceName) shouldObserve := m.observabilityMgr.ShouldAddTracing(qualifiedSvcName) || m.observabilityMgr.ShouldAddMetrics(qualifiedSvcName) - proxy, err := m.proxyBuilder.Build(service.ServersTransport, target, shouldObserve, passHostHeader, flushInterval) + proxy, err := m.proxyBuilder.Build(service.ServersTransport, target, shouldObserve, passHostHeader, server.PreservePath, flushInterval) if err != nil { return nil, fmt.Errorf("error building proxy for server URL %s: %w", server.URL, err) } From eeb99c35363f3b6b0c835a9244d15a95f7f197db Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 21 Oct 2024 09:54:04 +0200 Subject: [PATCH 07/18] Preserve HTTPRoute filters order --- .../httproute/filter_extension_ref.yml | 7 +++- pkg/provider/kubernetes/gateway/httproute.go | 39 +++++++++++++------ .../kubernetes/gateway/kubernetes_test.go | 19 ++++++--- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_extension_ref.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_extension_ref.yml index c377fd139..0d2ffc918 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_extension_ref.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_extension_ref.yml @@ -54,4 +54,9 @@ spec: extensionRef: group: traefik.io kind: Middleware - name: my-middleware + name: my-first-middleware + - type: ExtensionRef + extensionRef: + group: traefik.io + kind: Middleware + name: my-second-middleware diff --git a/pkg/provider/kubernetes/gateway/httproute.go b/pkg/provider/kubernetes/gateway/httproute.go index fc6c9cf1b..df9905aed 100644 --- a/pkg/provider/kubernetes/gateway/httproute.go +++ b/pkg/provider/kubernetes/gateway/httproute.go @@ -301,36 +301,52 @@ func (p *Provider) loadHTTPBackendRef(namespace string, backendRef gatev1.HTTPBa } func (p *Provider) loadMiddlewares(conf *dynamic.Configuration, namespace, routerName string, filters []gatev1.HTTPRouteFilter, pathMatch *gatev1.HTTPPathMatch) ([]string, error) { + type namedMiddleware struct { + Name string + Config *dynamic.Middleware + } + pm := ptr.Deref(pathMatch, gatev1.HTTPPathMatch{ Type: ptr.To(gatev1.PathMatchPathPrefix), Value: ptr.To("/"), }) - middlewares := make(map[string]*dynamic.Middleware) + var middlewares []namedMiddleware for i, filter := range filters { name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i) + switch filter.Type { case gatev1.HTTPRouteFilterRequestRedirect: - middlewares[name] = createRequestRedirect(filter.RequestRedirect, pm) + middlewares = append(middlewares, namedMiddleware{ + name, + createRequestRedirect(filter.RequestRedirect, pm), + }) case gatev1.HTTPRouteFilterRequestHeaderModifier: - middlewares[name] = createRequestHeaderModifier(filter.RequestHeaderModifier) + middlewares = append(middlewares, namedMiddleware{ + name, + createRequestHeaderModifier(filter.RequestHeaderModifier), + }) case gatev1.HTTPRouteFilterExtensionRef: name, middleware, err := p.loadHTTPRouteFilterExtensionRef(namespace, filter.ExtensionRef) if err != nil { return nil, fmt.Errorf("loading ExtensionRef filter %s: %w", filter.Type, err) } - - middlewares[name] = middleware + middlewares = append(middlewares, namedMiddleware{ + name, + middleware, + }) case gatev1.HTTPRouteFilterURLRewrite: - var err error middleware, err := createURLRewrite(filter.URLRewrite, pm) if err != nil { return nil, fmt.Errorf("invalid filter %s: %w", filter.Type, err) } - middlewares[name] = middleware + middlewares = append(middlewares, namedMiddleware{ + name, + middleware, + }) default: // As per the spec: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional @@ -342,12 +358,11 @@ func (p *Provider) loadMiddlewares(conf *dynamic.Configuration, namespace, route } var middlewareNames []string - for name, middleware := range middlewares { - if middleware != nil { - conf.HTTP.Middlewares[name] = middleware + for _, m := range middlewares { + if m.Config != nil { + conf.HTTP.Middlewares[m.Name] = m.Config } - - middlewareNames = append(middlewareNames, name) + middlewareNames = append(middlewareNames, m.Name) } return middlewareNames, nil diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index 28d1c9591..c3b287ddd 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -2431,7 +2431,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { entryPoints map[string]Entrypoint }{ { - desc: "HTTPRoute with ExtensionRef filter", + desc: "ExtensionRef filter", groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{ traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) { return namespace + "-" + name, nil, nil @@ -2459,7 +2459,10 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", - Middlewares: []string{"default-my-middleware"}, + Middlewares: []string{ + "default-my-first-middleware", + "default-my-second-middleware", + }, }, }, Middlewares: map[string]*dynamic.Middleware{}, @@ -2497,7 +2500,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, }, { - desc: "HTTPRoute with ExtensionRef filter and create middleware", + desc: "ExtensionRef filter with middleware creation", groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{ traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) { return namespace + "-" + name, &dynamic.Middleware{Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, nil @@ -2525,11 +2528,15 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", - Middlewares: []string{"default-my-middleware"}, + Middlewares: []string{ + "default-my-first-middleware", + "default-my-second-middleware", + }, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-my-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, + "default-my-first-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, + "default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, }, Services: map[string]*dynamic.Service{ "default-http-app-1-my-gateway-web-0-wrr": { @@ -2565,7 +2572,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, }, { - desc: "ExtensionRef filter: Unknown", + desc: "Unknown ExtensionRef filter", entryPoints: map[string]Entrypoint{"web": { Address: ":80", }}, From f18fcf3688b850f5e89530bb1bccf002fd592473 Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 21 Oct 2024 10:10:04 +0200 Subject: [PATCH 08/18] Preserve GRPCRoute filters order --- .../grpcroute/filter_extension_ref.yml | 56 ++++ pkg/provider/kubernetes/gateway/grpcroute.go | 27 +- .../kubernetes/gateway/kubernetes_test.go | 291 ++++++++++++++++++ pkg/provider/kubernetes/k8s/parser.go | 2 +- 4 files changed, 366 insertions(+), 10 deletions(-) create mode 100644 pkg/provider/kubernetes/gateway/fixtures/grpcroute/filter_extension_ref.yml diff --git a/pkg/provider/kubernetes/gateway/fixtures/grpcroute/filter_extension_ref.yml b/pkg/provider/kubernetes/gateway/fixtures/grpcroute/filter_extension_ref.yml new file mode 100644 index 000000000..675374765 --- /dev/null +++ b/pkg/provider/kubernetes/gateway/fixtures/grpcroute/filter_extension_ref.yml @@ -0,0 +1,56 @@ +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: my-gateway-class +spec: + controllerName: traefik.io/gateway-controller + +--- +kind: Gateway +apiVersion: gateway.networking.k8s.io/v1 +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: GRPCRoute + group: gateway.networking.k8s.io + namespaces: + from: Same + +--- +kind: GRPCRoute +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: grpc-app-1 + namespace: default +spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io + hostnames: + - foo.com + rules: + - backendRefs: + - name: whoami + port: 80 + weight: 1 + filters: + - type: ExtensionRef + extensionRef: + group: traefik.io + kind: Middleware + name: my-first-middleware + - type: ExtensionRef + extensionRef: + group: traefik.io + kind: Middleware + name: my-second-middleware \ No newline at end of file diff --git a/pkg/provider/kubernetes/gateway/grpcroute.go b/pkg/provider/kubernetes/gateway/grpcroute.go index 021a3909c..cb61428ec 100644 --- a/pkg/provider/kubernetes/gateway/grpcroute.go +++ b/pkg/provider/kubernetes/gateway/grpcroute.go @@ -278,20 +278,30 @@ func (p *Provider) loadGRPCBackendRef(route *gatev1.GRPCRoute, backendRef gatev1 } func (p *Provider) loadGRPCMiddlewares(conf *dynamic.Configuration, namespace, routerName string, filters []gatev1.GRPCRouteFilter) ([]string, error) { - middlewares := make(map[string]*dynamic.Middleware) + type namedMiddleware struct { + Name string + Config *dynamic.Middleware + } + + var middlewares []namedMiddleware for i, filter := range filters { name := fmt.Sprintf("%s-%s-%d", routerName, strings.ToLower(string(filter.Type)), i) switch filter.Type { case gatev1.GRPCRouteFilterRequestHeaderModifier: - middlewares[name] = createRequestHeaderModifier(filter.RequestHeaderModifier) + middlewares = append(middlewares, namedMiddleware{ + name, + createRequestHeaderModifier(filter.RequestHeaderModifier), + }) case gatev1.GRPCRouteFilterExtensionRef: name, middleware, err := p.loadHTTPRouteFilterExtensionRef(namespace, filter.ExtensionRef) if err != nil { return nil, fmt.Errorf("loading ExtensionRef filter %s: %w", filter.Type, err) } - - middlewares[name] = middleware + middlewares = append(middlewares, namedMiddleware{ + name, + middleware, + }) default: // As per the spec: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional @@ -303,12 +313,11 @@ func (p *Provider) loadGRPCMiddlewares(conf *dynamic.Configuration, namespace, r } var middlewareNames []string - for name, middleware := range middlewares { - if middleware != nil { - conf.HTTP.Middlewares[name] = middleware + for _, m := range middlewares { + if m.Config != nil { + conf.HTTP.Middlewares[m.Name] = m.Config } - - middlewareNames = append(middlewareNames, name) + middlewareNames = append(middlewareNames, m.Name) } return middlewareNames, nil diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index 985096362..e82ad3810 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -18,6 +18,7 @@ import ( "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" "github.com/traefik/traefik/v3/pkg/tls" "github.com/traefik/traefik/v3/pkg/types" + "google.golang.org/grpc/codes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -3231,6 +3232,296 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { } } +func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { + testCases := []struct { + desc string + groupKindFilterFuncs map[string]map[string]BuildFilterFunc + expected *dynamic.Configuration + entryPoints map[string]Entrypoint + }{ + { + desc: "ExtensionRef filter", + groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{ + traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) { + return namespace + "-" + name, nil, nil + }}, + }, + 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-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + EntryPoints: []string{"web"}, + Service: "default-grpc-app-1-my-gateway-web-0-wrr", + Rule: "Host(`foo.com`) && PathPrefix(`/`)", + Priority: 22, + RuleSyntax: "v3", + Middlewares: []string{ + "default-my-first-middleware", + "default-my-second-middleware", + }, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-grpc-app-1-my-gateway-web-0-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: ptr.To(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "h2c://10.10.0.1:80", + }, + { + URL: "h2c://10.10.0.2:80", + }, + }, + PassHostHeader: ptr.To(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "ExtensionRef filter with middleware creation", + groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{ + traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) { + return namespace + "-" + name, &dynamic.Middleware{Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, nil + }}, + }, + 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-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + EntryPoints: []string{"web"}, + Service: "default-grpc-app-1-my-gateway-web-0-wrr", + Rule: "Host(`foo.com`) && PathPrefix(`/`)", + Priority: 22, + RuleSyntax: "v3", + Middlewares: []string{ + "default-my-first-middleware", + "default-my-second-middleware", + }, + }, + }, + Middlewares: map[string]*dynamic.Middleware{ + "default-my-first-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, + "default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, + }, + Services: map[string]*dynamic.Service{ + "default-grpc-app-1-my-gateway-web-0-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: ptr.To(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "h2c://10.10.0.1:80", + }, + { + URL: "h2c://10.10.0.2:80", + }, + }, + PassHostHeader: ptr.To(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "Unknown ExtensionRef filter", + 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-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + EntryPoints: []string{"web"}, + Service: "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr", + Rule: "Host(`foo.com`) && PathPrefix(`/`)", + Priority: 22, + RuleSyntax: "v3", + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "invalid-grpcroute-filter", + Weight: ptr.To(1), + GRPCStatus: &dynamic.GRPCStatus{ + Code: codes.Unavailable, + Msg: "Service Unavailable", + }, + }, + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "ExtensionRef filter with filterFunc error", + groupKindFilterFuncs: map[string]map[string]BuildFilterFunc{ + traefikv1alpha1.GroupName: {"Middleware": func(name, namespace string) (string, *dynamic.Middleware, error) { + return "", nil, errors.New("BOOM") + }}, + }, + 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-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + EntryPoints: []string{"web"}, + Service: "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr", + Rule: "Host(`foo.com`) && PathPrefix(`/`)", + Priority: 22, + RuleSyntax: "v3", + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "invalid-grpcroute-filter", + Weight: ptr.To(1), + GRPCStatus: &dynamic.GRPCStatus{ + Code: codes.Unavailable, + Msg: "Service Unavailable", + }, + }, + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + if test.expected == nil { + return + } + + k8sObjects, gwObjects := readResources(t, []string{"services.yml", "grpcroute/filter_extension_ref.yml"}) + + kubeClient := kubefake.NewSimpleClientset(k8sObjects...) + gwClient := newGatewaySimpleClientSet(t, gwObjects...) + + client := newClientImpl(kubeClient, gwClient) + + eventCh, err := client.WatchAll(nil, make(chan struct{})) + require.NoError(t, err) + + if len(k8sObjects) > 0 || len(gwObjects) > 0 { + // just wait for the first event + <-eventCh + } + + p := Provider{ + EntryPoints: test.entryPoints, + client: client, + } + + for group, kindFuncs := range test.groupKindFilterFuncs { + for kind, filterFunc := range kindFuncs { + p.RegisterFilterFuncs(group, kind, filterFunc) + } + } + conf := p.loadConfigurationFromGateways(context.Background()) + assert.Equal(t, test.expected, conf) + }) + } +} + func TestLoadTCPRoutes(t *testing.T) { testCases := []struct { desc string diff --git a/pkg/provider/kubernetes/k8s/parser.go b/pkg/provider/kubernetes/k8s/parser.go index 422513ade..053a912a1 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|EndpointSlice|Node|Service|ConfigMap|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|ServersTransportTCP|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute|ReferenceGrant|BackendTLSPolicy)$`) + acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|EndpointSlice|Node|Service|ConfigMap|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|ServersTransportTCP|GatewayClass|Gateway|GRPCRoute|HTTPRoute|TCPRoute|TLSRoute|ReferenceGrant|BackendTLSPolicy)$`) files := strings.Split(string(content), "---\n") retVal := make([]runtime.Object, 0, len(files)) From 0605f8bf09a985cb343b8e6155681ce3047e594d Mon Sep 17 00:00:00 2001 From: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com> Date: Wed, 23 Oct 2024 11:10:04 +0200 Subject: [PATCH 09/18] Document nativeLBByDefault annotation on Kubernetes Gateway provider --- docs/content/providers/kubernetes-gateway.md | 24 +++++++++++++++++ .../routing/providers/kubernetes-gateway.md | 27 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/docs/content/providers/kubernetes-gateway.md b/docs/content/providers/kubernetes-gateway.md index a6291db0d..9f2201dee 100644 --- a/docs/content/providers/kubernetes-gateway.md +++ b/docs/content/providers/kubernetes-gateway.md @@ -304,6 +304,30 @@ providers: --providers.kubernetesgateway.labelselector="app=traefik" ``` +### `nativeLBByDefault` + +_Optional, Default: false_ + +Defines whether to use Native Kubernetes load-balancing mode by default. +For more information, please check out the `traefik.io/service.nativelb` [service annotation documentation](../routing/providers/kubernetes-gateway.md#native-load-balancing). + +```yaml tab="File (YAML)" +providers: + kubernetesGateway: + nativeLBByDefault: true + # ... +``` + +```toml tab="File (TOML)" +[providers.kubernetesGateway] + nativeLBByDefault = true + # ... +``` + +```bash tab="CLI" +--providers.kubernetesgateway.nativeLBByDefault=true +``` + ### `throttleDuration` _Optional, Default: 0_ diff --git a/docs/content/routing/providers/kubernetes-gateway.md b/docs/content/routing/providers/kubernetes-gateway.md index 8e97b5c75..c2da4447c 100644 --- a/docs/content/routing/providers/kubernetes-gateway.md +++ b/docs/content/routing/providers/kubernetes-gateway.md @@ -723,4 +723,31 @@ X-Forwarded-Server: traefik-6b66d45748-ns8mt X-Real-Ip: 10.42.2.1 ``` +## Native Load Balancing + +By default, Traefik sends the traffic directly to the pod IPs and reuses the established connections to the backends for performance purposes. + +It is possible to override this behavior and configure Traefik to send the traffic to the service IP. +The Kubernetes service itself does the load balancing to the pods. +It can be done with the annotation `traefik.io/service.nativelb` on the backend `Service`. + +By default, NativeLB is `false`. + +!!! info "Default value" + + Note that it is possible to override the default value by using the option [`nativeLBByDefault`](../../providers/kubernetes-gateway.md#nativelbbydefault) at the provider level. + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: myservice + namespace: default + annotations: + traefik.io/service.nativelb: "true" +spec: +[...] +``` + {!traefik-for-business-applications.md!} \ No newline at end of file From 3d2336bc83e85f009ca2c4de8fb159a9138119ca Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 23 Oct 2024 17:06:04 +0200 Subject: [PATCH 10/18] Use golangci-lint action --- .github/workflows/validate.yaml | 24 ++++++++++++++++++++---- Makefile | 10 +++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 2ccec8f24..abcbc97d7 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -12,6 +12,25 @@ env: jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go ${{ env.GO_VERSION }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: "${{ env.GOLANGCI_LINT_VERSION }}" + validate: runs-on: ubuntu-latest @@ -26,9 +45,6 @@ jobs: with: go-version: ${{ env.GO_VERSION }} - - name: Install golangci-lint ${{ env.GOLANGCI_LINT_VERSION }} - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_LINT_VERSION} - - name: Install misspell ${{ env.MISSPELL_VERSION }} run: curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION} @@ -36,7 +52,7 @@ jobs: run: touch webui/static/index.html - name: Validate - run: make validate + run: make validate-files validate-generate: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index af62ff77c..393d1b62a 100644 --- a/Makefile +++ b/Makefile @@ -120,20 +120,16 @@ lint: .PHONY: validate-files #? validate-files: Validate code and docs -validate-files: lint +validate-files: $(foreach exec,$(LINT_EXECUTABLES),\ $(if $(shell which $(exec)),,$(error "No $(exec) in PATH"))) + $(CURDIR)/script/validate-vendor.sh $(CURDIR)/script/validate-misspell.sh $(CURDIR)/script/validate-shell-script.sh .PHONY: validate #? validate: Validate code, docs, and vendor -validate: lint - $(foreach exec,$(EXECUTABLES),\ - $(if $(shell which $(exec)),,$(error "No $(exec) in PATH"))) - $(CURDIR)/script/validate-vendor.sh - $(CURDIR)/script/validate-misspell.sh - $(CURDIR)/script/validate-shell-script.sh +validate: lint validate-files # Target for building images for multiple architectures. .PHONY: multi-arch-image-% From edc0a52b5ae3945082b9aef755f65557316bbd4a Mon Sep 17 00:00:00 2001 From: Dylan Rodgers <94392934+tomatokoolaid@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:52:04 -0600 Subject: [PATCH 11/18] Updates to Business Callouts in Docs --- docs/content/getting-started/faq.md | 2 ++ .../includes/traefik-for-business-applications.md | 12 ++++++------ docs/content/index.md | 12 +++++------- docs/content/middlewares/http/basicauth.md | 1 + docs/content/middlewares/http/forwardauth.md | 1 + docs/content/middlewares/http/redirectregex.md | 2 ++ docs/content/middlewares/http/stripprefix.md | 2 ++ docs/content/observability/access-logs.md | 2 ++ docs/content/observability/logs.md | 2 ++ docs/content/operations/api.md | 2 ++ docs/content/plugins/index.md | 2 ++ .../user-guides/docker-compose/acme-dns/index.md | 2 ++ .../user-guides/docker-compose/acme-tls/index.md | 2 ++ 13 files changed, 31 insertions(+), 13 deletions(-) diff --git a/docs/content/getting-started/faq.md b/docs/content/getting-started/faq.md index facdd71bf..66f2d4d04 100644 --- a/docs/content/getting-started/faq.md +++ b/docs/content/getting-started/faq.md @@ -251,3 +251,5 @@ In which case, you should make sure your infrastructure is properly set up for a ```shell LEGO_DISABLE_CNAME_SUPPORT=true ``` + +{!traefik-for-business-applications.md!} diff --git a/docs/content/includes/traefik-for-business-applications.md b/docs/content/includes/traefik-for-business-applications.md index 474c815d2..b0e360f95 100644 --- a/docs/content/includes/traefik-for-business-applications.md +++ b/docs/content/includes/traefik-for-business-applications.md @@ -1,10 +1,10 @@ --- -!!! question "Using Traefik OSS in Production? Consider Adding Advanced Capabilities." +!!! question "Using Traefik OSS in Production?" - Add API Gateway or API Management capabilities seamlessly to your existing Traefik deployments. - No rip and replace. No learning curve. + If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS. - - [Explore our API Gateway](https://traefik.io/traefik-hub-api-gateway/) ([Watch the Demo Video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc)) - - [Explore our API Management](https://traefik.io/traefik-hub/) - - [Get 24/7/365 Commercial Support for Traefik OSS](https://info.traefik.io/request-commercial-support) + - [Watch our API Gateway Demo Video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc) + - [Request 24/7/365 OSS Support](https://info.traefik.io/request-commercial-support?cta=doc) + + Adding API Gateway capabilities to Traefik OSS is fast and seamless. There's no rip and replace and all configurations remain intact. See it in action via [this short video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc). diff --git a/docs/content/index.md b/docs/content/index.md index 512eee9f9..b52832377 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -18,11 +18,7 @@ Traefik is natively compliant with every major cluster technology, such as Kuber 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. -And if your needs change, you can add API gateway and API management capabilities seamlessly to your existing Traefik deployments. It takes less than a minute, there’s no rip-and-replace, and all your configurations are preserved. See how it works in this video: - -
- -
+And if your needs change, you can add API gateway and API management capabilities seamlessly to your existing Traefik deployments. It takes less than a minute, there’s no rip-and-replace, and all your configurations are preserved. See this in action in [our API gateway demo video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=docs). Developing Traefik, our main goal is to make it effortless to use, and we're sure you'll enjoy it. @@ -30,6 +26,8 @@ Developing Traefik, our main goal is to make it effortless to use, and we're sur !!! info - Join our user friendly and active [Community Forum](https://community.traefik.io "Link to Traefik Community Forum") to discuss, learn, and connect with the Traefik community. + Have a question? Join our [Community Forum](https://community.traefik.io "Link to Traefik Community Forum") to discuss, learn, and connect with the Traefik community. - Using Traefik OSS in Production? Consider our enterprise-grade [API Gateway](https://traefik.io/traefik-hub-api-gateway/), [API Management](https://traefik.io/traefik-hub/), and [Commercial Support](https://info.traefik.io/request-commercial-support) solutions. + Using Traefik OSS in Production? Consider our enterprise-grade [API Gateway](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc) or our [24/7/365 OSS Support](https://info.traefik.io/request-commercial-support?cta=doc). + + Explore our API Gateway upgrade via [this short demo video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc). diff --git a/docs/content/middlewares/http/basicauth.md b/docs/content/middlewares/http/basicauth.md index 7384e8ae1..82fd00ae4 100644 --- a/docs/content/middlewares/http/basicauth.md +++ b/docs/content/middlewares/http/basicauth.md @@ -404,3 +404,4 @@ http: [http.middlewares.test-auth.basicAuth] removeHeader = true ``` +{!traefik-for-business-applications.md!} diff --git a/docs/content/middlewares/http/forwardauth.md b/docs/content/middlewares/http/forwardauth.md index 238b8f3aa..8e8485c9e 100644 --- a/docs/content/middlewares/http/forwardauth.md +++ b/docs/content/middlewares/http/forwardauth.md @@ -637,3 +637,4 @@ http: [http.middlewares.test-auth.forwardAuth.tls] insecureSkipVerify: true ``` +{!traefik-for-business-applications.md!} diff --git a/docs/content/middlewares/http/redirectregex.md b/docs/content/middlewares/http/redirectregex.md index ccb15a09e..e10af16fd 100644 --- a/docs/content/middlewares/http/redirectregex.md +++ b/docs/content/middlewares/http/redirectregex.md @@ -99,3 +99,5 @@ The `replacement` option defines how to modify the URL to have the new target UR !!! warning Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax. + +{!traefik-for-business-applications.md!} diff --git a/docs/content/middlewares/http/stripprefix.md b/docs/content/middlewares/http/stripprefix.md index 2a51fb196..35bb527a9 100644 --- a/docs/content/middlewares/http/stripprefix.md +++ b/docs/content/middlewares/http/stripprefix.md @@ -170,3 +170,5 @@ http: prefixes = ["/foobar"] forceSlash = false ``` + +{!traefik-for-business-applications.md!} diff --git a/docs/content/observability/access-logs.md b/docs/content/observability/access-logs.md index ce7718a58..2a0c83398 100644 --- a/docs/content/observability/access-logs.md +++ b/docs/content/observability/access-logs.md @@ -268,3 +268,5 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock ``` + +{!traefik-for-business-applications.md!} diff --git a/docs/content/observability/logs.md b/docs/content/observability/logs.md index 46068f4eb..f350c5f67 100644 --- a/docs/content/observability/logs.md +++ b/docs/content/observability/logs.md @@ -89,3 +89,5 @@ This allows the logs to be rotated and processed by an external program, such as !!! warning This does not work on Windows due to the lack of USR signals. + +{!traefik-for-business-applications.md!} diff --git a/docs/content/operations/api.md b/docs/content/operations/api.md index a495ab4e5..7c8248c2e 100644 --- a/docs/content/operations/api.md +++ b/docs/content/operations/api.md @@ -174,3 +174,5 @@ All the following endpoints must be accessed with a `GET` HTTP request. | `/debug/pprof/profile` | See the [pprof Profile](https://golang.org/pkg/net/http/pprof/#Profile) Go documentation. | | `/debug/pprof/symbol` | See the [pprof Symbol](https://golang.org/pkg/net/http/pprof/#Symbol) Go documentation. | | `/debug/pprof/trace` | See the [pprof Trace](https://golang.org/pkg/net/http/pprof/#Trace) Go documentation. | + +{!traefik-for-business-applications.md!} diff --git a/docs/content/plugins/index.md b/docs/content/plugins/index.md index 7eb57106d..9cd3662f8 100644 --- a/docs/content/plugins/index.md +++ b/docs/content/plugins/index.md @@ -30,3 +30,5 @@ They need not be compiled, and no complex toolchain is necessary to build them. The experience of implementing a Traefik plugin is comparable to writing a web browser extension. To learn more about Traefik plugin creation, please refer to the [developer documentation](https://plugins.traefik.io/create). + +{!traefik-for-business-applications.md!} diff --git a/docs/content/user-guides/docker-compose/acme-dns/index.md b/docs/content/user-guides/docker-compose/acme-dns/index.md index 5affbe009..57752f855 100644 --- a/docs/content/user-guides/docker-compose/acme-dns/index.md +++ b/docs/content/user-guides/docker-compose/acme-dns/index.md @@ -186,3 +186,5 @@ environment: - "OVH_APPLICATION_SECRET_FILE=/run/secrets/ovh_application_secret" - "OVH_CONSUMER_KEY_FILE=/run/secrets/ovh_consumer_key" ``` + +{!traefik-for-business-applications.md!} diff --git a/docs/content/user-guides/docker-compose/acme-tls/index.md b/docs/content/user-guides/docker-compose/acme-tls/index.md index a781a1cd3..cb1a40e49 100644 --- a/docs/content/user-guides/docker-compose/acme-tls/index.md +++ b/docs/content/user-guides/docker-compose/acme-tls/index.md @@ -82,3 +82,5 @@ labels: # Uses the Host rule to define which certificate to issue - "traefik.http.routers.whoami.tls.certresolver=myresolver" ``` + +{!traefik-for-business-applications.md!} From e3ed52ba7caa723bc34a7618652c2b7c5c4bcfef Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Fri, 25 Oct 2024 14:26:04 +0200 Subject: [PATCH 12/18] Detect and drop broken conns in the fastproxy pool Co-authored-by: Romain --- pkg/proxy/fast/builder.go | 11 +- pkg/proxy/fast/connpool.go | 341 +++++++++++++++++++++++-- pkg/proxy/fast/connpool_test.go | 22 +- pkg/proxy/fast/proxy.go | 209 ++------------- pkg/proxy/fast/proxy_websocket_test.go | 8 +- pkg/proxy/fast/upgrade.go | 108 ++++---- pkg/proxy/httputil/proxy.go | 7 +- 7 files changed, 426 insertions(+), 280 deletions(-) diff --git a/pkg/proxy/fast/builder.go b/pkg/proxy/fast/builder.go index c53363dad..b41323dda 100644 --- a/pkg/proxy/fast/builder.go +++ b/pkg/proxy/fast/builder.go @@ -79,18 +79,13 @@ func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, passHostHeader, return nil, fmt.Errorf("getting ServersTransport: %w", err) } - var responseHeaderTimeout time.Duration - if cfg.ForwardingTimeouts != nil { - responseHeaderTimeout = time.Duration(cfg.ForwardingTimeouts.ResponseHeaderTimeout) - } - tlsConfig, err := r.transportManager.GetTLSConfig(cfgName) if err != nil { return nil, fmt.Errorf("getting TLS config: %w", err) } pool := r.getPool(cfgName, cfg, tlsConfig, targetURL, proxyURL) - return NewReverseProxy(targetURL, proxyURL, r.debug, passHostHeader, preservePath, responseHeaderTimeout, pool) + return NewReverseProxy(targetURL, proxyURL, r.debug, passHostHeader, preservePath, pool) } func (r *ProxyBuilder) getPool(cfgName string, config *dynamic.ServersTransport, tlsConfig *tls.Config, targetURL *url.URL, proxyURL *url.URL) *connPool { @@ -106,9 +101,11 @@ func (r *ProxyBuilder) getPool(cfgName string, config *dynamic.ServersTransport, idleConnTimeout := 90 * time.Second dialTimeout := 30 * time.Second + var responseHeaderTimeout time.Duration if config.ForwardingTimeouts != nil { idleConnTimeout = time.Duration(config.ForwardingTimeouts.IdleConnTimeout) dialTimeout = time.Duration(config.ForwardingTimeouts.DialTimeout) + responseHeaderTimeout = time.Duration(config.ForwardingTimeouts.ResponseHeaderTimeout) } proxyDialer := newDialer(dialerConfig{ @@ -119,7 +116,7 @@ func (r *ProxyBuilder) getPool(cfgName string, config *dynamic.ServersTransport, ProxyURL: proxyURL, }, tlsConfig) - connPool := newConnPool(config.MaxIdleConnsPerHost, idleConnTimeout, func() (net.Conn, error) { + connPool := newConnPool(config.MaxIdleConnsPerHost, idleConnTimeout, responseHeaderTimeout, func() (net.Conn, error) { return proxyDialer.Dial("tcp", addrFromURL(targetURL)) }) diff --git a/pkg/proxy/fast/connpool.go b/pkg/proxy/fast/connpool.go index e0d2c4e7f..375fac2fb 100644 --- a/pkg/proxy/fast/connpool.go +++ b/pkg/proxy/fast/connpool.go @@ -1,42 +1,309 @@ package fast import ( + "bufio" + "errors" "fmt" + "io" "net" + "net/http" + "net/http/httputil" + "strings" + "sync" + "sync/atomic" "time" "github.com/rs/zerolog/log" + "github.com/valyala/fasthttp" ) +// rwWithUpgrade contains a ResponseWriter and an upgradeHandler, +// used to upgrade the connection (e.g. Websockets). +type rwWithUpgrade struct { + RW http.ResponseWriter + Upgrade upgradeHandler +} + // conn is an enriched net.Conn. type conn struct { net.Conn + RWCh chan rwWithUpgrade + ErrCh chan error + + br *bufio.Reader + idleAt time.Time // the last time it was marked as idle. idleTimeout time.Duration + + responseHeaderTimeout time.Duration + + expectedResponse atomic.Bool + broken atomic.Bool + upgraded atomic.Bool + + closeMu sync.Mutex + closed bool + closeErr error + + bufferPool *pool[[]byte] + limitedReaderPool *pool[*io.LimitedReader] } -func (c *conn) isExpired() bool { +// Read reads data from the connection. +// Overrides conn Read to use the buffered reader. +func (c *conn) Read(b []byte) (n int, err error) { + return c.br.Read(b) +} + +// Close closes the connection. +// Ensures that connection is closed only once, +// to avoid duplicate close error. +func (c *conn) Close() error { + c.closeMu.Lock() + defer c.closeMu.Unlock() + + if c.closed { + return c.closeErr + } + + c.closed = true + c.closeErr = c.Conn.Close() + + return c.closeErr +} + +// isStale returns whether the connection is in an invalid state (i.e. expired/broken). +func (c *conn) isStale() bool { expTime := c.idleAt.Add(c.idleTimeout) - return c.idleTimeout > 0 && time.Now().After(expTime) + return c.idleTimeout > 0 && time.Now().After(expTime) || c.broken.Load() +} + +// isUpgraded returns whether this connection has been upgraded (e.g. Websocket). +// An upgraded connection should not be reused and putted back in the connection pool. +func (c *conn) isUpgraded() bool { + return c.upgraded.Load() +} + +// readLoop handles the successive HTTP response read operations on the connection, +// and watches for unsolicited bytes or connection errors when idle. +func (c *conn) readLoop() { + defer c.Close() + + for { + _, err := c.br.Peek(1) + if err != nil { + select { + // An error occurred while a response was expected to be handled. + case <-c.RWCh: + c.ErrCh <- err + // An error occurred on an idle connection. + default: + c.broken.Store(true) + } + return + } + + // Unsolicited response received on an idle connection. + if !c.expectedResponse.Load() { + c.broken.Store(true) + return + } + + r := <-c.RWCh + if err = c.handleResponse(r); err != nil { + c.ErrCh <- err + return + } + + c.expectedResponse.Store(false) + c.ErrCh <- nil + } +} + +func (c *conn) handleResponse(r rwWithUpgrade) error { + res := fasthttp.AcquireResponse() + defer fasthttp.ReleaseResponse(res) + + res.Header.SetNoDefaultContentType(true) + + for { + var ( + timer *time.Timer + errTimeout atomic.Pointer[timeoutError] + ) + if c.responseHeaderTimeout > 0 { + timer = time.AfterFunc(c.responseHeaderTimeout, func() { + errTimeout.Store(&timeoutError{errors.New("timeout awaiting response headers")}) + c.Close() // This close call is needed to interrupt the read operation below when the timeout is over. + }) + } + + res.Header.SetNoDefaultContentType(true) + if err := res.Header.Read(c.br); err != nil { + if c.responseHeaderTimeout > 0 { + if errT := errTimeout.Load(); errT != nil { + return errT + } + } + return err + } + + if timer != nil { + timer.Stop() + } + + fixPragmaCacheControl(&res.Header) + + resCode := res.StatusCode() + is1xx := 100 <= resCode && resCode <= 199 + // treat 101 as a terminal status, see issue 26161 + is1xxNonTerminal := is1xx && resCode != http.StatusSwitchingProtocols + if is1xxNonTerminal { + removeConnectionHeaders(&res.Header) + h := r.RW.Header() + + for _, header := range hopHeaders { + res.Header.Del(header) + } + + res.Header.VisitAll(func(key, value []byte) { + r.RW.Header().Add(string(key), string(value)) + }) + + r.RW.WriteHeader(res.StatusCode()) + // Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses + for k := range h { + delete(h, k) + } + + res.Reset() + res.Header.Reset() + res.Header.SetNoDefaultContentType(true) + + continue + } + break + } + + announcedTrailers := res.Header.Peek("Trailer") + + // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc) + if res.StatusCode() == http.StatusSwitchingProtocols { + r.Upgrade(r.RW, res, c) + c.upgraded.Store(true) // As the connection has been upgraded, it cannot be added back to the pool. + return nil + } + + removeConnectionHeaders(&res.Header) + + for _, header := range hopHeaders { + res.Header.Del(header) + } + + if len(announcedTrailers) > 0 { + res.Header.Add("Trailer", string(announcedTrailers)) + } + + res.Header.VisitAll(func(key, value []byte) { + r.RW.Header().Add(string(key), string(value)) + }) + + r.RW.WriteHeader(res.StatusCode()) + + if res.Header.ContentLength() == 0 { + return nil + } + + // When a body is not allowed for a given status code the body is ignored. + // The connection will be marked as broken by the next Peek in the readloop. + if !isBodyAllowedForStatus(res.StatusCode()) { + return nil + } + + // Chunked response, Content-Length is set to -1 by FastProxy when "Transfer-Encoding: chunked" header is received. + if res.Header.ContentLength() == -1 { + cbr := httputil.NewChunkedReader(c.br) + + b := c.bufferPool.Get() + if b == nil { + b = make([]byte, bufferSize) + } + defer c.bufferPool.Put(b) + + if _, err := io.CopyBuffer(&writeFlusher{r.RW}, cbr, b); err != nil { + return err + } + + res.Header.Reset() + res.Header.SetNoDefaultContentType(true) + if err := res.Header.ReadTrailer(c.br); err != nil { + return err + } + + if res.Header.Len() > 0 { + var announcedTrailersKey []string + if len(announcedTrailers) > 0 { + announcedTrailersKey = strings.Split(string(announcedTrailers), ",") + } + + res.Header.VisitAll(func(key, value []byte) { + for _, s := range announcedTrailersKey { + if strings.EqualFold(s, strings.TrimSpace(string(key))) { + r.RW.Header().Add(string(key), string(value)) + return + } + } + + r.RW.Header().Add(http.TrailerPrefix+string(key), string(value)) + }) + } + + return nil + } + + brl := c.limitedReaderPool.Get() + if brl == nil { + brl = &io.LimitedReader{} + } + defer c.limitedReaderPool.Put(brl) + + brl.R = c.br + brl.N = int64(res.Header.ContentLength()) + + b := c.bufferPool.Get() + if b == nil { + b = make([]byte, bufferSize) + } + defer c.bufferPool.Put(b) + + if _, err := io.CopyBuffer(r.RW, brl, b); err != nil { + return err + } + + return nil } // connPool is a net.Conn pool implementation using channels. type connPool struct { - dialer func() (net.Conn, error) - idleConns chan *conn - idleConnTimeout time.Duration - ticker *time.Ticker - doneCh chan struct{} + dialer func() (net.Conn, error) + idleConns chan *conn + idleConnTimeout time.Duration + responseHeaderTimeout time.Duration + ticker *time.Ticker + bufferPool pool[[]byte] + limitedReaderPool pool[*io.LimitedReader] + doneCh chan struct{} } // newConnPool creates a new connPool. -func newConnPool(maxIdleConn int, idleConnTimeout time.Duration, dialer func() (net.Conn, error)) *connPool { +func newConnPool(maxIdleConn int, idleConnTimeout, responseHeaderTimeout time.Duration, dialer func() (net.Conn, error)) *connPool { c := &connPool{ - dialer: dialer, - idleConns: make(chan *conn, maxIdleConn), - idleConnTimeout: idleConnTimeout, - doneCh: make(chan struct{}), + dialer: dialer, + idleConns: make(chan *conn, maxIdleConn), + idleConnTimeout: idleConnTimeout, + responseHeaderTimeout: responseHeaderTimeout, + doneCh: make(chan struct{}), } if idleConnTimeout > 0 { @@ -72,22 +339,28 @@ func (c *connPool) AcquireConn() (*conn, error) { return nil, err } - if !co.isExpired() { + if !co.isStale() { return co, nil } - // As the acquired conn is expired we can close it + // As the acquired conn is stale we can close it // without putting it again into the pool. if err := co.Close(); err != nil { log.Debug(). Err(err). - Msg("Unexpected error while releasing the connection") + Msg("Unexpected error while closing the connection") } } } // ReleaseConn releases the given net.Conn to the pool. func (c *connPool) ReleaseConn(co *conn) { + // An upgraded connection cannot be safely reused for another roundTrip, + // thus we are not putting it back to the pool. + if co.isUpgraded() { + return + } + co.idleAt = time.Now() c.releaseConn(co) } @@ -97,7 +370,7 @@ func (c *connPool) cleanIdleConns() { for { select { case co := <-c.idleConns: - if !co.isExpired() { + if !co.isStale() { c.releaseConn(co) return } @@ -105,7 +378,7 @@ func (c *connPool) cleanIdleConns() { if err := co.Close(); err != nil { log.Debug(). Err(err). - Msg("Unexpected error while releasing the connection") + Msg("Unexpected error while closing the connection") } default: @@ -155,9 +428,33 @@ func (c *connPool) askForNewConn(errCh chan<- error) { return } - c.releaseConn(&conn{ - Conn: co, - idleAt: time.Now(), - idleTimeout: c.idleConnTimeout, - }) + newConn := &conn{ + Conn: co, + br: bufio.NewReaderSize(co, bufioSize), + idleAt: time.Now(), + idleTimeout: c.idleConnTimeout, + responseHeaderTimeout: c.responseHeaderTimeout, + RWCh: make(chan rwWithUpgrade), + ErrCh: make(chan error), + bufferPool: &c.bufferPool, + limitedReaderPool: &c.limitedReaderPool, + } + go newConn.readLoop() + + c.releaseConn(newConn) +} + +// isBodyAllowedForStatus reports whether a given response status code +// permits a body. See RFC 7230, section 3.3. +// From https://github.com/golang/go/blame/master/src/net/http/transfer.go#L459 +func isBodyAllowedForStatus(status int) bool { + switch { + case status >= 100 && status <= 199: + return false + case status == 204: + return false + case status == 304: + return false + } + return true } diff --git a/pkg/proxy/fast/connpool_test.go b/pkg/proxy/fast/connpool_test.go index 696e62a36..7532a3e3b 100644 --- a/pkg/proxy/fast/connpool_test.go +++ b/pkg/proxy/fast/connpool_test.go @@ -58,7 +58,7 @@ func TestConnPool_ConnReuse(t *testing.T) { return &net.TCPConn{}, nil } - pool := newConnPool(2, 0, dialer) + pool := newConnPool(2, 0, 0, dialer) test.poolFn(pool) assert.Equal(t, test.expected, connAlloc) @@ -102,13 +102,16 @@ func TestConnPool_MaxIdleConn(t *testing.T) { var keepOpenedConn int dialer := func() (net.Conn, error) { keepOpenedConn++ - return &mockConn{closeFn: func() error { - keepOpenedConn-- - return nil - }}, nil + return &mockConn{ + doneCh: make(chan struct{}), + closeFn: func() error { + keepOpenedConn-- + return nil + }, + }, nil } - pool := newConnPool(test.maxIdleConn, 0, dialer) + pool := newConnPool(test.maxIdleConn, 0, 0, dialer) test.poolFn(pool) assert.Equal(t, test.expected, keepOpenedConn) @@ -129,7 +132,7 @@ func TestGC(t *testing.T) { return c, nil } - pools["test"] = newConnPool(10, 1*time.Second, dialer) + pools["test"] = newConnPool(10, 1*time.Second, 0, dialer) runtime.SetFinalizer(pools["test"], func(p *connPool) { isDestroyed = true }) @@ -149,10 +152,12 @@ func TestGC(t *testing.T) { type mockConn struct { closeFn func() error + doneCh chan struct{} // makes sure that the readLoop is blocking avoiding close. } func (m *mockConn) Read(_ []byte) (n int, err error) { - panic("implement me") + <-m.doneCh + return 0, nil } func (m *mockConn) Write(_ []byte) (n int, err error) { @@ -160,6 +165,7 @@ func (m *mockConn) Write(_ []byte) (n int, err error) { } func (m *mockConn) Close() error { + defer close(m.doneCh) if m.closeFn != nil { return m.closeFn() } diff --git a/pkg/proxy/fast/proxy.go b/pkg/proxy/fast/proxy.go index 388a4d73c..a400ce646 100644 --- a/pkg/proxy/fast/proxy.go +++ b/pkg/proxy/fast/proxy.go @@ -4,18 +4,14 @@ import ( "bufio" "bytes" "encoding/base64" - "errors" "fmt" "io" "net" "net/http" "net/http/httptrace" - "net/http/httputil" "net/url" "strings" "sync" - "sync/atomic" - "time" "github.com/rs/zerolog/log" proxyhttputil "github.com/traefik/traefik/v3/pkg/proxy/httputil" @@ -57,15 +53,6 @@ func (p *pool[T]) Put(x T) { p.pool.Put(x) } -type buffConn struct { - *bufio.Reader - net.Conn -} - -func (b buffConn) Read(p []byte) (int, error) { - return b.Reader.Read(p) -} - type writeDetector struct { net.Conn @@ -112,21 +99,17 @@ type ReverseProxy struct { connPool *connPool - bufferPool pool[[]byte] - readerPool pool[*bufio.Reader] - writerPool pool[*bufio.Writer] - limitReaderPool pool[*io.LimitedReader] + writerPool pool[*bufio.Writer] proxyAuth string - targetURL *url.URL - passHostHeader bool - preservePath bool - responseHeaderTimeout time.Duration + targetURL *url.URL + passHostHeader bool + preservePath bool } // NewReverseProxy creates a new ReverseProxy. -func NewReverseProxy(targetURL, proxyURL *url.URL, debug, passHostHeader, preservePath bool, responseHeaderTimeout time.Duration, connPool *connPool) (*ReverseProxy, error) { +func NewReverseProxy(targetURL, proxyURL *url.URL, debug, passHostHeader, preservePath bool, connPool *connPool) (*ReverseProxy, error) { var proxyAuth string if proxyURL != nil && proxyURL.User != nil && targetURL.Scheme == "http" { username := proxyURL.User.Username() @@ -135,13 +118,12 @@ func NewReverseProxy(targetURL, proxyURL *url.URL, debug, passHostHeader, preser } return &ReverseProxy{ - debug: debug, - passHostHeader: passHostHeader, - preservePath: preservePath, - targetURL: targetURL, - proxyAuth: proxyAuth, - connPool: connPool, - responseHeaderTimeout: responseHeaderTimeout, + debug: debug, + passHostHeader: passHostHeader, + preservePath: preservePath, + targetURL: targetURL, + proxyAuth: proxyAuth, + connPool: connPool, }, nil } @@ -273,8 +255,15 @@ func (p *ReverseProxy) roundTrip(rw http.ResponseWriter, req *http.Request, outR return fmt.Errorf("acquire connection: %w", err) } + // Before writing the request, + // we mark the conn as expecting to handle a response. + co.expectedResponse.Store(true) + wd := &writeDetector{Conn: co} + // TODO: do not wait to write the full request before reading the response (to handle "100 Continue"). + // TODO: this is currently impossible with fasthttp to write the request partially (headers only). + // Currently, writing the request fully is a mandatory step before handling the response. err = p.writeRequest(wd, outReq) if wd.written && trace != nil && trace.WroteRequest != nil { // WroteRequest hook is used by the tracing middleware to detect if the request has been written. @@ -293,169 +282,17 @@ func (p *ReverseProxy) roundTrip(rw http.ResponseWriter, req *http.Request, outR } } - br := p.readerPool.Get() - if br == nil { - br = bufio.NewReaderSize(co, bufioSize) - } - defer p.readerPool.Put(br) - - br.Reset(co) - - res := fasthttp.AcquireResponse() - defer fasthttp.ReleaseResponse(res) - - res.Header.SetNoDefaultContentType(true) - - for { - var timer *time.Timer - errTimeout := atomic.Pointer[timeoutError]{} - if p.responseHeaderTimeout > 0 { - timer = time.AfterFunc(p.responseHeaderTimeout, func() { - errTimeout.Store(&timeoutError{errors.New("timeout awaiting response headers")}) - co.Close() - }) - } - - res.Header.SetNoDefaultContentType(true) - if err := res.Header.Read(br); err != nil { - if p.responseHeaderTimeout > 0 { - if errT := errTimeout.Load(); errT != nil { - return errT - } - } - co.Close() - return err - } - - if timer != nil { - timer.Stop() - } - - fixPragmaCacheControl(&res.Header) - - resCode := res.StatusCode() - is1xx := 100 <= resCode && resCode <= 199 - // treat 101 as a terminal status, see issue 26161 - is1xxNonTerminal := is1xx && resCode != http.StatusSwitchingProtocols - if is1xxNonTerminal { - removeConnectionHeaders(&res.Header) - h := rw.Header() - - for _, header := range hopHeaders { - res.Header.Del(header) - } - - res.Header.VisitAll(func(key, value []byte) { - rw.Header().Add(string(key), string(value)) - }) - - rw.WriteHeader(res.StatusCode()) - // Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses - for k := range h { - delete(h, k) - } - - res.Reset() - res.Header.Reset() - res.Header.SetNoDefaultContentType(true) - - continue - } - break + // Sending the responseWriter unlocks the connection readLoop, to handle the response. + co.RWCh <- rwWithUpgrade{ + RW: rw, + Upgrade: upgradeResponseHandler(req.Context(), reqUpType), } - announcedTrailers := res.Header.Peek("Trailer") - - // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc) - if res.StatusCode() == http.StatusSwitchingProtocols { - // As the connection has been hijacked, it cannot be added back to the pool. - handleUpgradeResponse(rw, req, reqUpType, res, buffConn{Conn: co, Reader: br}) - return nil - } - - removeConnectionHeaders(&res.Header) - - for _, header := range hopHeaders { - res.Header.Del(header) - } - - if len(announcedTrailers) > 0 { - res.Header.Add("Trailer", string(announcedTrailers)) - } - - res.Header.VisitAll(func(key, value []byte) { - rw.Header().Add(string(key), string(value)) - }) - - rw.WriteHeader(res.StatusCode()) - - // Chunked response, Content-Length is set to -1 by FastProxy when "Transfer-Encoding: chunked" header is received. - if res.Header.ContentLength() == -1 { - cbr := httputil.NewChunkedReader(br) - - b := p.bufferPool.Get() - if b == nil { - b = make([]byte, bufferSize) - } - defer p.bufferPool.Put(b) - - if _, err := io.CopyBuffer(&writeFlusher{rw}, cbr, b); err != nil { - co.Close() - return err - } - - res.Header.Reset() - res.Header.SetNoDefaultContentType(true) - if err := res.Header.ReadTrailer(br); err != nil { - co.Close() - return err - } - - if res.Header.Len() > 0 { - var announcedTrailersKey []string - if len(announcedTrailers) > 0 { - announcedTrailersKey = strings.Split(string(announcedTrailers), ",") - } - - res.Header.VisitAll(func(key, value []byte) { - for _, s := range announcedTrailersKey { - if strings.EqualFold(s, strings.TrimSpace(string(key))) { - rw.Header().Add(string(key), string(value)) - return - } - } - - rw.Header().Add(http.TrailerPrefix+string(key), string(value)) - }) - } - - p.connPool.ReleaseConn(co) - - return nil - } - - brl := p.limitReaderPool.Get() - if brl == nil { - brl = &io.LimitedReader{} - } - defer p.limitReaderPool.Put(brl) - - brl.R = br - brl.N = int64(res.Header.ContentLength()) - - b := p.bufferPool.Get() - if b == nil { - b = make([]byte, bufferSize) - } - defer p.bufferPool.Put(b) - - if _, err := io.CopyBuffer(rw, brl, b); err != nil { - co.Close() + if err := <-co.ErrCh; err != nil { return err } p.connPool.ReleaseConn(co) - return nil } diff --git a/pkg/proxy/fast/proxy_websocket_test.go b/pkg/proxy/fast/proxy_websocket_test.go index 8297ac485..b057f8b58 100644 --- a/pkg/proxy/fast/proxy_websocket_test.go +++ b/pkg/proxy/fast/proxy_websocket_test.go @@ -362,7 +362,7 @@ func TestWebSocketRequestWithHeadersInResponseWriter(t *testing.T) { u := parseURI(t, srv.URL) - f, err := NewReverseProxy(u, nil, true, false, false, 0, newConnPool(1, 0, func() (net.Conn, error) { + f, err := NewReverseProxy(u, nil, true, false, false, newConnPool(1, 0, 0, func() (net.Conn, error) { return net.Dial("tcp", u.Host) })) require.NoError(t, err) @@ -434,7 +434,7 @@ func TestWebSocketUpgradeFailed(t *testing.T) { defer srv.Close() u := parseURI(t, srv.URL) - f, err := NewReverseProxy(u, nil, true, false, false, 0, newConnPool(1, 0, func() (net.Conn, error) { + f, err := NewReverseProxy(u, nil, true, false, false, newConnPool(1, 0, 0, func() (net.Conn, error) { return net.Dial("tcp", u.Host) })) require.NoError(t, err) @@ -663,7 +663,7 @@ func parseURI(t *testing.T, uri string) *url.URL { func createConnectionPool(target string, tlsConfig *tls.Config) *connPool { u := testhelpers.MustParseURL(target) - return newConnPool(200, 0, func() (net.Conn, error) { + return newConnPool(200, 0, 0, func() (net.Conn, error) { if tlsConfig != nil { return tls.Dial("tcp", u.Host, tlsConfig) } @@ -676,7 +676,7 @@ func createProxyWithForwarder(t *testing.T, uri string, pool *connPool) *httptes t.Helper() u := parseURI(t, uri) - proxy, err := NewReverseProxy(u, nil, false, true, false, 0, pool) + proxy, err := NewReverseProxy(u, nil, false, true, false, pool) require.NoError(t, err) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { diff --git a/pkg/proxy/fast/upgrade.go b/pkg/proxy/fast/upgrade.go index a42fc97d8..7bec09e49 100644 --- a/pkg/proxy/fast/upgrade.go +++ b/pkg/proxy/fast/upgrade.go @@ -2,6 +2,7 @@ package fast import ( "bytes" + "context" "fmt" "io" "net" @@ -19,72 +20,75 @@ type switchProtocolCopier struct { user, backend io.ReadWriter } -func (c switchProtocolCopier) copyFromBackend(errc chan<- error) { +func (c switchProtocolCopier) copyFromBackend(errCh chan<- error) { _, err := io.Copy(c.user, c.backend) - errc <- err + errCh <- err } -func (c switchProtocolCopier) copyToBackend(errc chan<- error) { +func (c switchProtocolCopier) copyToBackend(errCh chan<- error) { _, err := io.Copy(c.backend, c.user) - errc <- err + errCh <- err } -func handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, reqUpType string, res *fasthttp.Response, backConn net.Conn) { - defer backConn.Close() +type upgradeHandler func(rw http.ResponseWriter, res *fasthttp.Response, backConn net.Conn) - resUpType := upgradeTypeFastHTTP(&res.Header) +func upgradeResponseHandler(ctx context.Context, reqUpType string) upgradeHandler { + return func(rw http.ResponseWriter, res *fasthttp.Response, backConn net.Conn) { + resUpType := upgradeTypeFastHTTP(&res.Header) - if !strings.EqualFold(reqUpType, resUpType) { - httputil.ErrorHandler(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) - return - } - - hj, ok := rw.(http.Hijacker) - if !ok { - httputil.ErrorHandler(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) - return - } - backConnCloseCh := make(chan bool) - go func() { - // Ensure that the cancellation of a request closes the backend. - // See issue https://golang.org/issue/35559. - select { - case <-req.Context().Done(): - case <-backConnCloseCh: + if !strings.EqualFold(reqUpType, resUpType) { + httputil.ErrorHandlerWithContext(ctx, rw, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) + backConn.Close() + return } - _ = backConn.Close() - }() - defer close(backConnCloseCh) - - conn, brw, err := hj.Hijack() - if err != nil { - httputil.ErrorHandler(rw, req, fmt.Errorf("hijack failed on protocol switch: %w", err)) - return - } - defer conn.Close() - - for k, values := range rw.Header() { - for _, v := range values { - res.Header.Add(k, v) + hj, ok := rw.(http.Hijacker) + if !ok { + httputil.ErrorHandlerWithContext(ctx, rw, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)) + backConn.Close() + return } - } + backConnCloseCh := make(chan bool) + go func() { + // Ensure that the cancellation of a request closes the backend. + // See issue https://golang.org/issue/35559. + select { + case <-ctx.Done(): + case <-backConnCloseCh: + } + _ = backConn.Close() + }() + defer close(backConnCloseCh) - if err := res.Header.Write(brw.Writer); err != nil { - httputil.ErrorHandler(rw, req, fmt.Errorf("response write: %w", err)) - return - } + conn, brw, err := hj.Hijack() + if err != nil { + httputil.ErrorHandlerWithContext(ctx, rw, fmt.Errorf("hijack failed on protocol switch: %w", err)) + return + } + defer conn.Close() - if err := brw.Flush(); err != nil { - httputil.ErrorHandler(rw, req, fmt.Errorf("response flush: %w", err)) - return - } + for k, values := range rw.Header() { + for _, v := range values { + res.Header.Add(k, v) + } + } - errc := make(chan error, 1) - spc := switchProtocolCopier{user: conn, backend: backConn} - go spc.copyToBackend(errc) - go spc.copyFromBackend(errc) - <-errc + if err := res.Header.Write(brw.Writer); err != nil { + httputil.ErrorHandlerWithContext(ctx, rw, fmt.Errorf("response write: %w", err)) + return + } + + if err := brw.Flush(); err != nil { + httputil.ErrorHandlerWithContext(ctx, rw, fmt.Errorf("response flush: %w", err)) + return + } + + errCh := make(chan error, 1) + spc := switchProtocolCopier{user: conn, backend: backConn} + go spc.copyToBackend(errCh) + go spc.copyFromBackend(errCh) + <-errCh + } } func upgradeType(h http.Header) string { diff --git a/pkg/proxy/httputil/proxy.go b/pkg/proxy/httputil/proxy.go index 8ed35c23a..78c09f9a4 100644 --- a/pkg/proxy/httputil/proxy.go +++ b/pkg/proxy/httputil/proxy.go @@ -102,9 +102,14 @@ func isWebSocketUpgrade(req *http.Request) bool { // ErrorHandler is the http.Handler called when something goes wrong when forwarding the request. func ErrorHandler(w http.ResponseWriter, req *http.Request, err error) { + ErrorHandlerWithContext(req.Context(), w, err) +} + +// ErrorHandlerWithContext is the http.Handler called when something goes wrong when forwarding the request. +func ErrorHandlerWithContext(ctx context.Context, w http.ResponseWriter, err error) { statusCode := ComputeStatusCode(err) - logger := log.Ctx(req.Context()) + logger := log.Ctx(ctx) logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode)) w.WriteHeader(statusCode) From 27948493aa047a5fdc2eb59c438ce3bc37cb756c Mon Sep 17 00:00:00 2001 From: Anton Bartsits <8313309+tonybart1337@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:44:04 +0200 Subject: [PATCH 13/18] Panic on aborted requests to properly close the connection --- pkg/middlewares/accesslog/logger_test.go | 9 ++- pkg/middlewares/recovery/recovery.go | 93 +++++++++++++++++++++-- pkg/middlewares/recovery/recovery_test.go | 57 +++++++++++--- 3 files changed, 143 insertions(+), 16 deletions(-) diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index 01433c5f6..dc48c3593 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -23,7 +23,6 @@ import ( "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/middlewares/recovery" "github.com/traefik/traefik/v2/pkg/types" ) @@ -948,8 +947,14 @@ func doLoggingWithAbortedStream(t *testing.T, config *types.AccessLog) { req = req.WithContext(reqContext) chain := alice.New() + chain = chain.Append(func(next http.Handler) (http.Handler, error) { - return recovery.New(context.Background(), next) + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + defer func() { + _ = recover() // ignore the stream backend panic to avoid the test to fail. + }() + next.ServeHTTP(rw, req) + }), nil }) chain = chain.Append(capture.Wrap) chain = chain.Append(WrapHandler(logger)) diff --git a/pkg/middlewares/recovery/recovery.go b/pkg/middlewares/recovery/recovery.go index 753a5801b..2415c3ea3 100644 --- a/pkg/middlewares/recovery/recovery.go +++ b/pkg/middlewares/recovery/recovery.go @@ -1,7 +1,10 @@ package recovery import ( + "bufio" "context" + "fmt" + "net" "net/http" "runtime" @@ -28,12 +31,16 @@ func New(ctx context.Context, next http.Handler) (http.Handler, error) { } func (re *recovery) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - defer recoverFunc(rw, req) - re.next.ServeHTTP(rw, req) + recoveryRW := newRecoveryResponseWriter(rw) + defer recoverFunc(recoveryRW, req) + + re.next.ServeHTTP(recoveryRW, req) } -func recoverFunc(rw http.ResponseWriter, r *http.Request) { +func recoverFunc(rw recoveryResponseWriter, r *http.Request) { if err := recover(); err != nil { + defer rw.finalizeResponse() + logger := log.FromContext(middlewares.GetLoggerCtx(r.Context(), middlewareName, typeName)) if !shouldLogPanic(err) { logger.Debugf("Request has been aborted [%s - %s]: %v", r.RemoteAddr, r.URL, err) @@ -45,8 +52,6 @@ func recoverFunc(rw http.ResponseWriter, r *http.Request) { buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] logger.Errorf("Stack: %s", buf) - - http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } } @@ -56,3 +61,81 @@ func shouldLogPanic(panicValue interface{}) bool { //nolint:errorlint // false-positive because panicValue is an interface. return panicValue != nil && panicValue != http.ErrAbortHandler } + +type recoveryResponseWriter interface { + http.ResponseWriter + + finalizeResponse() +} + +func newRecoveryResponseWriter(rw http.ResponseWriter) recoveryResponseWriter { + wrapper := &responseWriterWrapper{rw: rw} + if _, ok := rw.(http.CloseNotifier); !ok { + return wrapper + } + + return &responseWriterWrapperWithCloseNotify{wrapper} +} + +type responseWriterWrapper struct { + rw http.ResponseWriter + headersSent bool +} + +func (r *responseWriterWrapper) Header() http.Header { + return r.rw.Header() +} + +func (r *responseWriterWrapper) Write(bytes []byte) (int, error) { + r.headersSent = true + return r.rw.Write(bytes) +} + +func (r *responseWriterWrapper) WriteHeader(code int) { + if r.headersSent { + return + } + + // Handling informational headers. + if code >= 100 && code <= 199 { + r.rw.WriteHeader(code) + return + } + + r.headersSent = true + r.rw.WriteHeader(code) +} + +func (r *responseWriterWrapper) Flush() { + if f, ok := r.rw.(http.Flusher); ok { + f.Flush() + } +} + +func (r *responseWriterWrapper) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if h, ok := r.rw.(http.Hijacker); ok { + return h.Hijack() + } + + return nil, nil, fmt.Errorf("not a hijacker: %T", r.rw) +} + +func (r *responseWriterWrapper) finalizeResponse() { + // If headers have been sent this is not possible to respond with an HTTP error, + // and we let the server abort the response silently thanks to the http.ErrAbortHandler sentinel panic value. + if r.headersSent { + panic(http.ErrAbortHandler) + } + + // The response has not yet started to be written, + // we can safely return a fresh new error response. + http.Error(r.rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) +} + +type responseWriterWrapperWithCloseNotify struct { + *responseWriterWrapper +} + +func (r *responseWriterWrapperWithCloseNotify) CloseNotify() <-chan bool { + return r.rw.(http.CloseNotifier).CloseNotify() +} diff --git a/pkg/middlewares/recovery/recovery_test.go b/pkg/middlewares/recovery/recovery_test.go index 570717ebc..1929f0b54 100644 --- a/pkg/middlewares/recovery/recovery_test.go +++ b/pkg/middlewares/recovery/recovery_test.go @@ -2,6 +2,8 @@ package recovery import ( "context" + "errors" + "io" "net/http" "net/http/httptest" "testing" @@ -11,17 +13,54 @@ import ( ) func TestRecoverHandler(t *testing.T) { - fn := func(w http.ResponseWriter, r *http.Request) { - panic("I love panicking!") + tests := []struct { + desc string + panicErr error + headersSent bool + }{ + { + desc: "headers sent and custom panic error", + panicErr: errors.New("foo"), + headersSent: true, + }, + { + desc: "headers sent and error abort handler", + panicErr: http.ErrAbortHandler, + headersSent: true, + }, + { + desc: "custom panic error", + panicErr: errors.New("foo"), + }, + { + desc: "error abort handler", + panicErr: http.ErrAbortHandler, + }, } - recovery, err := New(context.Background(), http.HandlerFunc(fn)) - require.NoError(t, err) + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + t.Parallel() - server := httptest.NewServer(recovery) - defer server.Close() + fn := func(rw http.ResponseWriter, req *http.Request) { + if test.headersSent { + rw.WriteHeader(http.StatusTeapot) + } + panic(test.panicErr) + } + recovery, err := New(context.Background(), http.HandlerFunc(fn)) + require.NoError(t, err) - resp, err := http.Get(server.URL) - require.NoError(t, err) + server := httptest.NewServer(recovery) + t.Cleanup(server.Close) - assert.Equal(t, http.StatusInternalServerError, resp.StatusCode) + res, err := http.Get(server.URL) + if test.headersSent { + require.Nil(t, res) + assert.ErrorIs(t, err, io.EOF) + } else { + require.NoError(t, err) + assert.Equal(t, http.StatusInternalServerError, res.StatusCode) + } + }) + } } From 0dc36379cf6cfe613ec820e58dfde8a28b231210 Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 28 Oct 2024 10:08:05 +0100 Subject: [PATCH 14/18] Ensuring Gateway API reflected Traefik resource name unicity Co-authored-by: Kevin Pollet --- integration/testdata/rawdata-gateway.json | 172 ++-- pkg/provider/kubernetes/gateway/grpcroute.go | 6 +- pkg/provider/kubernetes/gateway/httproute.go | 4 +- .../kubernetes/gateway/kubernetes_test.go | 908 +++++++++--------- pkg/provider/kubernetes/gateway/tcproute.go | 2 +- pkg/provider/kubernetes/gateway/tlsroute.go | 2 +- 6 files changed, 547 insertions(+), 547 deletions(-) diff --git a/integration/testdata/rawdata-gateway.json b/integration/testdata/rawdata-gateway.json index 15ee8b6ce..6ed949440 100644 --- a/integration/testdata/rawdata-gateway.json +++ b/integration/testdata/rawdata-gateway.json @@ -30,11 +30,11 @@ "traefik" ] }, - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06@kubernetesgateway": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06@kubernetesgateway": { "entryPoints": [ "web" ], - "service": "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + "service": "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", "ruleSyntax": "v3", "priority": 100008, @@ -43,11 +43,11 @@ "web" ] }, - "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway": { + "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway": { "entryPoints": [ "websecure" ], - "service": "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", + "service": "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", "ruleSyntax": "v3", "priority": 100008, @@ -96,42 +96,14 @@ "dashboard@internal" ] }, - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { - "weighted": { - "services": [ - { - "name": "default-whoami-80", - "weight": 1 - } - ] - }, - "status": "enabled", - "usedBy": [ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06@kubernetesgateway" - ] - }, - "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { - "weighted": { - "services": [ - { - "name": "default-whoami-80", - "weight": 1 - } - ] - }, - "status": "enabled", - "usedBy": [ - "default-http-app-1-my-https-gateway-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway" - ] - }, - "default-whoami-80@kubernetesgateway": { + "default-whoami-http-80@kubernetesgateway": { "loadBalancer": { "servers": [ { - "url": "http://10.42.0.3:80" + "url": "http://10.42.0.4:80" }, { - "url": "http://10.42.0.5:80" + "url": "http://10.42.0.6:80" } ], "passHostHeader": true, @@ -141,20 +113,48 @@ }, "status": "enabled", "serverStatus": { - "http://10.42.0.3:80": "UP", - "http://10.42.0.5:80": "UP" + "http://10.42.0.4:80": "UP", + "http://10.42.0.6:80": "UP" } }, + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { + "weighted": { + "services": [ + { + "name": "default-whoami-http-80", + "weight": 1 + } + ] + }, + "status": "enabled", + "usedBy": [ + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06@kubernetesgateway" + ] + }, + "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": { + "weighted": { + "services": [ + { + "name": "default-whoami-http-80", + "weight": 1 + } + ] + }, + "status": "enabled", + "usedBy": [ + "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway" + ] + }, "noop@internal": { "status": "enabled" } }, "tcpRouters": { - "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footcp" ], - "service": "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb-wrr", + "service": "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-footcp-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`*`)", "ruleSyntax": "v3", "priority": -1, @@ -163,11 +163,11 @@ "footcp" ] }, - "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footlsterminate" ], - "service": "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb-wrr", + "service": "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-footlsterminate-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`*`)", "ruleSyntax": "v3", "priority": -1, @@ -179,11 +179,11 @@ "footlsterminate" ] }, - "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway": { "entryPoints": [ "footlspassthrough" ], - "service": "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb-wrr", + "service": "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-footlspassthrough-0-e3b0c44298fc1c149afb-wrr", "rule": "HostSNI(`foo.bar`)", "ruleSyntax": "v3", "priority": 18, @@ -197,48 +197,6 @@ } }, "tcpServices": { - "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { - "weighted": { - "services": [ - { - "name": "default-whoamitcp-8080", - "weight": 1 - } - ] - }, - "status": "enabled", - "usedBy": [ - "default-tcp-app-1-my-tcp-gateway-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway" - ] - }, - "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { - "weighted": { - "services": [ - { - "name": "default-whoamitcp-8080", - "weight": 1 - } - ] - }, - "status": "enabled", - "usedBy": [ - "default-tcp-app-1-my-tls-gateway-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway" - ] - }, - "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { - "weighted": { - "services": [ - { - "name": "default-whoamitcp-8080", - "weight": 1 - } - ] - }, - "status": "enabled", - "usedBy": [ - "default-tls-app-1-my-tls-gateway-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway" - ] - }, "default-whoamitcp-8080@kubernetesgateway": { "loadBalancer": { "servers": [ @@ -246,11 +204,53 @@ "address": "10.42.0.2:8080" }, { - "address": "10.42.0.6:8080" + "address": "10.42.0.3:8080" } ] }, "status": "enabled" + }, + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-footcp-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { + "weighted": { + "services": [ + { + "name": "default-whoamitcp-8080", + "weight": 1 + } + ] + }, + "status": "enabled", + "usedBy": [ + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-footcp-0-e3b0c44298fc1c149afb@kubernetesgateway" + ] + }, + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-footlsterminate-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { + "weighted": { + "services": [ + { + "name": "default-whoamitcp-8080", + "weight": 1 + } + ] + }, + "status": "enabled", + "usedBy": [ + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-footlsterminate-0-e3b0c44298fc1c149afb@kubernetesgateway" + ] + }, + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-footlspassthrough-0-e3b0c44298fc1c149afb-wrr@kubernetesgateway": { + "weighted": { + "services": [ + { + "name": "default-whoamitcp-8080", + "weight": 1 + } + ] + }, + "status": "enabled", + "usedBy": [ + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-footlspassthrough-0-e3b0c44298fc1c149afb@kubernetesgateway" + ] } } } \ No newline at end of file diff --git a/pkg/provider/kubernetes/gateway/grpcroute.go b/pkg/provider/kubernetes/gateway/grpcroute.go index cb61428ec..5529b9c07 100644 --- a/pkg/provider/kubernetes/gateway/grpcroute.go +++ b/pkg/provider/kubernetes/gateway/grpcroute.go @@ -120,7 +120,7 @@ func (p *Provider) loadGRPCRoute(ctx context.Context, listener gatewayListener, for ri, routeRule := range route.Spec.Rules { // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-gw-%s-%s-ep-%s-%d", strings.ToLower(kindGRPCRoute), route.Namespace, route.Name, listener.GWNamespace, listener.GWName, listener.EPName, ri)) matches := routeRule.Matches if len(matches) == 0 { @@ -166,7 +166,7 @@ func (p *Provider) loadGRPCRoute(ctx context.Context, listener gatewayListener, default: var serviceCondition *metav1.Condition - router.Service, serviceCondition = p.loadGRPCService(conf, routeKey, routeRule, route) + router.Service, serviceCondition = p.loadGRPCService(conf, routerName, routeRule, route) if serviceCondition != nil { condition = *serviceCondition } @@ -267,7 +267,7 @@ func (p *Provider) loadGRPCBackendRef(route *gatev1.GRPCRoute, backendRef gatev1 } portStr := strconv.FormatInt(int64(port), 10) - serviceName = provider.Normalize(serviceName + "-" + portStr) + serviceName = provider.Normalize(serviceName + "-" + portStr + "-grpc") lb, errCondition := p.loadGRPCServers(namespace, route, backendRef) if errCondition != nil { diff --git a/pkg/provider/kubernetes/gateway/httproute.go b/pkg/provider/kubernetes/gateway/httproute.go index 2d6314024..a58d53560 100644 --- a/pkg/provider/kubernetes/gateway/httproute.go +++ b/pkg/provider/kubernetes/gateway/httproute.go @@ -123,7 +123,7 @@ func (p *Provider) loadHTTPRoute(ctx context.Context, listener gatewayListener, for ri, routeRule := range route.Spec.Rules { // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-gw-%s-%s-ep-%s-%d", strings.ToLower(kindHTTPRoute), route.Namespace, route.Name, listener.GWNamespace, listener.GWName, listener.EPName, ri)) for _, match := range routeRule.Matches { rule, priority := buildMatchRule(hostnames, match) @@ -224,7 +224,7 @@ func (p *Provider) loadService(ctx context.Context, listener gatewayListener, co namespace = string(*backendRef.Namespace) } - serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name)) + serviceName := provider.Normalize(namespace + "-" + string(backendRef.Name) + "-http") if err := p.isReferenceGranted(kindHTTPRoute, route.Namespace, group, string(kind), string(backendRef.Name), namespace); err != nil { return serviceName, &metav1.Condition{ diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index 053d04b1f..9e884f30d 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -246,9 +246,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -256,11 +256,11 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-9000", + Name: "default-whoami-http-9000", Weight: ptr.To(1), Status: ptr.To(500), }, @@ -615,9 +615,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -625,17 +625,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -676,7 +676,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, Service: "api@internal", Rule: "Host(`foo.com`) && Path(`/bar`)", @@ -710,9 +710,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -721,17 +721,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -781,9 +781,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-66e726cd8903b49727ae": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-66e726cd8903b49727ae-wrr", Rule: "(Host(`foo.com`) || Host(`bar.com`)) && PathPrefix(`/`)", Priority: 9, RuleSyntax: "v3", @@ -791,17 +791,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-66e726cd8903b49727ae-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-66e726cd8903b49727ae-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -842,9 +842,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-baa117c0219e3878749f": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-baa117c0219e3878749f-wrr", Rule: "(Host(`foo.com`) || HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.com$`)) && PathPrefix(`/`)", Priority: 11, RuleSyntax: "v3", @@ -852,17 +852,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-baa117c0219e3878749f-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-baa117c0219e3878749f-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -903,9 +903,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-45eba2eaf40ac792e036": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-45eba2eaf40ac792e036-wrr", Rule: "(Host(`foo.com`) || HostRegexp(`^[a-z0-9-\\.]+\\.foo\\.com$`)) && PathPrefix(`/`)", Priority: 11, RuleSyntax: "v3", @@ -913,17 +913,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-45eba2eaf40ac792e036-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-45eba2eaf40ac792e036-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -964,44 +964,44 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100009, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", }, - "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d737b4933fa88e68ab8a": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bir`)", Priority: 100008, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d737b4933fa88e68ab8a-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-web-1-d737b4933fa88e68ab8a-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-d737b4933fa88e68ab8a-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami2-8080", + Name: "default-whoami2-http-8080", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1017,7 +1017,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-whoami2-8080": { + "default-whoami2-http-8080": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1058,31 +1058,31 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, { - Name: "default-whoami2-8080", + Name: "default-whoami2-http-8080", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1098,7 +1098,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "default-whoami2-8080": { + "default-whoami2-http-8080": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1144,16 +1144,16 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", }, - "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1162,27 +1162,27 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-http-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-http-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-https-websecure-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-https-ep-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1237,16 +1237,16 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", }, - "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1255,27 +1255,27 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-websecure-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1325,61 +1325,61 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-6cf37fa71907768d925c": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-6cf37fa71907768d925c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && (Path(`/bar`) || PathPrefix(`/bar/`)) && Header(`my-header`,`foo`) && Header(`my-header2`,`bar`)", Priority: 10610, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-6cf37fa71907768d925c-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-6cf37fa71907768d925c-wrr", }, - "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-d23f7039bc8036fb918c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && PathRegexp(`^/buzz/[0-9]+$`)", Priority: 11408, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-d23f7039bc8036fb918c-wrr", }, - "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-aaba0f24fd26e1ca2276": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && Path(`/bar`) && Header(`my-header`,`bar`)", Priority: 100109, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-aaba0f24fd26e1ca2276-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-6cf37fa71907768d925c-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-6cf37fa71907768d925c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-web-2-d23f7039bc8036fb918c-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-2-d23f7039bc8036fb918c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-web-1-aaba0f24fd26e1ca2276-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-1-aaba0f24fd26e1ca2276-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: func(i int) *int { return &i }(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1420,27 +1420,27 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-74ad70a7cf090becdd3c": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Method(`GET`)", Priority: 11408, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-74ad70a7cf090becdd3c-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-74ad70a7cf090becdd3c-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-74ad70a7cf090becdd3c-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1481,27 +1481,27 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-bb7b03c9610e982fd627": { EntryPoints: []string{"web"}, Rule: "Host(`foo.com`) && (Path(`/foo`) || PathPrefix(`/foo/`)) && Query(`foo`,`bar`) && QueryRegexp(`baz`,`buz`)", Priority: 10428, RuleSyntax: "v3", - Service: "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-bb7b03c9610e982fd627-wrr", }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-bb7b03c9610e982fd627-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-bb7b03c9610e982fd627-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1542,9 +1542,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb-wrr", Rule: "Host(`foo.com`) && Path(`/foo`)", Priority: 100008, RuleSyntax: "v3", @@ -1552,17 +1552,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1603,16 +1603,16 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb-wrr", Rule: "Host(`foo.com`) && Path(`/foo`)", Priority: 100008, RuleSyntax: "v3", }, - "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597-wrr", Rule: "Host(`bar.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1620,27 +1620,27 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-efde1997778109a1f6eb-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-efde1997778109a1f6eb-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1656,7 +1656,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, }, - "bar-whoami-bar-80": { + "bar-whoami-bar-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1697,9 +1697,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597-wrr", Rule: "Host(`bar.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -1707,17 +1707,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "bar-http-app-bar-my-gateway-web-0-66f5c78d03d948e36597-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-66f5c78d03d948e36597-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, }, }, - "bar-whoami-bar-80": { + "bar-whoami-bar-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1758,17 +1758,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", - Middlewares: []string{"default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestheadermodifier-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestheadermodifier-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestheadermodifier-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestheadermodifier-0": { RequestHeaderModifier: &dynamic.HeaderModifier{ Set: map[string]string{"X-Foo": "Bar"}, Add: map[string]string{"X-Bar": "Foo"}, @@ -1777,17 +1777,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1828,17 +1828,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", - Middlewares: []string{"default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-responseheadermodifier-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-responseheadermodifier-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-responseheadermodifier-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-responseheadermodifier-0": { ResponseHeaderModifier: &dynamic.HeaderModifier{ Set: map[string]string{"X-Foo": "Bar"}, Add: map[string]string{"X-Bar": "Foo"}, @@ -1847,17 +1847,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -1898,17 +1898,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", - Middlewares: []string{"default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestredirect-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestredirect-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestredirect-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestredirect-0": { RequestRedirect: &dynamic.RequestRedirect{ Scheme: ptr.To("https"), Port: ptr.To(""), @@ -1917,7 +1917,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{}, }, }, @@ -1945,17 +1945,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr", Rule: "Host(`example.org`) && PathPrefix(`/`)", Priority: 13, RuleSyntax: "v3", - Middlewares: []string{"default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestredirect-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestredirect-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-requestredirect-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-requestredirect-0": { RequestRedirect: &dynamic.RequestRedirect{ Hostname: ptr.To("example.com"), Port: ptr.To("443"), @@ -1964,7 +1964,7 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-364ce6ec04c3d49b19c4-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-364ce6ec04c3d49b19c4-wrr": { Weighted: &dynamic.WeightedRoundRobin{}, }, }, @@ -1992,34 +1992,34 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, - Middlewares: []string{"default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { URLRewrite: &dynamic.URLRewrite{ Path: ptr.To("/bar"), }, }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: func(i int) *int { return &i }(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2060,34 +2060,34 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, - Middlewares: []string{"default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { URLRewrite: &dynamic.URLRewrite{ Hostname: ptr.To("www.foo.bar"), }, }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: func(i int) *int { return &i }(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2128,17 +2128,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr", Rule: "Host(`example.com`) && (Path(`/foo`) || PathPrefix(`/foo/`))", RuleSyntax: "v3", Priority: 10412, - Middlewares: []string{"default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, + Middlewares: []string{"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0"}, }, }, Middlewares: map[string]*dynamic.Middleware{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-urlrewrite-0": { URLRewrite: &dynamic.URLRewrite{ Hostname: ptr.To("www.foo.bar"), Path: ptr.To("/xyz"), @@ -2147,17 +2147,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-7f90cf546b15efadf2f8-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-7f90cf546b15efadf2f8-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: func(i int) *int { return &i }(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2198,9 +2198,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2208,17 +2208,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2260,9 +2260,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2270,17 +2270,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2294,12 +2294,12 @@ func TestLoadHTTPRoutes(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(100 * time.Millisecond), }, - ServersTransport: "default-whoami-80", + ServersTransport: "default-whoami-http-80", }, }, }, ServersTransports: map[string]*dynamic.ServersTransport{ - "default-whoami-80": { + "default-whoami-http-80": { ServerName: "whoami", RootCAs: []types.FileOrContent{ "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=", @@ -2330,9 +2330,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2340,17 +2340,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2364,12 +2364,12 @@ func TestLoadHTTPRoutes(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(100 * time.Millisecond), }, - ServersTransport: "default-whoami-80", + ServersTransport: "default-whoami-http-80", }, }, }, ServersTransports: map[string]*dynamic.ServersTransport{ - "default-whoami-80": { + "default-whoami-http-80": { ServerName: "whoami", }, }, @@ -2397,9 +2397,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2407,17 +2407,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2455,9 +2455,9 @@ func TestLoadHTTPRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2465,17 +2465,17 @@ func TestLoadHTTPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-native-80", + Name: "default-whoami-native-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-native-80": { + "default-whoami-native-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2565,9 +2565,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2575,7 +2575,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2615,9 +2615,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2625,7 +2625,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2667,9 +2667,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2677,11 +2677,11 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami", + Name: "default-whoami-http", Weight: ptr.To(1), Status: ptr.To(500), }, @@ -2718,9 +2718,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2728,11 +2728,11 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami", + Name: "default-whoami-http", Weight: ptr.To(1), Status: ptr.To(500), }, @@ -2770,9 +2770,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2780,7 +2780,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -2788,13 +2788,13 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { Weight: ptr.To(1), }, { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2841,9 +2841,9 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-multi-protocols-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-multi-protocols-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2851,25 +2851,25 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-multi-protocols-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-multi-protocols-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-h2c-80", + Name: "default-whoami-h2c-http-80", Weight: ptr.To(1), }, { - Name: "default-whoami-ws-80", + Name: "default-whoami-ws-http-80", Weight: ptr.To(1), }, { - Name: "default-whoami-wss-80", + Name: "default-whoami-wss-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-h2c-80": { + "default-whoami-h2c-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2882,7 +2882,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, }, }, - "default-whoami-ws-80": { + "default-whoami-ws-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2895,7 +2895,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) { }, }, }, - "default-whoami-wss-80": { + "default-whoami-wss-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -2985,9 +2985,9 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -2999,17 +2999,17 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -3054,9 +3054,9 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -3071,17 +3071,17 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { "default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, }, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -3121,9 +3121,9 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-err-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-err-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -3131,7 +3131,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-err-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-err-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -3171,9 +3171,9 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-err-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-err-wrr", Rule: "Host(`foo.com`) && Path(`/bar`)", Priority: 100008, RuleSyntax: "v3", @@ -3181,7 +3181,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-1c0cf64bde37d9d0df06-err-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-err-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -3269,9 +3269,9 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00": { EntryPoints: []string{"web"}, - Service: "default-grpc-app-1-my-gateway-web-0-wrr", + Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-wrr", Rule: "Host(`foo.com`) && PathPrefix(`/`)", Priority: 22, RuleSyntax: "v3", @@ -3283,17 +3283,17 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-grpc-app-1-my-gateway-web-0-wrr": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-80-grpc", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-80-grpc": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -3338,9 +3338,9 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00": { EntryPoints: []string{"web"}, - Service: "default-grpc-app-1-my-gateway-web-0-wrr", + Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-wrr", Rule: "Host(`foo.com`) && PathPrefix(`/`)", Priority: 22, RuleSyntax: "v3", @@ -3355,17 +3355,17 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { "default-my-second-middleware": {Headers: &dynamic.Headers{CustomRequestHeaders: map[string]string{"Test-Header": "Test"}}}, }, Services: map[string]*dynamic.Service{ - "default-grpc-app-1-my-gateway-web-0-wrr": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-80-grpc", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-80-grpc": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -3405,9 +3405,9 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00": { EntryPoints: []string{"web"}, - Service: "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr", + Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-err-wrr", Rule: "Host(`foo.com`) && PathPrefix(`/`)", Priority: 22, RuleSyntax: "v3", @@ -3415,7 +3415,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-err-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -3458,9 +3458,9 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00": { EntryPoints: []string{"web"}, - Service: "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr", + Service: "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-err-wrr", Rule: "Host(`foo.com`) && PathPrefix(`/`)", Priority: 22, RuleSyntax: "v3", @@ -3468,7 +3468,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-grpc-app-1-my-gateway-web-0-74471866db6e94e08d00-err-wrr": { + "grpcroute-default-grpc-app-1-gw-default-my-gateway-ep-web-0-74471866db6e94e08d00-err-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { @@ -3703,24 +3703,24 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb": { + "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"TCP"}, Rule: "HostSNI(`*`)", RuleSyntax: "v3", - Service: "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-wrr", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ - Name: "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb", + Name: "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-err-lb", Weight: ptr.To(1), }}, }, }, - "default-TCP-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb": { + "tcproute-default-TCP-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-err-lb": { LoadBalancer: &dynamic.TCPServersLoadBalancer{ Servers: []dynamic.TCPServer{}, }, @@ -3750,16 +3750,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3808,22 +3808,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-2"}, - Service: "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3833,7 +3833,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "default-tcp-app-2-my-tcp-gateway-tcp-2-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-2-gw-default-my-tcp-gateway-ep-tcp-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3894,22 +3894,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-my-tcp-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3919,7 +3919,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "default-tcp-app-my-tcp-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-gw-default-my-tcp-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3978,16 +3978,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4038,9 +4038,9 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -4048,7 +4048,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ Name: "default-whoamitcp-9000", @@ -4102,16 +4102,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4158,22 +4158,22 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4183,7 +4183,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4242,16 +4242,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "bar-tcp-app-bar-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4299,16 +4299,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4352,16 +4352,16 @@ func TestLoadTCPRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tcp-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4579,25 +4579,25 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"TCP"}, Rule: "HostSNI(`*`)", RuleSyntax: "v3", - Service: "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-wrr", TLS: &dynamic.RouterTCPTLSConfig{}, }, }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ - Name: "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb", + Name: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-err-lb", Weight: ptr.To(1), }}, }, }, - "default-tls-app-1-my-gateway-TCP-0-e3b0c44298fc1c149afb-err-lb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-TCP-0-e3b0c44298fc1c149afb-err-lb": { LoadBalancer: &dynamic.TCPServersLoadBalancer{ Servers: []dynamic.TCPServer{}, }, @@ -4670,9 +4670,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -4680,7 +4680,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4736,9 +4736,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4748,7 +4748,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4795,9 +4795,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4807,7 +4807,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4855,16 +4855,16 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -4874,7 +4874,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-tls-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4884,7 +4884,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -4952,9 +4952,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -4962,7 +4962,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5022,9 +5022,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5034,7 +5034,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5081,9 +5081,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5093,7 +5093,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5140,9 +5140,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5152,7 +5152,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5199,9 +5199,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5211,7 +5211,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5258,9 +5258,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.default`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5270,7 +5270,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5317,18 +5317,18 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.default`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, }, - "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.bar`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5338,7 +5338,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5348,7 +5348,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5407,9 +5407,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.bar`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5419,7 +5419,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "bar-tls-app-bar-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5466,18 +5466,18 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, }, - "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp-1"}, - Service: "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5487,7 +5487,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-my-gateway-tcp-1-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5497,7 +5497,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, - "default-tls-app-my-gateway-tcp-1-1-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-gw-default-my-gateway-ep-tcp-1-1-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5557,9 +5557,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5569,7 +5569,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5613,9 +5613,9 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5625,7 +5625,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-tls-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5822,22 +5822,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -5847,7 +5847,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5857,7 +5857,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-1-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5867,7 +5867,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-1-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-1-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -5894,16 +5894,16 @@ func TestLoadMixedRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -5912,27 +5912,27 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-1-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6009,22 +6009,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -6034,7 +6034,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6044,7 +6044,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6054,7 +6054,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6081,16 +6081,16 @@ func TestLoadMixedRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -6099,27 +6099,27 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6168,37 +6168,37 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, }, - "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -6206,7 +6206,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6216,7 +6216,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6226,7 +6226,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tls-app-default-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-default-tls-app-default-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6260,7 +6260,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6270,7 +6270,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6285,31 +6285,31 @@ func TestLoadMixedRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", TLS: &dynamic.RouterTLSConfig{}, }, - "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -6318,27 +6318,27 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6354,7 +6354,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-whoami-bar-80": { + "bar-whoami-bar-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6370,21 +6370,21 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, }, }, - "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, @@ -6423,22 +6423,22 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-1"}, - Service: "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, }, - "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls-2"}, - Service: "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr", + Service: "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`pass.tls.foo.example.com`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{ @@ -6460,7 +6460,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6470,7 +6470,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tcp-app-bar-my-gateway-tls-1-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-bar-tcp-app-bar-gw-default-my-gateway-ep-tls-1-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6480,7 +6480,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-tls-app-bar-my-gateway-tls-2-0-e3b0c44298fc1c149afb-wrr": { + "tlsroute-bar-tls-app-bar-gw-default-my-gateway-ep-tls-2-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6495,16 +6495,16 @@ func TestLoadMixedRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -6513,7 +6513,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "bar-whoami-bar-80": { + "bar-whoami-bar-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6529,21 +6529,21 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "bar-http-app-bar-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, }, }, - "bar-http-app-bar-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-bar-http-app-bar-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "bar-whoami-bar-80", + Name: "bar-whoami-bar-http-80", Weight: ptr.To(1), }, }, @@ -6581,15 +6581,15 @@ func TestLoadMixedRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tcp"}, - Service: "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", }, - "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -6597,7 +6597,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-default-my-gateway-tcp-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tcp-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6607,7 +6607,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, - "default-tcp-app-default-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-default-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -6634,16 +6634,16 @@ func TestLoadMixedRoutes(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd": { EntryPoints: []string{"web"}, - Service: "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd": { EntryPoints: []string{"websecure"}, - Service: "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr", + Service: "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr", Rule: "PathPrefix(`/`)", Priority: 2, RuleSyntax: "v3", @@ -6652,27 +6652,27 @@ func TestLoadMixedRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-default-my-gateway-web-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-web-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-http-app-default-my-gateway-websecure-0-a431b128267aabc954fd-wrr": { + "httproute-default-http-app-default-gw-default-my-gateway-ep-websecure-0-a431b128267aabc954fd-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-80", + Name: "default-whoami-http-80", Weight: ptr.To(1), }, }, }, }, - "default-whoami-80": { + "default-whoami-http-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ { @@ -6864,9 +6864,9 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb": { EntryPoints: []string{"tls"}, - Service: "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr", + Service: "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr", Rule: "HostSNI(`*`)", RuleSyntax: "v3", TLS: &dynamic.RouterTCPTLSConfig{}, @@ -6874,7 +6874,7 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tcp-app-1-my-gateway-tls-0-e3b0c44298fc1c149afb-wrr": { + "tcproute-default-tcp-app-1-gw-default-my-gateway-ep-tls-0-e3b0c44298fc1c149afb-wrr": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{{ Name: "default-whoamitcp-9000", @@ -7012,21 +7012,21 @@ func TestLoadRoutesWithReferenceGrants(t *testing.T) { }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ - "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-d40286ed9f4652ca2108": { EntryPoints: []string{"http"}, Rule: "Host(`foo.example.com`) && PathPrefix(`/`)", - Service: "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108-wrr", + Service: "httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-d40286ed9f4652ca2108-wrr", RuleSyntax: "v3", Priority: 17, }, }, Middlewares: map[string]*dynamic.Middleware{}, Services: map[string]*dynamic.Service{ - "default-http-app-1-my-gateway-http-0-d40286ed9f4652ca2108-wrr": { + "httproute-default-http-app-1-gw-default-my-gateway-ep-http-0-d40286ed9f4652ca2108-wrr": { Weighted: &dynamic.WeightedRoundRobin{ Services: []dynamic.WRRService{ { - Name: "default-whoami-bar-80", + Name: "default-whoami-bar-http-80", Weight: ptr.To(1), Status: ptr.To(500), }, diff --git a/pkg/provider/kubernetes/gateway/tcproute.go b/pkg/provider/kubernetes/gateway/tcproute.go index 0f859b5ae..9e302d001 100644 --- a/pkg/provider/kubernetes/gateway/tcproute.go +++ b/pkg/provider/kubernetes/gateway/tcproute.go @@ -130,7 +130,7 @@ func (p *Provider) loadTCPRoute(listener gatewayListener, route *gatev1alpha2.TC } // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-gw-%s-%s-ep-%s-%d", strings.ToLower(kindTCPRoute), route.Namespace, route.Name, listener.GWNamespace, listener.GWName, listener.EPName, ri)) // Routing criteria should be introduced at some point. routerName := makeRouterName("", routeKey) diff --git a/pkg/provider/kubernetes/gateway/tlsroute.go b/pkg/provider/kubernetes/gateway/tlsroute.go index 42b715de1..8c8e1cb76 100644 --- a/pkg/provider/kubernetes/gateway/tlsroute.go +++ b/pkg/provider/kubernetes/gateway/tlsroute.go @@ -132,7 +132,7 @@ func (p *Provider) loadTLSRoute(listener gatewayListener, route *gatev1alpha2.TL } // Adding the gateway desc and the entryPoint desc prevents overlapping of routers build from the same routes. - routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-%s-%d", route.Namespace, route.Name, listener.GWName, listener.EPName, ri)) + routeKey := provider.Normalize(fmt.Sprintf("%s-%s-%s-gw-%s-%s-ep-%s-%d", strings.ToLower(kindTLSRoute), route.Namespace, route.Name, listener.GWNamespace, listener.GWName, listener.EPName, ri)) // Routing criteria should be introduced at some point. routerName := makeRouterName("", routeKey) From 08fe27ce5f5cf242cd72670b2ecea329412a0ead Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 28 Oct 2024 10:22:04 +0100 Subject: [PATCH 15/18] Prepare release v2.11.13 --- CHANGELOG.md | 9 +++++++++ script/gcg/traefik-bugfix.toml | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79e5d283e..6a010870a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [v2.11.13](https://github.com/traefik/traefik/tree/v2.11.13) (2024-10-28) +[All Commits](https://github.com/traefik/traefik/compare/v2.11.12...v2.11.13) + +**Bug fixes:** +- **[middleware,service]** Panic on aborted requests to properly close the connection ([#11129](https://github.com/traefik/traefik/pull/11129) by [tonybart1337](https://github.com/tonybart1337)) + +**Documentation:** +- Update business callouts ([#11217](https://github.com/traefik/traefik/pull/11217) by [tomatokoolaid](https://github.com/tomatokoolaid)) + ## [v2.11.12](https://github.com/traefik/traefik/tree/v2.11.12) (2024-10-09) [All Commits](https://github.com/traefik/traefik/compare/v2.11.11...v2.11.12) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index dacf38d28..c7581b405 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.11.12 +# example new bugfix v2.11.13 CurrentRef = "v2.11" -PreviousRef = "v2.11.11" +PreviousRef = "v2.11.12" BaseBranch = "v2.11" -FutureCurrentRefName = "v2.11.12" +FutureCurrentRefName = "v2.11.13" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From e90f4a7cb4e2a457ce72b292c2ce383ae71661eb Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 28 Oct 2024 11:34:03 +0100 Subject: [PATCH 16/18] Prepare release v3.1.7 --- CHANGELOG.md | 13 +++++++++++++ script/gcg/traefik-bugfix.toml | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ad7f1f04..f71230ba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## [v3.1.7](https://github.com/traefik/traefik/tree/v3.1.7) (2024-10-28) +[All Commits](https://github.com/traefik/traefik/compare/v3.1.6...v3.1.7) + +**Bug fixes:** +- **[k8s,k8s/gatewayapi]** Preserve HTTPRoute filters order ([#11198](https://github.com/traefik/traefik/pull/11198) by [kevinpollet](https://github.com/kevinpollet)) + +**Documentation:** +- **[k8s,k8s/gatewayapi]** Fix broken links in Kubernetes Gateway provider page ([#11188](https://github.com/traefik/traefik/pull/11188) by [mloiseleur](https://github.com/mloiseleur)) + +**Misc:** +- Merge branch v2.11 into v3.1 ([#11232](https://github.com/traefik/traefik/pull/11232) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v2.11 into v3.1 ([#11218](https://github.com/traefik/traefik/pull/11218) by [kevinpollet](https://github.com/kevinpollet)) + ## [v2.11.13](https://github.com/traefik/traefik/tree/v2.11.13) (2024-10-28) [All Commits](https://github.com/traefik/traefik/compare/v2.11.12...v2.11.13) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 8e06b98e3..90dee22cf 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 v3.1.6 +# example new bugfix v3.1.7 CurrentRef = "v3.1" -PreviousRef = "v3.1.5" +PreviousRef = "v3.1.6" BaseBranch = "v3.1" -FutureCurrentRefName = "v3.1.6" +FutureCurrentRefName = "v3.1.7" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From 25caa72c0972fcb829276ebf5a41ef0263fa4a6f Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 28 Oct 2024 15:46:04 +0100 Subject: [PATCH 17/18] Prepare release v3.2.0 --- .github/PULL_REQUEST_TEMPLATE.md | 4 +- CHANGELOG.md | 57 +++++++++++++++++++++ script/gcg/traefik-final-release-part1.toml | 10 ++-- script/gcg/traefik-final-release-part2.toml | 8 +-- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bc36a9a3c..10570f2bf 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,11 +3,11 @@ PLEASE READ THIS MESSAGE. Documentation fixes or enhancements: - for Traefik v2: use branch v2.11 -- for Traefik v3: use branch v3.1 +- for Traefik v3: use branch v3.2 Bug fixes: - for Traefik v2: use branch v2.11 -- for Traefik v3: use branch v3.1 +- for Traefik v3: use branch v3.2 Enhancements: - for Traefik v2: we only accept bug fixes diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3cfb1d2..e87a30922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,60 @@ +## [v3.2.0](https://github.com/traefik/traefik/tree/v3.2.0) (2024-10-28) +[All Commits](https://github.com/traefik/traefik/compare/v3.2.0-rc1...v3.2.0) + +**Enhancements:** +- **[acme]** Remove same email requirement for certresolvers ([#11019](https://github.com/traefik/traefik/pull/11019) by [Emrio](https://github.com/Emrio)) +- **[acme]** Add support for custom CA certificates by certificate resolver ([#10816](https://github.com/traefik/traefik/pull/10816) by [ldez](https://github.com/ldez)) +- **[acme]** Add 30 day certificatesDuration step ([#10970](https://github.com/traefik/traefik/pull/10970) by [luker983](https://github.com/luker983)) +- **[docker]** Support HTTP BasicAuth for docker and swarm endpoint ([#10776](https://github.com/traefik/traefik/pull/10776) by [985492783](https://github.com/985492783)) +- **[k8s,k8s/gatewayapi]** Add supported features to the Gateway API GatewayClass status ([#11056](https://github.com/traefik/traefik/pull/11056) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Update sigs.k8s.io/gateway-api to v1.2.0-rc1 ([#11124](https://github.com/traefik/traefik/pull/11124) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Add support for backend protocol selection in HTTP and GRPC routes ([#11051](https://github.com/traefik/traefik/pull/11051) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Improve Kubernetes GatewayAPI TCPRoute and TLSRoute support ([#11042](https://github.com/traefik/traefik/pull/11042) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Support HTTPRoute destination port matching ([#11134](https://github.com/traefik/traefik/pull/11134) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s,k8s/gatewayapi]** Bump sigs.k8s.io/gateway-api to v1.2.0-rc2 ([#11131](https://github.com/traefik/traefik/pull/11131) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s,k8s/gatewayapi]** Add support for Gateway API BackendTLSPolicies ([#11009](https://github.com/traefik/traefik/pull/11009) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Support NativeLB option in GatewayAPI provider ([#11147](https://github.com/traefik/traefik/pull/11147) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Support ResponseHeaderModifier filter ([#10987](https://github.com/traefik/traefik/pull/10987) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s,k8s/gatewayapi]** Support GRPC routes ([#10975](https://github.com/traefik/traefik/pull/10975) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s,k8s/gatewayapi]** Bump sigs.k8s.io/gateway-api to v1.2.0 ([#11167](https://github.com/traefik/traefik/pull/11167) by [rtribotte](https://github.com/rtribotte)) +- **[metrics,otel]** Allow setting service.name for OTLP metrics ([#10917](https://github.com/traefik/traefik/pull/10917) by [cmartell-at-ocp](https://github.com/cmartell-at-ocp)) +- **[middleware,accesslogs]** Record trace id and EntryPoint span id into access log ([#10921](https://github.com/traefik/traefik/pull/10921) by [weijiany](https://github.com/weijiany)) +- **[middleware,authentication]** Support LogUserHeader with forwardAuth middleware ([#10833](https://github.com/traefik/traefik/pull/10833) by [GaleHuang](https://github.com/GaleHuang)) +- **[middleware]** Add encodings option to the compression middleware ([#10943](https://github.com/traefik/traefik/pull/10943) by [wollomatic](https://github.com/wollomatic)) +- **[middleware]** Add support for ipv6 subnet in ipStrategy ([#9747](https://github.com/traefik/traefik/pull/9747) by [michal-kralik](https://github.com/michal-kralik)) +- **[nomad]** Support for watching instead of polling Nomad ([#10997](https://github.com/traefik/traefik/pull/10997) by [deverton-godaddy](https://github.com/deverton-godaddy)) +- **[server,performance]** Introduce a fast proxy mode to improve HTTP/1.1 performances with backends ([#11122](https://github.com/traefik/traefik/pull/11122) by [kevinpollet](https://github.com/kevinpollet)) +- **[server]** Configurable max request header size ([#10995](https://github.com/traefik/traefik/pull/10995) by [lucasrod16](https://github.com/lucasrod16)) +- **[service]** Add mirrorBody option to HTTP mirroring ([#11032](https://github.com/traefik/traefik/pull/11032) by [MatteoPaier](https://github.com/MatteoPaier)) +- **[service]** Add an option to preserve server path ([#11193](https://github.com/traefik/traefik/pull/11193) by [mmatur](https://github.com/mmatur)) + +**Bug fixes:** +- **[k8s,k8s/gatewayapi]** Ensuring Gateway API reflected Traefik resource name unicity ([#11222](https://github.com/traefik/traefik/pull/11222) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Preserve GRPCRoute filters order ([#11199](https://github.com/traefik/traefik/pull/11199) by [kevinpollet](https://github.com/kevinpollet)) +- **[k8s,k8s/gatewayapi]** Support http and https appProtocol for Kubernetes Service ([#11176](https://github.com/traefik/traefik/pull/11176) by [WillDaSilva](https://github.com/WillDaSilva)) +- **[k8s,k8s/gatewayapi]** Avoid updating Accepted status for routes matching no Gateways ([#11170](https://github.com/traefik/traefik/pull/11170) by [rtribotte](https://github.com/rtribotte)) +- **[k8s,k8s/gatewayapi]** Do not update gateway status when not selected by a gateway class ([#11169](https://github.com/traefik/traefik/pull/11169) by [kevinpollet](https://github.com/kevinpollet)) +- **[service]** Detect and drop broken conns in the fastproxy pool ([#11212](https://github.com/traefik/traefik/pull/11212) by [kevinpollet](https://github.com/kevinpollet)) + +**Documentation:** +- **[k8s,k8s/gatewayapi]** Document nativeLBByDefault annotation on Kubernetes Gateway provider ([#11209](https://github.com/traefik/traefik/pull/11209) by [mloiseleur](https://github.com/mloiseleur)) +- **[k8s/crd,k8s]** Detail CRD update with v3.2 in the migration guide ([#11164](https://github.com/traefik/traefik/pull/11164) by [mloiseleur](https://github.com/mloiseleur)) +- **[k8s/gatewayapi]** Add missing RBAC in the migration guide ([#11189](https://github.com/traefik/traefik/pull/11189) by [mloiseleur](https://github.com/mloiseleur)) +- **[k8s]** Fix instructions for downloading CRDs of Gateway API v1.2 ([#11191](https://github.com/traefik/traefik/pull/11191) by [mloiseleur](https://github.com/mloiseleur)) +- Prepare release v3.2.0-rc2 ([#11182](https://github.com/traefik/traefik/pull/11182) by [kevinpollet](https://github.com/kevinpollet)) +- Prepare Release v3.2.0-rc1 ([#11154](https://github.com/traefik/traefik/pull/11154) by [rtribotte](https://github.com/rtribotte)) + +**Misc:** +- Merge branch v3.1 into v3.2 ([#11219](https://github.com/traefik/traefik/pull/11219) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v3.1 into v3.2 ([#11181](https://github.com/traefik/traefik/pull/11181) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v3.1 into master ([#11153](https://github.com/traefik/traefik/pull/11153) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v3.1 into master ([#11110](https://github.com/traefik/traefik/pull/11110) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v3.1 into master ([#11066](https://github.com/traefik/traefik/pull/11066) by [mmatur](https://github.com/mmatur)) +- Merge branch v3.1 into master ([#11047](https://github.com/traefik/traefik/pull/11047) by [mmatur](https://github.com/mmatur)) +- Merge branch v3.1 into master ([#10980](https://github.com/traefik/traefik/pull/10980) by [kevinpollet](https://github.com/kevinpollet)) +- Merge branch v3.1 into master ([#10952](https://github.com/traefik/traefik/pull/10952) by [mmatur](https://github.com/mmatur)) +- Merge branch v3.1 into master ([#10906](https://github.com/traefik/traefik/pull/10906) by [rtribotte](https://github.com/rtribotte)) + ## [v3.1.7](https://github.com/traefik/traefik/tree/v3.1.7) (2024-10-28) [All Commits](https://github.com/traefik/traefik/compare/v3.1.6...v3.1.7) diff --git a/script/gcg/traefik-final-release-part1.toml b/script/gcg/traefik-final-release-part1.toml index 69d309e74..8b2375d76 100644 --- a/script/gcg/traefik-final-release-part1.toml +++ b/script/gcg/traefik-final-release-part1.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example final release of v3.1.0 -CurrentRef = "v3.1" -PreviousRef = "v3.1.0-rc1" -BaseBranch = "v3.1" -FutureCurrentRefName = "v3.1.0" +# example final release of v3.2.0 +CurrentRef = "v3.2" +PreviousRef = "v3.2.0-rc1" +BaseBranch = "v3.2" +FutureCurrentRefName = "v3.2.0" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/script/gcg/traefik-final-release-part2.toml b/script/gcg/traefik-final-release-part2.toml index f005fc043..81f571eef 100644 --- a/script/gcg/traefik-final-release-part2.toml +++ b/script/gcg/traefik-final-release-part2.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example final release of v3.1.0 -CurrentRef = "v3.1.0-rc1" -PreviousRef = "v3.0.0-beta2" # divergence with master and branch v3 has been initiated with v3.0.0-beta2 +# example final release of v3.2.0 +CurrentRef = "v3.2.0-rc1" +PreviousRef = "v3.1.0-rc1" BaseBranch = "master" -FutureCurrentRefName = "v3.1.0-rc1" +FutureCurrentRefName = "v3.2.0-rc1" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From e8ff825ed272669604fc6c9ad2475f5019992f07 Mon Sep 17 00:00:00 2001 From: Nikolai K <45662151+nikonhub@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:30:38 +0100 Subject: [PATCH 18/18] Set Host header in HTTP provider request --- pkg/provider/http/http.go | 7 ++++++- pkg/provider/http/http_test.go | 12 +++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/provider/http/http.go b/pkg/provider/http/http.go index 4da8a2973..1068429b2 100644 --- a/pkg/provider/http/http.go +++ b/pkg/provider/http/http.go @@ -7,6 +7,7 @@ import ( "hash/fnv" "io" "net/http" + "strings" "time" "github.com/cenkalti/backoff/v4" @@ -149,7 +150,11 @@ func (p *Provider) fetchConfigurationData() ([]byte, error) { } for k, v := range p.Headers { - req.Header.Set(k, v) + if strings.EqualFold(k, "Host") { + req.Host = v + } else { + req.Header.Set(k, v) + } } res, err := p.httpClient.Do(req) diff --git a/pkg/provider/http/http_test.go b/pkg/provider/http/http_test.go index f99706ba9..c9f932536 100644 --- a/pkg/provider/http/http_test.go +++ b/pkg/provider/http/http_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -85,8 +86,9 @@ func TestProvider_fetchConfigurationData(t *testing.T) { desc: "should send configured headers", statusCode: http.StatusOK, headers: map[string]string{ - "Foo": "bar", - "Bar": "baz", + "Foo": "bar", + "Bar": "baz", + "Host": "localhost", }, expData: []byte("{}"), expErr: require.NoError, @@ -105,7 +107,11 @@ func TestProvider_fetchConfigurationData(t *testing.T) { handlerCalled = true for k, v := range test.headers { - assert.Equal(t, v, req.Header.Get(k)) + if strings.EqualFold(k, "Host") { + assert.Equal(t, v, req.Host) + } else { + assert.Equal(t, v, req.Header.Get(k)) + } } rw.WriteHeader(test.statusCode)