From 77509b0913f69f5f362390025ef44df3141cb1cc Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 22 Mar 2023 16:53:08 +0100 Subject: [PATCH 01/14] fix: decrease parallel build during the release --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0c957b003..8de756967 100644 --- a/Makefile +++ b/Makefile @@ -189,7 +189,7 @@ generate-genconf: .PHONY: release-packages release-packages: generate-webui build-dev-image rm -rf dist - $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) goreleaser release --skip-publish -p 4 --timeout="90m" + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) goreleaser release --skip-publish -p 2 --timeout="90m" $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) tar cfz dist/traefik-${VERSION}.src.tar.gz \ --exclude-vcs \ --exclude .idea \ From ac9d88e5a23203cd3abc09f0d15b756c726525ab Mon Sep 17 00:00:00 2001 From: Senan Kelly Date: Fri, 24 Mar 2023 00:26:07 +0000 Subject: [PATCH 02/14] Only warn about missing docker network when network_mode is not host or container --- pkg/provider/docker/config.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index 75110d095..894bb1049 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -310,6 +310,7 @@ func (p *Provider) getIPPort(ctx context.Context, container dockerData, serverPo func (p Provider) getIPAddress(ctx context.Context, container dockerData) string { logger := log.FromContext(ctx) + netNotFound := false if container.ExtraConf.Docker.Network != "" { settings := container.NetworkSettings if settings.Networks != nil { @@ -318,7 +319,8 @@ func (p Provider) getIPAddress(ctx context.Context, container dockerData) string return network.Addr } - logger.Warnf("Could not find network named '%s' for container '%s'! Maybe you're missing the project's prefix in the label? Defaulting to first available network.", container.ExtraConf.Docker.Network, container.Name) + netNotFound = true + logger.Debugf("Could not find network named %q for container %q. Maybe you're missing the project's prefix in the label?", container.ExtraConf.Docker.Network, container.Name) } } @@ -367,6 +369,9 @@ func (p Provider) getIPAddress(ctx context.Context, container dockerData) string } for _, network := range container.NetworkSettings.Networks { + if netNotFound { + logger.Warnf("Defaulting to first available network (%q) for container %q.", network, container.Name) + } return network.Addr } From f2eda3aa6df7eb3c031d8f9b527fc681985855c0 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 27 Mar 2023 12:14:05 +0200 Subject: [PATCH 03/14] chore: bump k8s.io/client-go from v0.22.1 to v0.26.3 --- docs/content/https/acme.md | 2 +- docs/scripts/verify.sh | 2 +- go.mod | 64 ++++---- go.sum | 116 +++++++++----- .../kubernetes/crd/client-containous.go | 56 +++++-- pkg/provider/kubernetes/crd/client.go | 65 ++++++-- pkg/provider/kubernetes/gateway/client.go | 45 ++++-- pkg/provider/kubernetes/ingress/client.go | 97 ++++++----- .../kubernetes/ingress/client_mock_test.go | 6 +- .../kubernetes/ingress/client_test.go | 22 +-- pkg/provider/kubernetes/ingress/convert.go | 70 ++++++++ .../kubernetes/ingress/convert_test.go | 151 ++++++++++++++++++ pkg/provider/kubernetes/ingress/kubernetes.go | 9 +- 13 files changed, 538 insertions(+), 167 deletions(-) create mode 100644 pkg/provider/kubernetes/ingress/convert.go create mode 100644 pkg/provider/kubernetes/ingress/convert_test.go diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index 640e0098a..85af60f9b 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -349,7 +349,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [Gandi v5](https://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | | [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | | [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | -| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | +| [GoDaddy](https://www.godaddy.com) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | | [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | | [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) | | [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) | diff --git a/docs/scripts/verify.sh b/docs/scripts/verify.sh index 970d18988..b3188c030 100755 --- a/docs/scripts/verify.sh +++ b/docs/scripts/verify.sh @@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \ --alt_ignore="/traefikproxy-vertical-logo-color.svg/" \ --http_status_ignore="0,500,501,503" \ --file_ignore="/404.html/" \ - --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/" \ + --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/,/www.godaddy.com/" \ '{}' 1>/dev/null ## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration diff --git a/go.mod b/go.mod index 8cc17b600..b4310a3c8 100644 --- a/go.mod +++ b/go.mod @@ -52,8 +52,8 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pires/go-proxyproto v0.6.1 github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.12.2-0.20220704083116-e8f91604d835 - github.com/prometheus/client_model v0.2.0 + github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_model v0.3.0 github.com/quic-go/quic-go v0.33.0 github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac github.com/sirupsen/logrus v1.9.0 @@ -75,15 +75,15 @@ require ( golang.org/x/text v0.7.0 golang.org/x/time v0.3.0 golang.org/x/tools v0.2.0 - google.golang.org/grpc v1.41.0 + google.golang.org/grpc v1.49.0 gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.22.1 - k8s.io/apiextensions-apiserver v0.21.3 - k8s.io/apimachinery v0.22.1 - k8s.io/client-go v0.22.1 - k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e + k8s.io/api v0.26.3 + k8s.io/apiextensions-apiserver v0.26.3 + k8s.io/apimachinery v0.26.3 + k8s.io/client-go v0.26.3 + k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 mvdan.cc/xurls/v2 v2.1.0 sigs.k8s.io/gateway-api v0.4.0 ) @@ -155,16 +155,20 @@ require ( github.com/elastic/go-licenser v0.3.1 // indirect github.com/elastic/go-sysinfo v1.1.1 // indirect github.com/elastic/go-windows v1.0.0 // indirect - github.com/evanphx/json-patch v4.11.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exoscale/egoscale v0.90.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v0.4.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect + 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-redis/redis/v8 v8.11.5 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect @@ -177,18 +181,18 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect github.com/gophercloud/gophercloud v1.0.0 // indirect github.com/gophercloud/utils v0.0.0-20210216074907-f6de111f2eae // indirect github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect github.com/hashicorp/consul/sdk v0.10.0 // indirect github.com/hashicorp/cronexpr v1.1.1 // indirect @@ -210,7 +214,7 @@ require ( github.com/huandu/xstrings v1.3.3 // indirect github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect github.com/imdario/mergo v0.3.12 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea // indirect @@ -252,6 +256,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect github.com/nrdcg/auroradns v1.1.0 // indirect github.com/nrdcg/desec v0.6.0 // indirect @@ -260,7 +265,7 @@ require ( github.com/nrdcg/goinwx v0.8.1 // indirect github.com/nrdcg/namesilo v0.2.1 // indirect github.com/nrdcg/porkbun v0.1.1 // indirect - github.com/onsi/ginkgo/v2 v2.2.0 // indirect + github.com/onsi/ginkgo/v2 v2.4.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.4 // indirect @@ -270,8 +275,8 @@ require ( github.com/philhofer/fwd v1.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pquerna/otp v1.3.0 // indirect - github.com/prometheus/common v0.35.0 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-19 v0.2.1 // indirect github.com/quic-go/qtls-go1-20 v0.1.1 // indirect @@ -289,7 +294,7 @@ require ( github.com/softlayer/softlayer-go v1.0.6 // indirect github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect github.com/spf13/cast v1.3.1 // indirect - github.com/spf13/cobra v1.2.1 // indirect + github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect @@ -310,14 +315,14 @@ require ( github.com/yandex-cloud/go-sdk v0.0.0-20220805164847-cf028e604997 // indirect go.elastic.co/apm/module/apmhttp v1.13.1 // indirect go.elastic.co/fastjson v1.1.0 // indirect - go.etcd.io/etcd/api/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect - go.etcd.io/etcd/client/v3 v3.5.4 // indirect + go.etcd.io/etcd/api/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect + go.etcd.io/etcd/client/v3 v3.5.5 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect - go.uber.org/zap v1.18.1 // indirect + go.uber.org/zap v1.19.0 // indirect go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect golang.org/x/crypto v0.5.0 // indirect @@ -330,18 +335,19 @@ require ( golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.44.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/ns1/ns1-go.v2 v2.6.5 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect inet.af/netaddr v0.0.0-20220617031823-097006376321 // indirect - k8s.io/klog/v2 v2.10.0 // indirect - k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) // Containous forks diff --git a/go.sum b/go.sum index 68881132a..e295ed62a 100644 --- a/go.sum +++ b/go.sum @@ -312,8 +312,12 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 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= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= @@ -464,6 +468,7 @@ github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobe github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= @@ -593,6 +598,8 @@ github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/El github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -603,13 +610,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= 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.90.0 h1:DZBXVU3iHqu5Ju5lQ5jWVlPo0IpI98SUo8Aa1UQVrmo= github.com/exoscale/egoscale v0.90.0/go.mod h1:wyXE5zrnFynMXA0jMhwQqSe24CfUhmBk2WI5wFZcq6Y= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -630,8 +639,8 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= @@ -674,24 +683,30 @@ github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNV github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +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/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -805,6 +820,8 @@ github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -818,8 +835,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.0.0-20191015185424-71da34e4d9b3/go.mod h1:ZXFeSndFcK4vB1NR4voH1Zm38K7ViUNiYtfIBDxrwf0= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= @@ -870,7 +887,6 @@ github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= 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 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.15.1-0.20210202035223-633d73521055/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= @@ -894,8 +910,9 @@ github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:Fecb github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg= github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -1040,8 +1057,9 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb-client-go/v2 v2.7.0 h1:QgP5mlBE9sGnzplpnf96pr+p7uqlIlL4W2GAP3n+XZg= github.com/influxdata/influxdb-client-go/v2 v2.7.0/go.mod h1:Y/0W1+TZir7ypoQZYd2IrnVOKB3Tq6oegAQeSVN/+EU= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= @@ -1334,6 +1352,7 @@ github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1 github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1389,8 +1408,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= -github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1404,7 +1423,7 @@ github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1514,16 +1533,17 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP 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.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2-0.20220704083116-e8f91604d835 h1:sYuFGkrz0PtewSFk0Bg7p7jjiiklc6FUIWz+mFGQfD0= -github.com/prometheus/client_golang v1.12.2-0.20220704083116-e8f91604d835/go.mod h1:RjnYTcBFM8s+WRft6oBqj4p5OgXJASPw5UFiI7w+GSs= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -1536,8 +1556,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.35.0 h1:Eyr+Pw2VymWejHqCugNaQXkAi6KayVNxaHeu6khmFBE= -github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1552,8 +1572,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/qri-io/jsonpointer v0.1.0/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= github.com/qri-io/jsonschema v0.1.1/go.mod h1:QpzJ6gBQ0GYgGmh7mDQ1YsvvhSgE4rYj0k8t5MBOmUY= @@ -1660,8 +1681,9 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1837,14 +1859,14 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= 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.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI= +go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1875,8 +1897,9 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.18.1 h1:CSUJ2mjFszzEWt4CdKISEuChVIXGBn3lAPwkRGyVrc4= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= @@ -2204,6 +2227,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2389,6 +2413,7 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -2411,8 +2436,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 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 h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2443,8 +2469,10 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 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 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= 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= @@ -2458,8 +2486,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 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 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 h1:Dez4VzRQWAI5YXJRBx58BiC0gONGuW/oY4l8fWKzOXY= gopkg.in/DataDog/dd-trace-go.v1 v1.43.1/go.mod h1:YL9g+nlUY7ByCffD5pDytAqy99GNbytRV0EBpKuldM4= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -2553,10 +2582,12 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU= k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= -k8s.io/api v0.22.1 h1:ISu3tD/jRhYfSW8jI/Q1e+lRxkR7w9UwQEZ7FgslrwY= k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= -k8s.io/apiextensions-apiserver v0.21.3 h1:+B6biyUWpqt41kz5x6peIsljlsuwvNAp/oFax/j2/aY= +k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= +k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE= +k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= +k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= k8s.io/apimachinery v0.0.0-20180904193909-def12e63c512/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= k8s.io/apimachinery v0.0.0-20190806215851-162a2dabc72f/go.mod h1:+ntn62igV2hyNj7/0brOvXSMONE2KxcePkSxK7/9FFQ= k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ= @@ -2566,8 +2597,9 @@ k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= -k8s.io/apimachinery v0.22.1 h1:DTARnyzmdHMz7bFWFDDm22AM4pLWTQECMpRTFu2d2OM= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= +k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= @@ -2580,8 +2612,9 @@ k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA= k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU= -k8s.io/client-go v0.22.1 h1:jW0ZSHi8wW260FvcXHkIa0NLxFBQszTlhiAVsU5mopw= k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= +k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s= +k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo= k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= @@ -2607,23 +2640,26 @@ k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE= k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e h1:ldQh+neBabomh7+89dTpiFAB8tGdfVmuIzAHbvtl+9I= k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY= +k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= mvdan.cc/xurls/v2 v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA= mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E= @@ -2638,14 +2674,18 @@ sigs.k8s.io/controller-runtime v0.9.6/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCb sigs.k8s.io/controller-tools v0.6.2/go.mod h1:oaeGpjXn6+ZSEIQkUe/+3I40PNiDYp9aeawbt3xTgJ8= sigs.k8s.io/gateway-api v0.4.0 h1:07IJkTt21NetZTHtPKJk2I4XIgDN4BAlTIq1wK7V11o= sigs.k8s.io/gateway-api v0.4.0/go.mod h1:r3eiNP+0el+NTLwaTfOrCNXy8TukC+dIM3ggc+fbNWk= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/pkg/provider/kubernetes/crd/client-containous.go b/pkg/provider/kubernetes/crd/client-containous.go index 1b67f0201..6b2ba3ea4 100644 --- a/pkg/provider/kubernetes/crd/client-containous.go +++ b/pkg/provider/kubernetes/crd/client-containous.go @@ -320,16 +320,52 @@ func (c *clientWrapper) getContainousTraefikService(namespace, name string) (*v1 return toVersion.(*v1alpha1.TraefikService), exist, err } -func addContainousInformers(factoryCrd externalversions.SharedInformerFactory, eventHandler *k8s.ResourceEventHandler) { - factoryCrd.TraefikContainous().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().Middlewares().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().MiddlewareTCPs().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler) - factoryCrd.TraefikContainous().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler) +func addContainousInformers(factoryCrd externalversions.SharedInformerFactory, eventHandler *k8s.ResourceEventHandler) error { + _, err := factoryCrd.TraefikContainous().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().Middlewares().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().MiddlewareTCPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + _, err = factoryCrd.TraefikContainous().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + _, err = factoryCrd.TraefikContainous().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler) + if err != nil { + return err + } + + return nil } func objectKey(meta metav1.ObjectMeta) string { diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 2330d3a00..9586a18fa 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -163,24 +163,63 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< for _, ns := range namespaces { factoryCrd := externalversions.NewSharedInformerFactoryWithOptions(c.csCrd, resyncPeriod, externalversions.WithNamespace(ns), externalversions.WithTweakListOptions(matchesLabelSelector)) - factoryCrd.Traefik().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().Middlewares().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().MiddlewareTCPs().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler) - factoryCrd.Traefik().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler) + _, err := factoryCrd.Traefik().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().Middlewares().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().MiddlewareTCPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().IngressRouteTCPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryCrd.Traefik().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } - addContainousInformers(factoryCrd, eventHandler) + err = addContainousInformers(factoryCrd, eventHandler) + if err != nil { + return nil, err + } factoryKube := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns)) - factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) - factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } factorySecret := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) - factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } c.factoriesCrd[ns] = factoryCrd c.factoriesKube[ns] = factoryKube diff --git a/pkg/provider/kubernetes/gateway/client.go b/pkg/provider/kubernetes/gateway/client.go index e8317e45f..1561ad472 100644 --- a/pkg/provider/kubernetes/gateway/client.go +++ b/pkg/provider/kubernetes/gateway/client.go @@ -172,27 +172,54 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } c.factoryNamespace = informers.NewSharedInformerFactory(c.csKube, resyncPeriod) - c.factoryNamespace.Core().V1().Namespaces().Informer().AddEventHandler(eventHandler) + _, err := c.factoryNamespace.Core().V1().Namespaces().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } c.factoryGatewayClass = externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithTweakListOptions(labelSelectorOptions)) - c.factoryGatewayClass.Gateway().V1alpha2().GatewayClasses().Informer().AddEventHandler(eventHandler) + _, err = c.factoryGatewayClass.Gateway().V1alpha2().GatewayClasses().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } // TODO manage Reference Policy // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.ReferencePolicy for _, ns := range namespaces { factoryGateway := externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithNamespace(ns)) - factoryGateway.Gateway().V1alpha2().Gateways().Informer().AddEventHandler(eventHandler) - factoryGateway.Gateway().V1alpha2().HTTPRoutes().Informer().AddEventHandler(eventHandler) - factoryGateway.Gateway().V1alpha2().TCPRoutes().Informer().AddEventHandler(eventHandler) - factoryGateway.Gateway().V1alpha2().TLSRoutes().Informer().AddEventHandler(eventHandler) + _, err = factoryGateway.Gateway().V1alpha2().Gateways().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryGateway.Gateway().V1alpha2().HTTPRoutes().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryGateway.Gateway().V1alpha2().TCPRoutes().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryGateway.Gateway().V1alpha2().TLSRoutes().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } factoryKube := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns)) - factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) - factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } factorySecret := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) - factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } c.factoriesGateway[ns] = factoryGateway c.factoriesKube[ns] = factoryKube diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index b9759b1f0..a2d6bfe31 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -31,10 +31,6 @@ const ( defaultTimeout = 5 * time.Second ) -type marshaler interface { - Marshal() ([]byte, error) -} - // Client is a client for the Provider master. // WatchAll starts the watch of the Provider resources and updates the stores. // The stores can then be accessed via the Get* functions. @@ -45,7 +41,7 @@ type Client interface { GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) - UpdateIngressStatus(ing *networkingv1.Ingress, ingStatus []corev1.LoadBalancerIngress) error + UpdateIngressStatus(ing *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error GetServerVersion() *version.Version } @@ -171,20 +167,35 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< factoryIngress := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(matchesLabelSelector)) if supportsNetworkingV1Ingress(serverVersion) { - factoryIngress.Networking().V1().Ingresses().Informer().AddEventHandler(eventHandler) + _, err = factoryIngress.Networking().V1().Ingresses().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } } else { - factoryIngress.Networking().V1beta1().Ingresses().Informer().AddEventHandler(eventHandler) + _, err = factoryIngress.Networking().V1beta1().Ingresses().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } } c.factoriesIngress[ns] = factoryIngress factoryKube := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns)) - factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) - factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } + _, err = factoryKube.Core().V1().Endpoints().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } c.factoriesKube[ns] = factoryKube factorySecret := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) - factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } c.factoriesSecret[ns] = factorySecret } @@ -218,9 +229,15 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< c.clusterFactory = informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod) if supportsNetworkingV1Ingress(serverVersion) { - c.clusterFactory.Networking().V1().IngressClasses().Informer().AddEventHandler(eventHandler) + _, err = c.clusterFactory.Networking().V1().IngressClasses().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } } else { - c.clusterFactory.Networking().V1beta1().IngressClasses().Informer().AddEventHandler(eventHandler) + _, err = c.clusterFactory.Networking().V1beta1().IngressClasses().Informer().AddEventHandler(eventHandler) + if err != nil { + return nil, err + } } c.clusterFactory.Start(stopCh) @@ -262,7 +279,7 @@ func (c *clientWrapper) GetIngresses() []*networkingv1.Ingress { } for _, ing := range list { - n, err := toNetworkingV1(ing) + n, err := convert[networkingv1.Ingress](ing) if err != nil { log.WithoutContext().Errorf("Failed to convert ingress %s from networking/v1beta1 to networking/v1: %v", ns, err) continue @@ -276,36 +293,6 @@ func (c *clientWrapper) GetIngresses() []*networkingv1.Ingress { return results } -func toNetworkingV1(ing marshaler) (*networkingv1.Ingress, error) { - data, err := ing.Marshal() - if err != nil { - return nil, err - } - - ni := &networkingv1.Ingress{} - err = ni.Unmarshal(data) - if err != nil { - return nil, err - } - - return ni, nil -} - -func toNetworkingV1IngressClass(ing marshaler) (*networkingv1.IngressClass, error) { - data, err := ing.Marshal() - if err != nil { - return nil, err - } - - ni := &networkingv1.IngressClass{} - err = ni.Unmarshal(data) - if err != nil { - return nil, err - } - - return ni, nil -} - func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingress) { if old.Spec.Backend != nil { port := networkingv1.ServiceBackendPort{} @@ -352,7 +339,7 @@ func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingr } // UpdateIngressStatus updates an Ingress with a provided status. -func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus []corev1.LoadBalancerIngress) error { +func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error { if !c.isWatchedNamespace(src.Namespace) { return fmt.Errorf("failed to get ingress %s/%s: namespace is not within watched namespaces", src.Namespace, src.Name) } @@ -374,7 +361,7 @@ func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus } ingCopy := ing.DeepCopy() - ingCopy.Status = networkingv1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: ingStatus}} + ingCopy.Status = networkingv1.IngressStatus{LoadBalancer: networkingv1.IngressLoadBalancerStatus{Ingress: ingStatus}} ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() @@ -388,7 +375,7 @@ func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus return nil } -func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingStatus []corev1.LoadBalancerIngress) error { +func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error { ing, err := c.factoriesIngress[c.lookupNamespace(src.Namespace)].Networking().V1beta1().Ingresses().Lister().Ingresses(src.Namespace).Get(src.Name) if err != nil { return fmt.Errorf("failed to get ingress %s/%s: %w", src.Namespace, src.Name, err) @@ -396,13 +383,23 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingSta logger := log.WithoutContext().WithField("namespace", ing.Namespace).WithField("ingress", ing.Name) - if isLoadBalancerIngressEquals(ing.Status.LoadBalancer.Ingress, ingStatus) { + ingresses, err := convertSlice[networkingv1.IngressLoadBalancerIngress](ing.Status.LoadBalancer.Ingress) + if err != nil { + return err + } + + if isLoadBalancerIngressEquals(ingresses, ingStatus) { logger.Debug("Skipping ingress status update") return nil } + ingressesBeta1, err := convertSlice[networkingv1beta1.IngressLoadBalancerIngress](ingStatus) + if err != nil { + return err + } + ingCopy := ing.DeepCopy() - ingCopy.Status = networkingv1beta1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: ingStatus}} + ingCopy.Status = networkingv1beta1.IngressStatus{LoadBalancer: networkingv1beta1.IngressLoadBalancerStatus{Ingress: ingressesBeta1}} ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() @@ -416,7 +413,7 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingSta } // isLoadBalancerIngressEquals returns true if the given slices are equal, false otherwise. -func isLoadBalancerIngressEquals(aSlice, bSlice []corev1.LoadBalancerIngress) bool { +func isLoadBalancerIngressEquals(aSlice, bSlice []networkingv1.IngressLoadBalancerIngress) bool { if len(aSlice) != len(bSlice) { return false } @@ -482,7 +479,7 @@ func (c *clientWrapper) GetIngressClasses() ([]*networkingv1.IngressClass, error for _, ic := range ingressClasses { if ic.Spec.Controller == traefikDefaultIngressClassController { - icN, err := toNetworkingV1IngressClass(ic) + icN, err := convert[networkingv1.IngressClass](ic) if err != nil { log.WithoutContext().Errorf("Failed to convert ingress class %s from networking/v1beta1 to networking/v1: %v", ic.Name, err) continue diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index 6cc6ef138..21883ca67 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -51,7 +51,7 @@ func newClientMock(serverVersion string, paths ...string) clientMock { case *corev1.Endpoints: c.endpoints = append(c.endpoints, o) case *networkingv1beta1.Ingress: - ing, err := toNetworkingV1(o) + ing, err := convert[networkingv1.Ingress](o) if err != nil { panic(err) } @@ -60,7 +60,7 @@ func newClientMock(serverVersion string, paths ...string) clientMock { case *networkingv1.Ingress: c.ingresses = append(c.ingresses, o) case *networkingv1beta1.IngressClass: - ic, err := toNetworkingV1IngressClass(o) + ic, err := convert[networkingv1.IngressClass](o) if err != nil { panic(err) } @@ -132,6 +132,6 @@ func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-cha return c.watchChan, nil } -func (c clientMock) UpdateIngressStatus(_ *networkingv1.Ingress, _ []corev1.LoadBalancerIngress) error { +func (c clientMock) UpdateIngressStatus(_ *networkingv1.Ingress, _ []networkingv1.IngressLoadBalancerIngress) error { return c.apiIngressStatusError } diff --git a/pkg/provider/kubernetes/ingress/client_test.go b/pkg/provider/kubernetes/ingress/client_test.go index 48f0bf064..11eb03f4b 100644 --- a/pkg/provider/kubernetes/ingress/client_test.go +++ b/pkg/provider/kubernetes/ingress/client_test.go @@ -61,8 +61,8 @@ func TestTranslateNotFoundError(t *testing.T) { func TestIsLoadBalancerIngressEquals(t *testing.T) { testCases := []struct { desc string - aSlice []corev1.LoadBalancerIngress - bSlice []corev1.LoadBalancerIngress + aSlice []networkingv1.IngressLoadBalancerIngress + bSlice []networkingv1.IngressLoadBalancerIngress expectedEqual bool }{ { @@ -71,28 +71,28 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "not the same length", - bSlice: []corev1.LoadBalancerIngress{ + bSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, expectedEqual: false, }, { desc: "same ordered content", - aSlice: []corev1.LoadBalancerIngress{ + aSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, - bSlice: []corev1.LoadBalancerIngress{ + bSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, expectedEqual: true, }, { desc: "same unordered content", - aSlice: []corev1.LoadBalancerIngress{ + aSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []corev1.LoadBalancerIngress{ + bSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.2", Hostname: "traefik2"}, {IP: "192.168.1.1", Hostname: "traefik"}, }, @@ -100,11 +100,11 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "different ordered content", - aSlice: []corev1.LoadBalancerIngress{ + aSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []corev1.LoadBalancerIngress{ + bSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik"}, }, @@ -112,11 +112,11 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "different unordered content", - aSlice: []corev1.LoadBalancerIngress{ + aSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []corev1.LoadBalancerIngress{ + bSlice: []networkingv1.IngressLoadBalancerIngress{ {IP: "192.168.1.2", Hostname: "traefik3"}, {IP: "192.168.1.1", Hostname: "traefik"}, }, diff --git a/pkg/provider/kubernetes/ingress/convert.go b/pkg/provider/kubernetes/ingress/convert.go new file mode 100644 index 000000000..c4482ec13 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/convert.go @@ -0,0 +1,70 @@ +package ingress + +import ( + "errors" + + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" +) + +type marshaler interface { + Marshal() ([]byte, error) +} + +type unmarshaler interface { + Unmarshal([]byte) error +} + +type LoadBalancerIngress interface { + corev1.LoadBalancerIngress | networkingv1beta1.IngressLoadBalancerIngress | networkingv1.IngressLoadBalancerIngress +} + +// convertSlice converts slice of LoadBalancerIngress to slice of LoadBalancerIngress. +// O (Bar), I (Foo) => []Bar. +func convertSlice[O LoadBalancerIngress, I LoadBalancerIngress](loadBalancerIngresses []I) ([]O, error) { + var results []O + + for _, loadBalancerIngress := range loadBalancerIngresses { + mar, ok := any(&loadBalancerIngress).(marshaler) + if !ok { + // All the pointer of types related to the interface LoadBalancerIngress are compatible with the interface marshaler. + continue + } + + um, err := convert[O](mar) + if err != nil { + return nil, err + } + + v, ok := any(*um).(O) + if !ok { + continue + } + + results = append(results, v) + } + + return results, nil +} + +// convert must only be used with unmarshaler and marshaler compatible types. +func convert[T any](input marshaler) (*T, error) { + data, err := input.Marshal() + if err != nil { + return nil, err + } + + var output T + um, ok := any(&output).(unmarshaler) + if !ok { + return nil, errors.New("the output type doesn't implement unmarshaler interface") + } + + err = um.Unmarshal(data) + if err != nil { + return nil, err + } + + return &output, nil +} diff --git a/pkg/provider/kubernetes/ingress/convert_test.go b/pkg/provider/kubernetes/ingress/convert_test.go new file mode 100644 index 000000000..4a4759313 --- /dev/null +++ b/pkg/provider/kubernetes/ingress/convert_test.go @@ -0,0 +1,151 @@ +package ingress + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" +) + +func Test_convertSlice_corev1_to_networkingv1(t *testing.T) { + g := []corev1.LoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []corev1.PortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + actual, err := convertSlice[networkingv1.IngressLoadBalancerIngress](g) + require.NoError(t, err) + + expected := []networkingv1.IngressLoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []networkingv1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + assert.Equal(t, expected, actual) +} + +func Test_convertSlice_networkingv1beta1_to_networkingv1(t *testing.T) { + g := []networkingv1beta1.IngressLoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []networkingv1beta1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + actual, err := convertSlice[networkingv1.IngressLoadBalancerIngress](g) + require.NoError(t, err) + + expected := []networkingv1.IngressLoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []networkingv1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + assert.Equal(t, expected, actual) +} + +func Test_convertSlice_networkingv1_to_networkingv1beta1(t *testing.T) { + g := []networkingv1.IngressLoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []networkingv1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + actual, err := convertSlice[networkingv1beta1.IngressLoadBalancerIngress](g) + require.NoError(t, err) + + expected := []networkingv1beta1.IngressLoadBalancerIngress{ + { + IP: "132456", + Hostname: "foo", + Ports: []networkingv1beta1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + }, + } + + assert.Equal(t, expected, actual) +} + +func Test_convert(t *testing.T) { + g := &corev1.LoadBalancerIngress{ + IP: "132456", + Hostname: "foo", + Ports: []corev1.PortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + } + + actual, err := convert[networkingv1.IngressLoadBalancerIngress](g) + require.NoError(t, err) + + expected := &networkingv1.IngressLoadBalancerIngress{ + IP: "132456", + Hostname: "foo", + Ports: []networkingv1.IngressPortStatus{ + { + Port: 123, + Protocol: "https", + Error: ptr("test"), + }, + }, + } + + assert.Equal(t, expected, actual) +} + +func ptr[T any](v T) *T { + return &v +} diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 0698b860f..8724b09dd 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -350,7 +350,7 @@ func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Clie return errors.New("publishedService or ip or hostname must be defined") } - return k8sClient.UpdateIngressStatus(ing, []corev1.LoadBalancerIngress{{IP: p.IngressEndpoint.IP, Hostname: p.IngressEndpoint.Hostname}}) + return k8sClient.UpdateIngressStatus(ing, []networkingv1.IngressLoadBalancerIngress{{IP: p.IngressEndpoint.IP, Hostname: p.IngressEndpoint.Hostname}}) } serviceInfo := strings.Split(p.IngressEndpoint.PublishedService, "/") @@ -375,7 +375,12 @@ func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Clie return fmt.Errorf("missing service: %s", p.IngressEndpoint.PublishedService) } - return k8sClient.UpdateIngressStatus(ing, service.Status.LoadBalancer.Ingress) + ingresses, err := convertSlice[networkingv1.IngressLoadBalancerIngress](service.Status.LoadBalancer.Ingress) + if err != nil { + return err + } + + return k8sClient.UpdateIngressStatus(ing, ingresses) } func (p *Provider) shouldProcessIngress(ingress *networkingv1.Ingress, ingressClasses []*networkingv1.IngressClass) bool { From 7fc07c31a030e048f9d3c6cc4626fb9b220ac9e6 Mon Sep 17 00:00:00 2001 From: sven Date: Wed, 29 Mar 2023 17:16:05 +0200 Subject: [PATCH 04/14] docs: update wording --- docs/content/contributing/advocating.md | 4 +- docs/content/contributing/data-collection.md | 12 +- .../contributing/maintainers-guidelines.md | 16 +- .../content/contributing/submitting-issues.md | 17 +- .../contributing/submitting-pull-requests.md | 156 ++++++------ .../submitting-security-issues.md | 2 +- docs/content/https/acme.md | 230 +++++++++--------- 7 files changed, 218 insertions(+), 219 deletions(-) diff --git a/docs/content/contributing/advocating.md b/docs/content/contributing/advocating.md index 785c97156..c7bbaacd7 100644 --- a/docs/content/contributing/advocating.md +++ b/docs/content/contributing/advocating.md @@ -9,7 +9,7 @@ Spread the Love & Tell Us about It {: .subtitle } Traefik Proxy was started by the community for the community. -You can contribute to the Traefik community in three main ways: +You can contribute to the Traefik community in three main ways: **Spread the word!** Guides, videos, blog posts, how-to articles, and showing off your network design all help spread the word about Traefik Proxy and teach others in the community how to best implement it. @@ -28,4 +28,4 @@ Luckily, as an open source community, our users can help by [building awesome fe We are a big community, so we do need to prioritize a bit. That is why we use the tag `contributor/wanted` to let you know which pull requests will make it to the front of the queue for design support and review. Feel free to grab one of these and run with it. -Top contributors get unique swag to celebrate. +Top contributors get unique swag to celebrate. diff --git a/docs/content/contributing/data-collection.md b/docs/content/contributing/data-collection.md index cb047d8fe..f68f329cc 100644 --- a/docs/content/contributing/data-collection.md +++ b/docs/content/contributing/data-collection.md @@ -10,8 +10,8 @@ Understanding How Traefik is Being Used ## Configuration Example -Understanding how you use Traefik is very important to us: it helps us improve the solution in many different ways. -For this very reason, the sendAnonymousUsage option is mandatory: we want you to take time to consider whether or not you wish to share anonymous data with us so we can benefit from your experience and use cases. +Understanding how you use Traefik is very important to us: it helps us improve the solution in many different ways. +For this very reason, the sendAnonymousUsage option is mandatory: we want you to take time to consider whether or not you wish to share anonymous data with us, so we can benefit from your experience and use cases. !!! example "Enabling Data Collection" @@ -34,9 +34,7 @@ For this very reason, the sendAnonymousUsage option is mandatory: we want you to ## Collected Data -This feature comes from the public proposal [here](https://github.com/traefik/traefik/issues/2369). - -This feature is activated when using Traefik Pilot to better understand the community's need, and also to get information about plug-ins popularity. +This feature comes from this [public proposal](https://github.com/traefik/traefik/issues/2369). In order to help us learn more about how Traefik is being used and improve it, we collect anonymous usage statistics from running instances. Those data help us prioritize our developments and focus on what's important for our users (for example, which provider is popular, and which is not). @@ -47,7 +45,7 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col - the Traefik version number - a hash of the configuration -- an **anonymized version** of the static configuration (token, user name, password, URL, IP, domain, email, etc, are removed). +- an **anonymized version** of the static configuration (token, username, password, URL, IP, domain, email, etc., are removed). !!! info @@ -101,4 +99,4 @@ providers: If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/traefik/traefik/blob/master/pkg/collector/collector.go) -By default we anonymize all configuration fields, except fields tagged with `export=true`. +By default, we anonymize all configuration fields, except fields tagged with `export=true`. diff --git a/docs/content/contributing/maintainers-guidelines.md b/docs/content/contributing/maintainers-guidelines.md index b1d2a0432..049bd92e8 100644 --- a/docs/content/contributing/maintainers-guidelines.md +++ b/docs/content/contributing/maintainers-guidelines.md @@ -11,7 +11,7 @@ Note: the document is a work in progress. Welcome to the Traefik Community. This document describes how to be part of the core team -as well as various responsibilities +together with various responsibilities and guidelines for Traefik maintainers. We are strongly promoting a philosophy of openness and sharing, and firmly standing against the elitist closed approach. @@ -20,7 +20,7 @@ and wants to be part of that journey! ## Onboarding Process -If you consider joining our community please drop us a line using Twitter or leave a note in the issue. +If you consider joining our community, please drop us a line using Twitter or leave a note in the issue. We will schedule a quick call to meet you and learn more about your motivation. During the call, the team will discuss the process of becoming a maintainer. We will be happy to answer any questions and explain all your doubts. @@ -53,7 +53,7 @@ but we can suggest you start with activities such as: Each of the issues that are labeled as bug/possible bug/confirmed requires a reproducible use case. You can help in creating a reproducible use case if it has not been added to the issue or use the sample code provided by the reporter. - Typically, a simple docker compose should be enough to reproduce the issue. + Typically, a simple Docker Compose should be enough to reproduce the issue. - Code contribution. - Documentation contribution. - Technical documentation is one of the most important components of the product. @@ -61,7 +61,7 @@ but we can suggest you start with activities such as: using the official documentation, is a game changer. - You will be listed on our Maintainers GitHub page - as well as on our website in the section [maintainers](maintainers.md). + and on our website in the section [maintainers](maintainers.md). - We will be promoting you on social channels (mostly on Twitter). ## Governance @@ -71,7 +71,7 @@ but we can suggest you start with activities such as: ## Communicating - All of our maintainers are added to Slack #traefik-maintainers channel that belongs to Traefik labs workspace. - Having the team in one place helps us to communicate effectively. + Having the team in one place helps us to communicate effectively. You can reach Traefik core developers directly, which offers the possibility to discuss issues, pull requests, enhancements more efficiently and get the feedback almost immediately. @@ -112,9 +112,9 @@ maintainers' activity and involvement will be reviewed on a regular basis. - Be able to put yourself in users’ shoes. - Be open-minded and respectful with other maintainers and other community members. -- Keep the communication public - +- Keep the communication public - if anyone tries to communicate with you directly, - ask him politely to move the conversation to a public communication channel. + ask politely to move the conversation to a public communication channel. - Stay away from defensive comments. - Please try to express your thoughts clearly enough and note that some of us are not native English speakers. @@ -122,7 +122,7 @@ maintainers' activity and involvement will be reviewed on a regular basis. none of us is able to predict your thoughts. - There are a lot of use cases of using Traefik and even more issues that are difficult to reproduce. - If the issue can’t be replicated due to a lack of reproducible case (a simple docker compose should be enough) - + If the issue can’t be replicated due to a lack of reproducible case (a simple Docker Compose should be enough) - set your time limits while working on the issue and express clearly that you were not able to replicate it. You can come back later to that case. diff --git a/docs/content/contributing/submitting-issues.md b/docs/content/contributing/submitting-issues.md index 9a06c3e99..89826aac9 100644 --- a/docs/content/contributing/submitting-issues.md +++ b/docs/content/contributing/submitting-issues.md @@ -9,10 +9,10 @@ Help Us Help You! {: .subtitle } Issues are perfect for requesting a feature/enhancement or reporting a suspected bug. -We use the [GitHub issue tracker](https://github.com/traefik/traefik/issues) to keep track of issues in Traefik. +We use the [GitHub issue tracker](https://github.com/traefik/traefik/issues) to keep track of issues in Traefik. The process of sorting and checking the issues is a daunting task, and requires a lot of work (more than an hour a day ... just for sorting). -To help us (and other community members) quickly and easily understand what you need, +To help us (and other community members) quickly and effortlessly understand what you need, be sure to follow the guidelines below. !!! important "Getting Help Vs Reporting an Issue" @@ -33,16 +33,17 @@ Examples: ## Feature Request -Traefik is an open source project and aims to be the best edge router possible. +Traefik is an open source project and aims to be the best edge router possible. Remember when asking for new features that these must be useful to the majority (and not only useful in edge case scenarios, or hack-like setups). Follow the [issue template](https://github.com/traefik/traefik/blob/master/.github/ISSUE_TEMPLATE/feature-request.yml) as much as possible. Do your best to explain what you're looking for, and why it would improve Traefik for everyone. Be detailed and share the use-case(s) to allow us to see the value of your feature request as quickly as possible. -Features with a lot of positive interaction (claps, +1s, conversation about how this would impact them) indicate higher community interest and help us to prioritize. -If you are interested in creating a PR for your feature request, let us know in the the issue so we can work with you. +Features with a lot of positive interaction (claps, +1s, conversation about how this would impact them) indicate higher community interest and help us to prioritize. + +If you are interested in creating a PR for your feature request, let us know in the issue, so we can work with you. It can take a lot of work to make sure a PR can integrate with our existing code and planning with the team ahead of time can make sure that your PR can be accepted and merged quickly. ## Issues or Possible Bug Reports @@ -50,13 +51,13 @@ It can take a lot of work to make sure a PR can integrate with our existing code Follow the [issue template](https://github.com/traefik/traefik/blob/master/.github/ISSUE_TEMPLATE/bug_report.yml) as much as possible. Explain the conditions in which you encountered the issue; what is your context? -Share any logs you may have and make sure to share the steps it takes to reproduce your issue or bug. +Share any logs you may have, and make sure to share the steps it takes to reproduce your issue or bug. Remain as clear and concise as possible. -Take time to polish the format of your message so we'll enjoy reading it and working on it. +Take time to polish the format of your message, so we'll enjoy reading it and working on it. Help your readers focus on what matters and help them understand the structure of your message (see the [GitHub Markdown Syntax](https://docs.github.com/en/get-started/writing-on-github)). ## International English -Every maintainer / Traefik user is not a native English speaker, so if you feel sometimes that some messages sound rude, remember that it probably is a language barrier problem from someone willing to help you. +Every maintainer / Traefik user is not a native English speaker, so if you sometimes feel that some messages sound rude, remember that it probably is a language barrier problem from someone willing to help you. diff --git a/docs/content/contributing/submitting-pull-requests.md b/docs/content/contributing/submitting-pull-requests.md index 855c04cf4..2e6a666fb 100644 --- a/docs/content/contributing/submitting-pull-requests.md +++ b/docs/content/contributing/submitting-pull-requests.md @@ -5,22 +5,22 @@ description: "Looking to contribute to Traefik Proxy? This guide will show you t # Before You Submit a Pull Request -This guide is for contributors who already have a pull request to submit. -If you are looking for information on setting up your developer environment -and creating code to contribute to Traefik Proxy or related projects, +This guide is for contributors who already have a pull request to submit. +If you are looking for information on setting up your developer environment +and creating code to contribute to Traefik Proxy or related projects, see the [development guide](https://docs.traefik.io/contributing/building-testing/). -Looking for a way to contribute to Traefik Proxy? -Check out this list of [Priority Issues](https://github.com/traefik/traefik/labels/contributor%2Fwanted), -the [Good First Issue](https://github.com/traefik/traefik/labels/contributor%2Fgood-first-issue) list, +Looking for a way to contribute to Traefik Proxy? +Check out this list of [Priority Issues](https://github.com/traefik/traefik/labels/contributor%2Fwanted), +the [Good First Issue](https://github.com/traefik/traefik/labels/contributor%2Fgood-first-issue) list, or the list of [confirmed bugs](https://github.com/traefik/traefik/labels/kind%2Fbug%2Fconfirmed) waiting to be remedied. ## How We Prioritize -We wish we could review every pull request right away. -Unfortunately, our team has to prioritize pull requests (PRs) for review -(but we are welcoming new [maintainers](https://github.com/traefik/traefik/blob/master/docs/content/contributing/maintainers-guidelines.md) to speed this up, -so if you are interested, check it out and apply). +We wish we could review every pull request right away. +Unfortunately, our team has to prioritize pull requests (PRs) for review +(but we are welcoming new [maintainers](https://github.com/traefik/traefik/blob/master/docs/content/contributing/maintainers-guidelines.md) to speed this up, +if you are interested, check it out and apply). The PRs we are able to handle fastest are: @@ -30,20 +30,20 @@ The PRs we are able to handle fastest are: PRs that take more time to address include: -* Enhancements or Features without the `contributor/wanted` tag. - -If you have an idea for an enhancement or feature that you would like to build, -[create an issue](https://github.com/traefik/traefik/issues/new/choose) for it first -and tell us you are interested in writing the PR. -If an issue already exists, definitely comment on it to tell us you are interested in creating a PR. +* Enhancements or Features without the `contributor/wanted` tag. + +If you have an idea for an enhancement or feature that you would like to build, +[create an issue](https://github.com/traefik/traefik/issues/new/choose) for it first +and tell us you are interested in writing the PR. +If an issue already exists, definitely comment on it to tell us you are interested in creating a PR. + +This will allow us to communicate directly and let you know if it is something we would accept. + +It also allows us to make sure you have all the information you need during the design phase +so that it can be reviewed and merged quickly. + +Read more about the [Triage process](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md) in the docs. -This will allow us to communicate directly and let you know if it is something we would accept. -It also allows us to make sure you have all the information you need during the design phase -so that it can be reviewed and merged quickly. - -If you have questions about the Triage process, -[read more here](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md). - ## The Pull Request Submit Process Merging a PR requires the following steps to be completed before it is merged automatically. @@ -63,8 +63,8 @@ Merging a PR requires the following steps to be completed before it is merged au ## Pull Request Review Cycle -You can read about our Triage Process [here](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md), -but in short, it looks like this: +Learn about our [Triage Process](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md), +in short, it looks like this: * We triage every new PR or comment before entering it into the review process. * We ensure that all prerequisites for review have been met. @@ -76,20 +76,20 @@ but in short, it looks like this: * Code Review. * We review the code in-depth and run tests. * We may ask for changes here. - * During code review, we ask that you be reasonably responsive, - if a PR languishes in code review it is at risk of rejection, + * During code review, we ask that you be reasonably responsive, + if a PR languishes in code review it is at risk of rejection, or we may take ownership of the PR and the contributor will become a co-author. -* Merge. +* Merge. * Success! !!! note - Occasionally, we may freeze our codebase when working towards a specific feature or goal that could impact other development. + Occasionally, we may freeze our codebase when working towards a specific feature or goal that could impact other development. During this time, your pull request could remain unmerged while the release work is completed. ## Run Local Verifications -You must run these local verifications before you submit your pull request to predict the pass or failure of continuous integration. +You must run these local verifications before you submit your pull request to predict the pass or failure of continuous integration. Your PR will not be reviewed until these are green on the CI. * `make validate` @@ -98,10 +98,10 @@ Your PR will not be reviewed until these are green on the CI. ## The Testing and Merge Workflow -Pull Requests are managed by the bot [Myrmica Lobicornis](https://github.com/traefik/lobicornis). -This bot is responsible for verifying GitHub Checks (CI, Tests, etc), mergability, and minimum reviews. -In addition, it rebases or merges with the base PR branch if needed. -It performs several other housekeeping items +Pull Requests are managed by the bot [Myrmica Lobicornis](https://github.com/traefik/lobicornis). +This bot is responsible for verifying GitHub Checks (CI, Tests, etc), mergability, and minimum reviews. +In addition, it rebases or merges with the base PR branch if needed. +It performs several other housekeeping items and you can read more about those on the [README](https://github.com/traefik/lobicornis) for Lobicornis. The maintainer giving the final LGTM must add the `status/3-needs-merge` label to trigger the merge bot. @@ -110,7 +110,7 @@ By default, a squash-rebase merge will be carried out. The status `status/4-merge-in-progress` is only used by the bot. -If the bot is not able to perform the merge, the label `bot/need-human-merge` is added. +If the bot is not able to perform the merge, the label `bot/need-human-merge` is added. In such a situation, solve the conflicts/CI/... and then remove the label `bot/need-human-merge`. To prevent the bot from automatically merging a PR, add the label `bot/no-merge`. @@ -126,23 +126,23 @@ This label can be used when: ## Why Was My Pull Request Closed? -Traefik Proxy is made by the community for the community, -as such the goal is to engage the community to make Traefik the best reverse proxy available. -Part of this goal is maintaining a lean codebase and ensuring code velocity. +Traefik Proxy is made by the community for the community, +as such the goal is to engage the community to make Traefik the best reverse proxy available. +Part of this goal is maintaining a lean codebase and ensuring code velocity. unfortunately, this means that sometimes we will not be able to merge a pull request. -Because we respect the work you did, you will always be told why we are closing your pull request. -If you do not agree with our decision, do not worry; closed pull requests are easy to recreate, +Because we respect the work you did, you will always be told why we are closing your pull request. +If you do not agree with our decision, do not worry; closed pull requests are effortless to recreate, and little work is lost by closing a pull request that subsequently needs to be reopened. Your pull request might be closed if: -* Your PR's design conflicts with our existing codebase in such a way that Merging is not an option +* Your PR's design conflicts with our existing codebase in such a way that merging is not an option and the work needed to make your pull request usable is too high. * To prevent this, make sure you created an issue first and think about including Traefik Proxy maintainers in your design phase to minimize conflicts. * Your PR is for an enhancement or feature that we will not use. - * Please remember to create an issue for any pull request **before** you create a PR + * Please remember to create an issue for any pull request **before** you create a PR to ensure that your goal is something we can merge and that you have any design insight you might need from the team. * Your PR has been waiting for feedback from the contributor for over 90 days. @@ -150,54 +150,54 @@ Your pull request might be closed if: A few factors affect how long your pull request might wait for review. -We must prioritize which PRs we focus on. -Our first priority is PRs we have identified as having high community engagement and broad applicability. -We put our top priorities on our roadmap and you can identify them by the `contributor/wanted` tag. -These PRs will enter our review process the fastest. +We must prioritize which PRs we focus on. +Our first priority is PRs we have identified as having high community engagement and broad applicability. +We put our top priorities on our roadmap, and you can identify them by the `contributor/wanted` tag. +These PRs will enter our review process the fastest. -Our second priority is bug fixes. -Especially for bugs that have already been tagged with `bug/confirmed`. +Our second priority is bug fixes. +Especially for bugs that have already been tagged with `bug/confirmed`. These reviews enter the process quickly. -If your PR does not meet the criteria above, -it will take longer for us to review as any PRs that do meet the criteria above will be prioritized. +If your PR does not meet the criteria above, +it will take longer for us to review, as any PRs that do meet the criteria above will be prioritized. -Additionally, during the last few weeks of a milestone, we stop reviewing PRs to reduce churn and stabilize. -We will resume after the release. +Additionally, during the last few weeks of a milestone, we stop reviewing PRs to reduce churn and stabilize. +We will resume after the release. -The second major reason that we deprioritize your PR is that you are not following best practices. +The second major reason that we deprioritize your PR is that you are not following best practices. The most common failures to follow best practices are: -* You did not create an issue for the PR you wish to make. - If you do not create an issue before submitting your PR, - we will not be able to answer any design questions and let you know how likely your PR is to be merged. +* You did not create an issue for the PR you wish to make. + If you do not create an issue before submitting your PR, + we will not be able to answer any design questions and let you know how likely your PR is to be merged. * You created pull requests that are too large to review. * Break your pull requests up. - If you can extract whole ideas from your pull request and send those as pull requests of their own, - you should do that instead. - It is better to have many pull requests addressing one thing than one pull request addressing many things. - * Traefik Proxy is a fast-moving codebase — lock in your changes ASAP with your small pull request, + If you can extract whole ideas from your pull request and send those as pull requests of their own, + you should do that instead. + It is better to have many pull requests addressing one thing than one pull request addressing many things. + * Traefik Proxy is a fast-moving codebase — lock in your changes ASAP with your small pull request, and make merges be someone else's problem. - We want every pull request to be useful on its own, + We want every pull request to be useful on its own, so use your best judgment on what should be a pull request vs. a commit. * You did not comment well. * Comment everything. -Please remember that we are working internationally, cross-culturally, and with different use-cases. +Please remember that we are working internationally, cross-culturally, and with different use-cases. Your reviewer will not intuitively understand the problem the same way you do or solve it the same way you would. -This is why every change you make must be explained and your strategy for coding must also be explained. +This is why every change you make must be explained, and your strategy for coding must also be explained. * Your tests were inadequate or absent. - * If you do not know how to test your PR, please ask! + * If you do not know how to test your PR, please ask! We will be happy to help you or suggest appropriate test cases. -If you have already followed the best practices and your PR still has not received a response, +If you have already followed the best practices and your PR still has not received a response, here are some things you can do to move the process along: -* If you have fixed all the issues from a review, - remember to re-request a review (using the designated button) to let your reviewer know that you are ready. - You can choose to comment with the changes you made. +* If you have fixed all the issues from a review, + remember to re-request a review (using the designated button) to let your reviewer know that you are ready. + You can choose to comment with the changes you made. * Ping `@tfny` if you have not been assigned to a reviewer. For more information on best practices, try these links: @@ -209,23 +209,23 @@ For more information on best practices, try these links: ## It's OK to Push Back -Sometimes reviewers make mistakes. -It is OK to push back on changes your reviewer requested. +Sometimes reviewers make mistakes. +It is OK to push back on changes your reviewer requested. If you have a good reason for doing something a certain way, you are absolutely allowed to debate the merits of a requested change. Both the reviewer and reviewee should strive to discuss these issues in a polite and respectful manner. -You might be overruled, but you might also prevail. +You might be overruled, but you might also prevail. We are pretty reasonable people. Another phenomenon of open-source projects (where anyone can comment on any issue) is the dog-pile - -your pull request gets so many comments from so many people it becomes hard to follow. -In this situation, you can ask the primary reviewer (assignee) whether they want you to fork a new pull request -to clear out all the comments. -You do not have to fix every issue raised by every person who feels like commenting, +your pull request gets so many comments from so many people it becomes hard to follow. +In this situation, you can ask the primary reviewer (assignee) whether they want you to fork a new pull request +to clear out all the comments. +You do not have to fix every issue raised by every person who feels like commenting, but you should answer reasonable comments with an explanation. ## Common Sense and Courtesy -No document can take the place of common sense and good taste. -Use your best judgment, while you put a bit of thought into how your work can be made easier to review. -If you do these things your pull requests will get merged with less friction. +No document can take the place of common sense and good taste. +Use your best judgment, while you put a bit of thought into how your work can be made easier to review. +If you do these things, your pull requests will get merged with less friction. diff --git a/docs/content/contributing/submitting-security-issues.md b/docs/content/contributing/submitting-security-issues.md index 71bbd7724..5a59408a2 100644 --- a/docs/content/contributing/submitting-security-issues.md +++ b/docs/content/contributing/submitting-security-issues.md @@ -12,7 +12,7 @@ You can subscribe sending a mail to security+subscribe@traefik.io or on [the onl ## CVE -Reported vulnerabilities can be found on +Reported vulnerabilities can be found on [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik). ## Report a Vulnerability diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index 85af60f9b..ebd9af1f1 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -308,121 +308,121 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used For complete details, refer to your provider's _Additional configuration_ link. -| Provider Name | Provider Code | Environment Variables | | -|----------------------------------------------------------------------------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| -| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | -| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | -| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) | -| [ArvanCloud](https://www.arvancloud.com/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) | -| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | -| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) | -| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | -| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | -| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | -| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) | -| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) | -| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) | -| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | -| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | -| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | -| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) | -| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) | -| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) | -| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | -| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | -| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) | -| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | -| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | -| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | -| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) | -| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) | -| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) | -| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) | -| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) | -| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) | -| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | -| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) | -| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) | -| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | -| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) | -| [G-Core Lab](https://gcorelabs.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) | -| [Gandi v5](https://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | -| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | -| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | -| [GoDaddy](https://www.godaddy.com) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | -| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | -| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) | -| [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) | -| [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) | -| [IIJ DNS Platform Service](https://www.iij.ad.jp) | `iijdpf` | `IIJ_DPF_API_TOKEN` , `IIJ_DPF_DPM_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iijdpf) | -| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | -| [Infoblox](https://www.infoblox.com/) | `infoblox` | `INFOBLOX_USERNAME`, `INFOBLOX_PASSWORD`, `INFOBLOX_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/infoblox) | -| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) | -| [Internet.bs](https://internetbs.net) | `internetbs` | `INTERNET_BS_API_KEY`, `INTERNET_BS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/internetbs) | -| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | -| [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) | -| [iwantmyname](https://iwantmyname.com) | `iwantmyname` | `IWANTMYNAME_USERNAME` , `IWANTMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/iwantmyname) | -| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | -| [Liara](https://liara.ir) | `liara` | `LIARA_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/liara) | -| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | -| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | -| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | -| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) | -| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) | -| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | -| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) | -| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) | -| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | -| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) | -| [NearlyFreeSpeech.NET](https://www.nearlyfreespeech.net/) | `nearlyfreespeech` | `NEARLYFREESPEECH_API_KEY`, `NEARLYFREESPEECH_LOGIN` | [Additional configuration](https://go-acme.github.io/lego/dns/nearlyfreespeech) | -| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) | -| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) | -| [Nicmanager](https://www.nicmanager.com) | `nicmanager` | `NICMANAGER_API_EMAIL`, `NICMANAGER_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/nicmanager) | -| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) | -| [Njalla](https://njal.la) | `njalla` | `NJALLA_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/njalla) | -| [NS1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) | -| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) | -| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) | -| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) | -| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) | -| [Porkbun](https://porkbun.com/) | `porkbun` | `PORKBUN_SECRET_API_KEY`, `PORKBUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/porkbun) | -| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) | -| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) | -| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) | -| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) | -| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) | -| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) | -| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) | -| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCALEWAY_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) | -| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | -| [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) | -| [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) | -| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) | -| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) | -| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) | -| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | -| [UKFast SafeDNS](https://www.ans.co.uk/cloud-and-infrastructure/dedicated-servers/dns-management/) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) | -| [Ultradns](https://neustarsecurityservices.com/dns-services) | `ultradns` | `ULTRADNS_USERNAME`, `ULTRADNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/ultradns) | -| [Variomedia](https://www.variomedia.de/) | `variomedia` | `VARIOMEDIA_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/variomedia) | -| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | -| [Vercel](https://vercel.com) | `vercel` | `VERCEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vercel) | -| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) | -| [VinylDNS](https://www.vinyldns.io) | `vinyldns` | `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, `VINYLDNS_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/vinyldns) | -| [VK Cloud](https://mcs.mail.ru/) | `vkcloud` | `VK_CLOUD_PASSWORD`, `VK_CLOUD_PROJECT_ID`, `VK_CLOUD_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/vkcloud) | -| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | -| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | -| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) | -| [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) | -| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) | -| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) | -| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) | -| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) | -| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) | -| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | -| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press Enter. | | +| Provider Name | Provider Code | Environment Variables | | +|--------------------------------------------------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | +| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | +| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) | +| [ArvanCloud](https://www.arvancloud.com/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) | +| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | +| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) | +| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | +| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | +| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | +| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) | +| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) | +| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) | +| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | +| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | +| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | +| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) | +| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) | +| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) | +| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | +| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | +| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) | +| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | +| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | +| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | +| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) | +| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) | +| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) | +| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) | +| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) | +| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) | +| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | +| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) | +| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) | +| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | +| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) | +| [G-Core Lab](https://gcorelabs.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) | +| [Gandi v5](https://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | +| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | +| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | +| [GoDaddy](https://www.godaddy.com) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | +| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | +| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) | +| [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) | +| [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) | +| [IIJ DNS Platform Service](https://www.iij.ad.jp) | `iijdpf` | `IIJ_DPF_API_TOKEN` , `IIJ_DPF_DPM_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iijdpf) | +| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | +| [Infoblox](https://www.infoblox.com/) | `infoblox` | `INFOBLOX_USERNAME`, `INFOBLOX_PASSWORD`, `INFOBLOX_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/infoblox) | +| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) | +| [Internet.bs](https://internetbs.net) | `internetbs` | `INTERNET_BS_API_KEY`, `INTERNET_BS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/internetbs) | +| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | +| [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) | +| [iwantmyname](https://iwantmyname.com) | `iwantmyname` | `IWANTMYNAME_USERNAME` , `IWANTMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/iwantmyname) | +| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | +| [Liara](https://liara.ir) | `liara` | `LIARA_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/liara) | +| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | +| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | +| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | +| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) | +| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) | +| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | +| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) | +| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) | +| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | +| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) | +| [NearlyFreeSpeech.NET](https://www.nearlyfreespeech.net/) | `nearlyfreespeech` | `NEARLYFREESPEECH_API_KEY`, `NEARLYFREESPEECH_LOGIN` | [Additional configuration](https://go-acme.github.io/lego/dns/nearlyfreespeech) | +| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) | +| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) | +| [Nicmanager](https://www.nicmanager.com) | `nicmanager` | `NICMANAGER_API_EMAIL`, `NICMANAGER_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/nicmanager) | +| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) | +| [Njalla](https://njal.la) | `njalla` | `NJALLA_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/njalla) | +| [NS1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) | +| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) | +| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) | +| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) | +| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) | +| [Porkbun](https://porkbun.com/) | `porkbun` | `PORKBUN_SECRET_API_KEY`, `PORKBUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/porkbun) | +| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) | +| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) | +| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) | +| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) | +| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) | +| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) | +| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) | +| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCALEWAY_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) | +| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | +| [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) | +| [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) | +| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) | +| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) | +| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) | +| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | +| [UKFast SafeDNS](https://docs.ukfast.co.uk/domains/safedns/index.html) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) | +| [Ultradns](https://neustarsecurityservices.com/dns-services) | `ultradns` | `ULTRADNS_USERNAME`, `ULTRADNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/ultradns) | +| [Variomedia](https://www.variomedia.de/) | `variomedia` | `VARIOMEDIA_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/variomedia) | +| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | +| [Vercel](https://vercel.com) | `vercel` | `VERCEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vercel) | +| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) | +| [VinylDNS](https://www.vinyldns.io) | `vinyldns` | `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, `VINYLDNS_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/vinyldns) | +| [VK Cloud](https://mcs.mail.ru/) | `vkcloud` | `VK_CLOUD_PASSWORD`, `VK_CLOUD_PROJECT_ID`, `VK_CLOUD_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/vkcloud) | +| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | +| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | +| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) | +| [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) | +| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) | +| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) | +| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) | +| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) | +| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) | +| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | +| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press Enter. | | [^1]: More information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/). [^2]: [Providing credentials to your application](https://cloud.google.com/docs/authentication/production). From ae65d5ff78586e90f9329ae8f1276ae378544b31 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 30 Mar 2023 12:10:05 +0200 Subject: [PATCH 05/14] Update Yaegi to v0.15.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b4310a3c8..97d2e00f4 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,7 @@ require ( github.com/stretchr/testify v1.8.1 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/traefik/paerser v0.2.0 - github.com/traefik/yaegi v0.15.0 + github.com/traefik/yaegi v0.15.1 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible github.com/unrolled/render v1.0.2 diff --git a/go.sum b/go.sum index e295ed62a..48465d616 100644 --- a/go.sum +++ b/go.sum @@ -1752,8 +1752,8 @@ github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305 h1:y/1cL5AL2oRcfz github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305/go.mod h1:gXOLibKqQTRAVuVZ9gX7G9Ykky8ll8yb4slxsEMoY0c= github.com/traefik/paerser v0.2.0 h1:zqCLGSXoNlcBd+mzqSCLjon/I6phqIjeJL2xFB2ysgQ= github.com/traefik/paerser v0.2.0/go.mod h1:afzaVcgF8A+MpTnPG4wBr4whjanCSYA6vK5RwaYVtRc= -github.com/traefik/yaegi v0.15.0 h1:ScDDfQXTT75rKvcsMcP84rOxHsZ8b6NiQJyGocGDB7g= -github.com/traefik/yaegi v0.15.0/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCiTds9p0= +github.com/traefik/yaegi v0.15.1 h1:YA5SbaL6HZA0Exh9T/oArRHqGN2HQ+zgmCY7dkoTXu4= +github.com/traefik/yaegi v0.15.1/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCiTds9p0= github.com/transip/gotransip/v6 v6.17.0 h1:2RCyqYqz5+Ej8z96EyE4sf6tQrrfEBaFDO0LliSl6+8= github.com/transip/gotransip/v6 v6.17.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= From be1b1a6489b625efec5cb7d1bfc99a4d08106eaf Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 3 Apr 2023 10:06:06 +0200 Subject: [PATCH 06/14] chore: update linter --- .github/workflows/validate.yaml | 2 +- .golangci.yml | 145 ++++-- .semaphore/semaphore.yml | 2 +- build.Dockerfile | 2 +- docs/scripts/verify.sh | 2 +- pkg/config/dynamic/http_config.go | 4 +- pkg/config/dynamic/middlewares.go | 2 +- pkg/config/dynamic/tcp_config.go | 2 +- pkg/config/dynamic/udp_config.go | 2 +- pkg/config/static/static_config.go | 26 +- pkg/muxer/tcp/mux.go | 13 +- .../kubernetes/crd/client-containous.go | 68 +-- pkg/provider/kubernetes/crd/client.go | 100 ++-- .../kubernetes/crd/client_mock_test.go | 64 +-- pkg/provider/kubernetes/crd/client_test.go | 4 +- pkg/provider/kubernetes/crd/kubernetes.go | 20 +- .../kubernetes/crd/kubernetes_http.go | 26 +- pkg/provider/kubernetes/crd/kubernetes_tcp.go | 10 +- .../kubernetes/crd/kubernetes_test.go | 65 ++- pkg/provider/kubernetes/crd/kubernetes_udp.go | 6 +- pkg/provider/kubernetes/crd/scheme.go | 48 +- .../traefikcontainous/v1alpha1/register.go | 8 +- .../crd/traefikio/v1alpha1/register.go | 8 +- pkg/provider/kubernetes/gateway/client.go | 93 ++-- .../kubernetes/gateway/client_mock_test.go | 48 +- .../kubernetes/gateway/client_test.go | 70 +-- pkg/provider/kubernetes/gateway/kubernetes.go | 208 ++++----- .../kubernetes/gateway/kubernetes_test.go | 438 +++++++++--------- .../ingress/builder_ingress_test.go | 36 +- pkg/provider/kubernetes/ingress/client.go | 88 ++-- .../kubernetes/ingress/client_mock_test.go | 26 +- .../kubernetes/ingress/client_test.go | 58 +-- pkg/provider/kubernetes/ingress/convert.go | 6 +- .../kubernetes/ingress/convert_test.go | 36 +- pkg/provider/kubernetes/ingress/kubernetes.go | 22 +- .../kubernetes/ingress/kubernetes_test.go | 4 +- .../kubernetes/k8s/event_handler_test.go | 10 +- pkg/provider/kubernetes/k8s/parser.go | 4 +- 38 files changed, 924 insertions(+), 852 deletions(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 69de25cf4..483085825 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -7,7 +7,7 @@ on: env: GO_VERSION: '1.20' - GOLANGCI_LINT_VERSION: v1.51.2 + GOLANGCI_LINT_VERSION: v1.52.2 MISSSPELL_VERSION: v0.4.0 IN_DOCKER: "" diff --git a/.golangci.yml b/.golangci.yml index 43065313c..cd0093d85 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,9 +6,10 @@ run: linters-settings: govet: - check-shadowing: false - golint: - min-confidence: 0 + enable-all: true + disable: + - shadow + - fieldalignment gocyclo: min-complexity: 14 goconst: @@ -33,40 +34,112 @@ linters-settings: keywords: - FIXME importas: - corev1: k8s.io/api/core/v1 - networkingv1beta1: k8s.io/api/networking/v1beta1 - extensionsv1beta1: k8s.io/api/extensions/v1beta1 - metav1: k8s.io/apimachinery/pkg/apis/meta/v1 - kubeerror: k8s.io/apimachinery/pkg/api/errors - composeapi: github.com/docker/compose/v2/pkg/api + no-unaliased: true + alias: + - alias: composeapi + pkg: github.com/docker/compose/v2/pkg/api + + # Standard Kubernetes rewrites: + - alias: corev1 + pkg: "k8s.io/api/core/v1" + - alias: netv1 + pkg: "k8s.io/api/networking/v1" + - alias: netv1beta1 + pkg: "k8s.io/api/networking/v1beta1" + - alias: admv1 + pkg: "k8s.io/api/admission/v1" + - alias: admv1beta1 + pkg: "k8s.io/api/admission/v1beta1" + - alias: extv1beta1 + pkg: "k8s.io/api/extensions/v1beta1" + - alias: metav1 + pkg: "k8s.io/apimachinery/pkg/apis/meta/v1" + - alias: ktypes + pkg: "k8s.io/apimachinery/pkg/types" + - alias: kerror + pkg: "k8s.io/apimachinery/pkg/api/errors" + - alias: kclientset + pkg: "k8s.io/client-go/kubernetes" + - alias: kinformers + pkg: "k8s.io/client-go/informers" + - alias: ktesting + pkg: "k8s.io/client-go/testing" + - alias: kschema + pkg: "k8s.io/apimachinery/pkg/runtime/schema" + - alias: kscheme + pkg: "k8s.io/client-go/kubernetes/scheme" + - alias: kversion + pkg: "k8s.io/apimachinery/pkg/version" + - alias: kubefake + pkg: "k8s.io/client-go/kubernetes/fake" + - alias: discoveryfake + pkg: "k8s.io/client-go/discovery/fake" + + # Kubernetes Gateway rewrites: + - alias: gateclientset + pkg: "sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned" + - alias: gateinformers + pkg: "sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions" + - alias: gatev1alpha2 + pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2" + + # Traefik Kubernetes rewrites: + - alias: containousv1alpha1 + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1" + - alias: traefikv1alpha1 + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + - alias: traefikclientset + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" + - alias: traefikinformers + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" + - alias: traefikscheme + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + - alias: traefikcrdfake + pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" + tagalign: + align: false + sort: true + order: + - description + - json + - toml + - yaml + - yml + - label + - label-slice-as-struct + - file + - kv + - export revive: rules: - name: struct-tag - rules: - - name: blank-imports - - name: context-as-argument - - name: context-keys-type - - name: dot-imports - - name: error-return - - name: error-strings - - name: error-naming - - name: exported - - name: if-return - - name: increment-decrement - - name: var-naming - - name: var-declaration - - name: package-comments - - name: range - - name: receiver-naming - - name: time-naming - - name: unexported-return - - name: indent-error-flow - - name: errorf - - name: empty-block - - name: superfluous-else - - name: unused-parameter - - name: unreachable-code - - name: redefines-builtin-id + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + disabled: true + - name: if-return + - name: increment-decrement + - name: var-naming + - name: var-declaration + - name: package-comments + disabled: true + - name: range + - name: receiver-naming + - name: time-naming + - name: unexported-return + - name: indent-error-flow + - name: errorf + - name: empty-block + - name: superfluous-else + - name: unused-parameter + disabled: true + - name: unreachable-code + - name: redefines-builtin-id gomoddirectives: replace-allow-list: - github.com/abbot/go-http-auth @@ -188,3 +261,7 @@ issues: text: 'Duplicate words \(sub\) found' linters: - dupword + - path: pkg/provider/kubernetes/gateway/client_mock_test.go + text: 'unusedwrite: unused write to field' + linters: + - govet diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 558c79b75..4244a52f7 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -25,7 +25,7 @@ global_job_config: - export "PATH=${GOPATH}/bin:${PATH}" - mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin" - export GOPROXY=https://proxy.golang.org,direct - - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.50.0 + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.52.2 - curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin" - checkout - cache restore traefik-$(checksum go.sum) diff --git a/build.Dockerfile b/build.Dockerfile index 6d4ba8625..ce037bbfd 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -13,7 +13,7 @@ RUN mkdir -p /usr/local/bin \ | tar -xzC /usr/local/bin --transform 's#^.+/##x' # Download golangci-lint binary to bin folder in $GOPATH -RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.50.0 +RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.52.2 # Download misspell binary to bin folder in $GOPATH RUN curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.4.0 diff --git a/docs/scripts/verify.sh b/docs/scripts/verify.sh index b3188c030..44835ce79 100755 --- a/docs/scripts/verify.sh +++ b/docs/scripts/verify.sh @@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \ --alt_ignore="/traefikproxy-vertical-logo-color.svg/" \ --http_status_ignore="0,500,501,503" \ --file_ignore="/404.html/" \ - --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/,/www.godaddy.com/" \ + --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/,/www.godaddy.com/,/internetbs.net/" \ '{}' 1>/dev/null ## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index 0fa03feba..db89e049b 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -199,8 +199,8 @@ type ResponseForwarding struct { // Server holds the server configuration. type Server struct { URL string `json:"url,omitempty" toml:"url,omitempty" yaml:"url,omitempty" label:"-"` - Scheme string `toml:"-" json:"-" yaml:"-" file:"-"` - Port string `toml:"-" json:"-" yaml:"-" file:"-"` + Scheme string `json:"-" toml:"-" yaml:"-" file:"-"` + Port string `json:"-" toml:"-" yaml:"-" file:"-"` } // SetDefaults Default values for a Server. diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index 9c6fb6610..c2ec1ba44 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -391,7 +391,7 @@ func (s *IPStrategy) Get() (ip.Strategy, error) { type IPWhiteList struct { // SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation). SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"` - IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` + IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/tcp_config.go b/pkg/config/dynamic/tcp_config.go index 0f986db46..2bd871d02 100644 --- a/pkg/config/dynamic/tcp_config.go +++ b/pkg/config/dynamic/tcp_config.go @@ -108,7 +108,7 @@ func (l *TCPServersLoadBalancer) Mergeable(loadBalancer *TCPServersLoadBalancer) // TCPServer holds a TCP Server configuration. type TCPServer struct { Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" label:"-"` - Port string `toml:"-" json:"-" yaml:"-"` + Port string `json:"-" toml:"-" yaml:"-"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/udp_config.go b/pkg/config/dynamic/udp_config.go index e6a711e86..9e601a2df 100644 --- a/pkg/config/dynamic/udp_config.go +++ b/pkg/config/dynamic/udp_config.go @@ -78,5 +78,5 @@ func (l *UDPServersLoadBalancer) Mergeable(loadBalancer *UDPServersLoadBalancer) // UDPServer defines a UDP server configuration. type UDPServer struct { Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" label:"-"` - Port string `toml:"-" json:"-" yaml:"-" file:"-"` + Port string `json:"-" toml:"-" yaml:"-" file:"-"` } diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index 11e36d8cd..8eb8e56cf 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -159,12 +159,12 @@ func (a *LifeCycle) SetDefaults() { type Tracing struct { ServiceName string `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"` SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." json:"spanNameLimit,omitempty" toml:"spanNameLimit,omitempty" yaml:"spanNameLimit,omitempty" export:"true"` - Jaeger *jaeger.Config `description:"Settings for Jaeger." json:"jaeger,omitempty" toml:"jaeger,omitempty" yaml:"jaeger,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Zipkin *zipkin.Config `description:"Settings for Zipkin." json:"zipkin,omitempty" toml:"zipkin,omitempty" yaml:"zipkin,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Datadog *datadog.Config `description:"Settings for Datadog." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Instana *instana.Config `description:"Settings for Instana." json:"instana,omitempty" toml:"instana,omitempty" yaml:"instana,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Haystack *haystack.Config `description:"Settings for Haystack." json:"haystack,omitempty" toml:"haystack,omitempty" yaml:"haystack,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Elastic *elastic.Config `description:"Settings for Elastic." json:"elastic,omitempty" toml:"elastic,omitempty" yaml:"elastic,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` + Jaeger *jaeger.Config `description:"Settings for Jaeger." json:"jaeger,omitempty" toml:"jaeger,omitempty" yaml:"jaeger,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Zipkin *zipkin.Config `description:"Settings for Zipkin." json:"zipkin,omitempty" toml:"zipkin,omitempty" yaml:"zipkin,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Datadog *datadog.Config `description:"Settings for Datadog." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Instana *instana.Config `description:"Settings for Instana." json:"instana,omitempty" toml:"instana,omitempty" yaml:"instana,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Haystack *haystack.Config `description:"Settings for Haystack." json:"haystack,omitempty" toml:"haystack,omitempty" yaml:"haystack,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Elastic *elastic.Config `description:"Settings for Elastic." json:"elastic,omitempty" toml:"elastic,omitempty" yaml:"elastic,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } // SetDefaults sets the default values. @@ -177,14 +177,14 @@ func (t *Tracing) SetDefaults() { type Providers struct { ProvidersThrottleDuration ptypes.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." json:"providersThrottleDuration,omitempty" toml:"providersThrottleDuration,omitempty" yaml:"providersThrottleDuration,omitempty" export:"true"` - Docker *docker.Provider `description:"Enable Docker backend with default settings." json:"docker,omitempty" toml:"docker,omitempty" yaml:"docker,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` + Docker *docker.Provider `description:"Enable Docker backend with default settings." json:"docker,omitempty" toml:"docker,omitempty" yaml:"docker,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` File *file.Provider `description:"Enable File backend with default settings." json:"file,omitempty" toml:"file,omitempty" yaml:"file,omitempty" export:"true"` - Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." json:"marathon,omitempty" toml:"marathon,omitempty" yaml:"marathon,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - KubernetesIngress *ingress.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesIngress,omitempty" toml:"kubernetesIngress,omitempty" yaml:"kubernetesIngress,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - KubernetesGateway *gateway.Provider `description:"Enable Kubernetes gateway api provider with default settings." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` + Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." json:"marathon,omitempty" toml:"marathon,omitempty" yaml:"marathon,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + KubernetesIngress *ingress.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesIngress,omitempty" toml:"kubernetesIngress,omitempty" yaml:"kubernetesIngress,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + KubernetesGateway *gateway.Provider `description:"Enable Kubernetes gateway api provider with default settings." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` ConsulCatalog *consulcatalog.ProviderBuilder `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Nomad *nomad.ProviderBuilder `description:"Enable Nomad backend with default settings." json:"nomad,omitempty" toml:"nomad,omitempty" yaml:"nomad,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` diff --git a/pkg/muxer/tcp/mux.go b/pkg/muxer/tcp/mux.go index 093c182d0..730a124c6 100644 --- a/pkg/muxer/tcp/mux.go +++ b/pkg/muxer/tcp/mux.go @@ -422,33 +422,30 @@ func preparePattern(template string) (string, error) { pattern := bytes.NewBufferString("") // Host SNI matching is case-insensitive - fmt.Fprint(pattern, "(?i)") + _, _ = fmt.Fprint(pattern, "(?i)") pattern.WriteByte('^') var end int - var err error for i := 0; i < len(idxs); i += 2 { // Set all values we are interested in. raw := template[end:idxs[i]] end = idxs[i+1] parts := strings.SplitN(template[idxs[i]+1:end-1], ":", 2) name := parts[0] + patt := defaultPattern if len(parts) == 2 { patt = parts[1] } + // Name or pattern can't be empty. if name == "" || patt == "" { return "", fmt.Errorf("mux: missing name or pattern in %q", template[idxs[i]:end]) } - // Build the regexp pattern. - fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt) - // Append variable name and compiled pattern. - if err != nil { - return "", err - } + // Build the regexp pattern. + _, _ = fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt) } // Add the remaining. diff --git a/pkg/provider/kubernetes/crd/client-containous.go b/pkg/provider/kubernetes/crd/client-containous.go index 6b2ba3ea4..fc9610e0f 100644 --- a/pkg/provider/kubernetes/crd/client-containous.go +++ b/pkg/provider/kubernetes/crd/client-containous.go @@ -4,15 +4,15 @@ import ( "fmt" "github.com/traefik/traefik/v2/pkg/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikscheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + traefikinformers "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" ) -func (c *clientWrapper) appendContainousIngressRoutes(result []*v1alpha1.IngressRoute) []*v1alpha1.IngressRoute { +func (c *clientWrapper) appendContainousIngressRoutes(result []*traefikv1alpha1.IngressRoute) []*traefikv1alpha1.IngressRoute { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -31,20 +31,20 @@ func (c *clientWrapper) appendContainousIngressRoutes(result []*v1alpha1.Ingress continue } - toVersion, err := scheme.Scheme.ConvertToVersion(ing, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(ing, GroupVersioner) if err != nil { log.Errorf("Failed to convert ingress route in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.IngressRoute)) + result = append(result, toVersion.(*traefikv1alpha1.IngressRoute)) } } return result } -func (c *clientWrapper) appendContainousIngressRouteTCPs(result []*v1alpha1.IngressRouteTCP) []*v1alpha1.IngressRouteTCP { +func (c *clientWrapper) appendContainousIngressRouteTCPs(result []*traefikv1alpha1.IngressRouteTCP) []*traefikv1alpha1.IngressRouteTCP { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -63,20 +63,20 @@ func (c *clientWrapper) appendContainousIngressRouteTCPs(result []*v1alpha1.Ingr continue } - toVersion, err := scheme.Scheme.ConvertToVersion(ing, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(ing, GroupVersioner) if err != nil { log.Errorf("Failed to convert tcp ingress route in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.IngressRouteTCP)) + result = append(result, toVersion.(*traefikv1alpha1.IngressRouteTCP)) } } return result } -func (c *clientWrapper) appendContainousIngressRouteUDPs(result []*v1alpha1.IngressRouteUDP) []*v1alpha1.IngressRouteUDP { +func (c *clientWrapper) appendContainousIngressRouteUDPs(result []*traefikv1alpha1.IngressRouteUDP) []*traefikv1alpha1.IngressRouteUDP { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -95,20 +95,20 @@ func (c *clientWrapper) appendContainousIngressRouteUDPs(result []*v1alpha1.Ingr continue } - toVersion, err := scheme.Scheme.ConvertToVersion(ing, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(ing, GroupVersioner) if err != nil { log.Errorf("Failed to convert udp ingress route in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.IngressRouteUDP)) + result = append(result, toVersion.(*traefikv1alpha1.IngressRouteUDP)) } } return result } -func (c *clientWrapper) appendContainousMiddlewares(result []*v1alpha1.Middleware) []*v1alpha1.Middleware { +func (c *clientWrapper) appendContainousMiddlewares(result []*traefikv1alpha1.Middleware) []*traefikv1alpha1.Middleware { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -127,20 +127,20 @@ func (c *clientWrapper) appendContainousMiddlewares(result []*v1alpha1.Middlewar continue } - toVersion, err := scheme.Scheme.ConvertToVersion(middleware, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(middleware, GroupVersioner) if err != nil { log.Errorf("Failed to convert middleware in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.Middleware)) + result = append(result, toVersion.(*traefikv1alpha1.Middleware)) } } return result } -func (c *clientWrapper) appendContainousMiddlewareTCPs(result []*v1alpha1.MiddlewareTCP) []*v1alpha1.MiddlewareTCP { +func (c *clientWrapper) appendContainousMiddlewareTCPs(result []*traefikv1alpha1.MiddlewareTCP) []*traefikv1alpha1.MiddlewareTCP { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -159,20 +159,20 @@ func (c *clientWrapper) appendContainousMiddlewareTCPs(result []*v1alpha1.Middle continue } - toVersion, err := scheme.Scheme.ConvertToVersion(middleware, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(middleware, GroupVersioner) if err != nil { log.Errorf("Failed to convert tcp middleware in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.MiddlewareTCP)) + result = append(result, toVersion.(*traefikv1alpha1.MiddlewareTCP)) } } return result } -func (c *clientWrapper) appendContainousTraefikServices(result []*v1alpha1.TraefikService) []*v1alpha1.TraefikService { +func (c *clientWrapper) appendContainousTraefikServices(result []*traefikv1alpha1.TraefikService) []*traefikv1alpha1.TraefikService { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -191,20 +191,20 @@ func (c *clientWrapper) appendContainousTraefikServices(result []*v1alpha1.Traef continue } - toVersion, err := scheme.Scheme.ConvertToVersion(traefikService, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(traefikService, GroupVersioner) if err != nil { log.Errorf("Failed to convert Traefik service in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.TraefikService)) + result = append(result, toVersion.(*traefikv1alpha1.TraefikService)) } } return result } -func (c *clientWrapper) appendContainousServersTransport(result []*v1alpha1.ServersTransport) []*v1alpha1.ServersTransport { +func (c *clientWrapper) appendContainousServersTransport(result []*traefikv1alpha1.ServersTransport) []*traefikv1alpha1.ServersTransport { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -223,20 +223,20 @@ func (c *clientWrapper) appendContainousServersTransport(result []*v1alpha1.Serv continue } - toVersion, err := scheme.Scheme.ConvertToVersion(serversTransport, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(serversTransport, GroupVersioner) if err != nil { log.Errorf("Failed to convert servers transport in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.ServersTransport)) + result = append(result, toVersion.(*traefikv1alpha1.ServersTransport)) } } return result } -func (c *clientWrapper) appendContainousTLSOptions(result []*v1alpha1.TLSOption) []*v1alpha1.TLSOption { +func (c *clientWrapper) appendContainousTLSOptions(result []*traefikv1alpha1.TLSOption) []*traefikv1alpha1.TLSOption { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -255,20 +255,20 @@ func (c *clientWrapper) appendContainousTLSOptions(result []*v1alpha1.TLSOption) continue } - toVersion, err := scheme.Scheme.ConvertToVersion(option, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(option, GroupVersioner) if err != nil { log.Errorf("Failed to convert tls option in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.TLSOption)) + result = append(result, toVersion.(*traefikv1alpha1.TLSOption)) } } return result } -func (c *clientWrapper) appendContainousTLSStores(result []*v1alpha1.TLSStore) []*v1alpha1.TLSStore { +func (c *clientWrapper) appendContainousTLSStores(result []*traefikv1alpha1.TLSStore) []*traefikv1alpha1.TLSStore { listed := map[string]struct{}{} for _, obj := range result { listed[objectKey(obj.ObjectMeta)] = struct{}{} @@ -287,20 +287,20 @@ func (c *clientWrapper) appendContainousTLSStores(result []*v1alpha1.TLSStore) [ continue } - toVersion, err := scheme.Scheme.ConvertToVersion(store, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(store, GroupVersioner) if err != nil { log.Errorf("Failed to convert tls store in namespace %s: %v", ns, err) continue } - result = append(result, toVersion.(*v1alpha1.TLSStore)) + result = append(result, toVersion.(*traefikv1alpha1.TLSStore)) } } return result } -func (c *clientWrapper) getContainousTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error) { +func (c *clientWrapper) getContainousTraefikService(namespace, name string) (*traefikv1alpha1.TraefikService, bool, error) { if !c.isWatchedNamespace(namespace) { return nil, false, fmt.Errorf("failed to get service %s/%s: namespace is not within watched namespaces", namespace, name) } @@ -312,15 +312,15 @@ func (c *clientWrapper) getContainousTraefikService(namespace, name string) (*v1 return nil, false, err } - toVersion, err := scheme.Scheme.ConvertToVersion(service, GroupVersioner) + toVersion, err := traefikscheme.Scheme.ConvertToVersion(service, GroupVersioner) if err != nil { log.Errorf("Failed to convert Traefik service in namespace %s: %v", namespace, err) } - return toVersion.(*v1alpha1.TraefikService), exist, err + return toVersion.(*traefikv1alpha1.TraefikService), exist, err } -func addContainousInformers(factoryCrd externalversions.SharedInformerFactory, eventHandler *k8s.ResourceEventHandler) error { +func addContainousInformers(factoryCrd traefikinformers.SharedInformerFactory, eventHandler *k8s.ResourceEventHandler) error { _, err := factoryCrd.TraefikContainous().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) if err != nil { return err diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 9586a18fa..c678db966 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -9,17 +9,17 @@ import ( "time" "github.com/traefik/traefik/v2/pkg/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikclientset "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" + traefikinformers "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" "github.com/traefik/traefik/v2/pkg/version" corev1 "k8s.io/api/core/v1" - kubeerror "k8s.io/apimachinery/pkg/api/errors" + kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/informers" - "k8s.io/client-go/kubernetes" + kinformers "k8s.io/client-go/informers" + kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -31,16 +31,16 @@ const resyncPeriod = 10 * time.Minute // The stores can then be accessed via the Get* functions. type Client interface { WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) - GetIngressRoutes() []*v1alpha1.IngressRoute - GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP - GetIngressRouteUDPs() []*v1alpha1.IngressRouteUDP - GetMiddlewares() []*v1alpha1.Middleware - GetMiddlewareTCPs() []*v1alpha1.MiddlewareTCP - GetTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error) - GetTraefikServices() []*v1alpha1.TraefikService - GetTLSOptions() []*v1alpha1.TLSOption - GetServersTransports() []*v1alpha1.ServersTransport - GetTLSStores() []*v1alpha1.TLSStore + GetIngressRoutes() []*traefikv1alpha1.IngressRoute + GetIngressRouteTCPs() []*traefikv1alpha1.IngressRouteTCP + GetIngressRouteUDPs() []*traefikv1alpha1.IngressRouteUDP + GetMiddlewares() []*traefikv1alpha1.Middleware + GetMiddlewareTCPs() []*traefikv1alpha1.MiddlewareTCP + GetTraefikService(namespace, name string) (*traefikv1alpha1.TraefikService, bool, error) + GetTraefikServices() []*traefikv1alpha1.TraefikService + GetTLSOptions() []*traefikv1alpha1.TLSOption + GetServersTransports() []*traefikv1alpha1.ServersTransport + GetTLSStores() []*traefikv1alpha1.TLSStore GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) @@ -48,12 +48,12 @@ type Client interface { // TODO: add tests for the clientWrapper (and its methods) itself. type clientWrapper struct { - csCrd versioned.Interface - csKube kubernetes.Interface + csCrd traefikclientset.Interface + csKube kclientset.Interface - factoriesCrd map[string]externalversions.SharedInformerFactory - factoriesKube map[string]informers.SharedInformerFactory - factoriesSecret map[string]informers.SharedInformerFactory + factoriesCrd map[string]traefikinformers.SharedInformerFactory + factoriesKube map[string]kinformers.SharedInformerFactory + factoriesSecret map[string]kinformers.SharedInformerFactory labelSelector string @@ -70,12 +70,12 @@ func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { runtime.GOARCH, ) - csCrd, err := versioned.NewForConfig(c) + csCrd, err := traefikclientset.NewForConfig(c) if err != nil { return nil, err } - csKube, err := kubernetes.NewForConfig(c) + csKube, err := kclientset.NewForConfig(c) if err != nil { return nil, err } @@ -83,13 +83,13 @@ func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { return newClientImpl(csKube, csCrd), nil } -func newClientImpl(csKube kubernetes.Interface, csCrd versioned.Interface) *clientWrapper { +func newClientImpl(csKube kclientset.Interface, csCrd traefikclientset.Interface) *clientWrapper { return &clientWrapper{ csCrd: csCrd, csKube: csKube, - factoriesCrd: make(map[string]externalversions.SharedInformerFactory), - factoriesKube: make(map[string]informers.SharedInformerFactory), - factoriesSecret: make(map[string]informers.SharedInformerFactory), + factoriesCrd: make(map[string]traefikinformers.SharedInformerFactory), + factoriesKube: make(map[string]kinformers.SharedInformerFactory), + factoriesSecret: make(map[string]kinformers.SharedInformerFactory), } } @@ -162,7 +162,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } for _, ns := range namespaces { - factoryCrd := externalversions.NewSharedInformerFactoryWithOptions(c.csCrd, resyncPeriod, externalversions.WithNamespace(ns), externalversions.WithTweakListOptions(matchesLabelSelector)) + factoryCrd := traefikinformers.NewSharedInformerFactoryWithOptions(c.csCrd, resyncPeriod, traefikinformers.WithNamespace(ns), traefikinformers.WithTweakListOptions(matchesLabelSelector)) _, err := factoryCrd.Traefik().V1alpha1().IngressRoutes().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -205,7 +205,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< return nil, err } - factoryKube := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns)) + factoryKube := kinformers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, kinformers.WithNamespace(ns)) _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -215,7 +215,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< return nil, err } - factorySecret := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) + factorySecret := kinformers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, kinformers.WithNamespace(ns), kinformers.WithTweakListOptions(notOwnedByHelm)) _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -255,8 +255,8 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< return eventCh, nil } -func (c *clientWrapper) GetIngressRoutes() []*v1alpha1.IngressRoute { - var result []*v1alpha1.IngressRoute +func (c *clientWrapper) GetIngressRoutes() []*traefikv1alpha1.IngressRoute { + var result []*traefikv1alpha1.IngressRoute for ns, factory := range c.factoriesCrd { ings, err := factory.Traefik().V1alpha1().IngressRoutes().Lister().List(labels.Everything()) @@ -269,8 +269,8 @@ func (c *clientWrapper) GetIngressRoutes() []*v1alpha1.IngressRoute { return c.appendContainousIngressRoutes(result) } -func (c *clientWrapper) GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP { - var result []*v1alpha1.IngressRouteTCP +func (c *clientWrapper) GetIngressRouteTCPs() []*traefikv1alpha1.IngressRouteTCP { + var result []*traefikv1alpha1.IngressRouteTCP for ns, factory := range c.factoriesCrd { ings, err := factory.Traefik().V1alpha1().IngressRouteTCPs().Lister().List(labels.Everything()) @@ -283,8 +283,8 @@ func (c *clientWrapper) GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP { return c.appendContainousIngressRouteTCPs(result) } -func (c *clientWrapper) GetIngressRouteUDPs() []*v1alpha1.IngressRouteUDP { - var result []*v1alpha1.IngressRouteUDP +func (c *clientWrapper) GetIngressRouteUDPs() []*traefikv1alpha1.IngressRouteUDP { + var result []*traefikv1alpha1.IngressRouteUDP for ns, factory := range c.factoriesCrd { ings, err := factory.Traefik().V1alpha1().IngressRouteUDPs().Lister().List(labels.Everything()) @@ -297,8 +297,8 @@ func (c *clientWrapper) GetIngressRouteUDPs() []*v1alpha1.IngressRouteUDP { return c.appendContainousIngressRouteUDPs(result) } -func (c *clientWrapper) GetMiddlewares() []*v1alpha1.Middleware { - var result []*v1alpha1.Middleware +func (c *clientWrapper) GetMiddlewares() []*traefikv1alpha1.Middleware { + var result []*traefikv1alpha1.Middleware for ns, factory := range c.factoriesCrd { middlewares, err := factory.Traefik().V1alpha1().Middlewares().Lister().List(labels.Everything()) @@ -311,8 +311,8 @@ func (c *clientWrapper) GetMiddlewares() []*v1alpha1.Middleware { return c.appendContainousMiddlewares(result) } -func (c *clientWrapper) GetMiddlewareTCPs() []*v1alpha1.MiddlewareTCP { - var result []*v1alpha1.MiddlewareTCP +func (c *clientWrapper) GetMiddlewareTCPs() []*traefikv1alpha1.MiddlewareTCP { + var result []*traefikv1alpha1.MiddlewareTCP for ns, factory := range c.factoriesCrd { middlewares, err := factory.Traefik().V1alpha1().MiddlewareTCPs().Lister().List(labels.Everything()) @@ -326,7 +326,7 @@ func (c *clientWrapper) GetMiddlewareTCPs() []*v1alpha1.MiddlewareTCP { } // GetTraefikService returns the named service from the given namespace. -func (c *clientWrapper) GetTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error) { +func (c *clientWrapper) GetTraefikService(namespace, name string) (*traefikv1alpha1.TraefikService, bool, error) { if !c.isWatchedNamespace(namespace) { return nil, false, fmt.Errorf("failed to get service %s/%s: namespace is not within watched namespaces", namespace, name) } @@ -341,8 +341,8 @@ func (c *clientWrapper) GetTraefikService(namespace, name string) (*v1alpha1.Tra return service, exist, err } -func (c *clientWrapper) GetTraefikServices() []*v1alpha1.TraefikService { - var result []*v1alpha1.TraefikService +func (c *clientWrapper) GetTraefikServices() []*traefikv1alpha1.TraefikService { + var result []*traefikv1alpha1.TraefikService for ns, factory := range c.factoriesCrd { traefikServices, err := factory.Traefik().V1alpha1().TraefikServices().Lister().List(labels.Everything()) @@ -356,8 +356,8 @@ func (c *clientWrapper) GetTraefikServices() []*v1alpha1.TraefikService { } // GetServersTransports returns all ServersTransport. -func (c *clientWrapper) GetServersTransports() []*v1alpha1.ServersTransport { - var result []*v1alpha1.ServersTransport +func (c *clientWrapper) GetServersTransports() []*traefikv1alpha1.ServersTransport { + var result []*traefikv1alpha1.ServersTransport for ns, factory := range c.factoriesCrd { serversTransports, err := factory.Traefik().V1alpha1().ServersTransports().Lister().List(labels.Everything()) @@ -371,8 +371,8 @@ func (c *clientWrapper) GetServersTransports() []*v1alpha1.ServersTransport { } // GetTLSOptions returns all TLS options. -func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption { - var result []*v1alpha1.TLSOption +func (c *clientWrapper) GetTLSOptions() []*traefikv1alpha1.TLSOption { + var result []*traefikv1alpha1.TLSOption for ns, factory := range c.factoriesCrd { options, err := factory.Traefik().V1alpha1().TLSOptions().Lister().List(labels.Everything()) @@ -386,8 +386,8 @@ func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption { } // GetTLSStores returns all TLS stores. -func (c *clientWrapper) GetTLSStores() []*v1alpha1.TLSStore { - var result []*v1alpha1.TLSStore +func (c *clientWrapper) GetTLSStores() []*traefikv1alpha1.TLSStore { + var result []*traefikv1alpha1.TLSStore for ns, factory := range c.factoriesCrd { stores, err := factory.Traefik().V1alpha1().TLSStores().Lister().List(labels.Everything()) @@ -463,7 +463,7 @@ func (c *clientWrapper) isWatchedNamespace(ns string) bool { // translateNotFoundError will translate a "not found" error to a boolean return // value which indicates if the resource exists and a nil error. func translateNotFoundError(err error) (bool, error) { - if kubeerror.IsNotFound(err) { + if kerror.IsNotFound(err) { return false, nil } return err == nil, err diff --git a/pkg/provider/kubernetes/crd/client_mock_test.go b/pkg/provider/kubernetes/crd/client_mock_test.go index 221ba61fc..b80b9f0e1 100644 --- a/pkg/provider/kubernetes/crd/client_mock_test.go +++ b/pkg/provider/kubernetes/crd/client_mock_test.go @@ -5,17 +5,17 @@ import ( "os" "path/filepath" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes/scheme" + kscheme "k8s.io/client-go/kubernetes/scheme" ) var _ Client = (*clientMock)(nil) func init() { // required by k8s.MustParseYaml - err := v1alpha1.AddToScheme(scheme.Scheme) + err := traefikv1alpha1.AddToScheme(kscheme.Scheme) if err != nil { panic(err) } @@ -30,15 +30,15 @@ type clientMock struct { apiSecretError error apiEndpointsError error - ingressRoutes []*v1alpha1.IngressRoute - ingressRouteTCPs []*v1alpha1.IngressRouteTCP - ingressRouteUDPs []*v1alpha1.IngressRouteUDP - middlewares []*v1alpha1.Middleware - middlewareTCPs []*v1alpha1.MiddlewareTCP - tlsOptions []*v1alpha1.TLSOption - tlsStores []*v1alpha1.TLSStore - traefikServices []*v1alpha1.TraefikService - serversTransport []*v1alpha1.ServersTransport + ingressRoutes []*traefikv1alpha1.IngressRoute + ingressRouteTCPs []*traefikv1alpha1.IngressRouteTCP + ingressRouteUDPs []*traefikv1alpha1.IngressRouteUDP + middlewares []*traefikv1alpha1.Middleware + middlewareTCPs []*traefikv1alpha1.MiddlewareTCP + tlsOptions []*traefikv1alpha1.TLSOption + tlsStores []*traefikv1alpha1.TLSStore + traefikServices []*traefikv1alpha1.TraefikService + serversTransport []*traefikv1alpha1.ServersTransport watchChan chan interface{} } @@ -59,23 +59,23 @@ func newClientMock(paths ...string) clientMock { c.services = append(c.services, o) case *corev1.Endpoints: c.endpoints = append(c.endpoints, o) - case *v1alpha1.IngressRoute: + case *traefikv1alpha1.IngressRoute: c.ingressRoutes = append(c.ingressRoutes, o) - case *v1alpha1.IngressRouteTCP: + case *traefikv1alpha1.IngressRouteTCP: c.ingressRouteTCPs = append(c.ingressRouteTCPs, o) - case *v1alpha1.IngressRouteUDP: + case *traefikv1alpha1.IngressRouteUDP: c.ingressRouteUDPs = append(c.ingressRouteUDPs, o) - case *v1alpha1.Middleware: + case *traefikv1alpha1.Middleware: c.middlewares = append(c.middlewares, o) - case *v1alpha1.MiddlewareTCP: + case *traefikv1alpha1.MiddlewareTCP: c.middlewareTCPs = append(c.middlewareTCPs, o) - case *v1alpha1.TraefikService: + case *traefikv1alpha1.TraefikService: c.traefikServices = append(c.traefikServices, o) - case *v1alpha1.TLSOption: + case *traefikv1alpha1.TLSOption: c.tlsOptions = append(c.tlsOptions, o) - case *v1alpha1.ServersTransport: + case *traefikv1alpha1.ServersTransport: c.serversTransport = append(c.serversTransport, o) - case *v1alpha1.TLSStore: + case *traefikv1alpha1.TLSStore: c.tlsStores = append(c.tlsStores, o) case *corev1.Secret: c.secrets = append(c.secrets, o) @@ -88,27 +88,27 @@ func newClientMock(paths ...string) clientMock { return c } -func (c clientMock) GetIngressRoutes() []*v1alpha1.IngressRoute { +func (c clientMock) GetIngressRoutes() []*traefikv1alpha1.IngressRoute { return c.ingressRoutes } -func (c clientMock) GetIngressRouteTCPs() []*v1alpha1.IngressRouteTCP { +func (c clientMock) GetIngressRouteTCPs() []*traefikv1alpha1.IngressRouteTCP { return c.ingressRouteTCPs } -func (c clientMock) GetIngressRouteUDPs() []*v1alpha1.IngressRouteUDP { +func (c clientMock) GetIngressRouteUDPs() []*traefikv1alpha1.IngressRouteUDP { return c.ingressRouteUDPs } -func (c clientMock) GetMiddlewares() []*v1alpha1.Middleware { +func (c clientMock) GetMiddlewares() []*traefikv1alpha1.Middleware { return c.middlewares } -func (c clientMock) GetMiddlewareTCPs() []*v1alpha1.MiddlewareTCP { +func (c clientMock) GetMiddlewareTCPs() []*traefikv1alpha1.MiddlewareTCP { return c.middlewareTCPs } -func (c clientMock) GetTraefikService(namespace, name string) (*v1alpha1.TraefikService, bool, error) { +func (c clientMock) GetTraefikService(namespace, name string) (*traefikv1alpha1.TraefikService, bool, error) { for _, svc := range c.traefikServices { if svc.Namespace == namespace && svc.Name == name { return svc, true, nil @@ -118,23 +118,23 @@ func (c clientMock) GetTraefikService(namespace, name string) (*v1alpha1.Traefik return nil, false, nil } -func (c clientMock) GetTraefikServices() []*v1alpha1.TraefikService { +func (c clientMock) GetTraefikServices() []*traefikv1alpha1.TraefikService { return c.traefikServices } -func (c clientMock) GetTLSOptions() []*v1alpha1.TLSOption { +func (c clientMock) GetTLSOptions() []*traefikv1alpha1.TLSOption { return c.tlsOptions } -func (c clientMock) GetTLSStores() []*v1alpha1.TLSStore { +func (c clientMock) GetTLSStores() []*traefikv1alpha1.TLSStore { return c.tlsStores } -func (c clientMock) GetServersTransports() []*v1alpha1.ServersTransport { +func (c clientMock) GetServersTransports() []*traefikv1alpha1.ServersTransport { return c.serversTransport } -func (c clientMock) GetTLSOption(namespace, name string) (*v1alpha1.TLSOption, bool, error) { +func (c clientMock) GetTLSOption(namespace, name string) (*traefikv1alpha1.TLSOption, bool, error) { for _, option := range c.tlsOptions { if option.Namespace == namespace && option.Name == name { return option, true, nil diff --git a/pkg/provider/kubernetes/crd/client_test.go b/pkg/provider/kubernetes/crd/client_test.go index 42aa574ee..09e127671 100644 --- a/pkg/provider/kubernetes/crd/client_test.go +++ b/pkg/provider/kubernetes/crd/client_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - crdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" + traefikcrdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubefake "k8s.io/client-go/kubernetes/fake" @@ -30,7 +30,7 @@ func TestClientIgnoresHelmOwnedSecrets(t *testing.T) { } kubeClient := kubefake.NewSimpleClientset(helmSecret, secret) - crdClient := crdfake.NewSimpleClientset() + crdClient := traefikcrdfake.NewSimpleClientset() client := newClientImpl(kubeClient, crdClient) diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 2e3ab3781..9a9aec188 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -24,7 +24,7 @@ import ( "github.com/traefik/traefik/v2/pkg/job" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/safe" "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/types" @@ -521,7 +521,7 @@ func getSecretValue(c Client, ns, urn string) (string, error) { return string(secretValue), nil } -func createCircuitBreakerMiddleware(circuitBreaker *v1alpha1.CircuitBreaker) (*dynamic.CircuitBreaker, error) { +func createCircuitBreakerMiddleware(circuitBreaker *traefikv1alpha1.CircuitBreaker) (*dynamic.CircuitBreaker, error) { if circuitBreaker == nil { return nil, nil } @@ -550,7 +550,7 @@ func createCircuitBreakerMiddleware(circuitBreaker *v1alpha1.CircuitBreaker) (*d return cb, nil } -func createRateLimitMiddleware(rateLimit *v1alpha1.RateLimit) (*dynamic.RateLimit, error) { +func createRateLimitMiddleware(rateLimit *traefikv1alpha1.RateLimit) (*dynamic.RateLimit, error) { if rateLimit == nil { return nil, nil } @@ -576,7 +576,7 @@ func createRateLimitMiddleware(rateLimit *v1alpha1.RateLimit) (*dynamic.RateLimi return rl, nil } -func createRetryMiddleware(retry *v1alpha1.Retry) (*dynamic.Retry, error) { +func createRetryMiddleware(retry *traefikv1alpha1.Retry) (*dynamic.Retry, error) { if retry == nil { return nil, nil } @@ -591,7 +591,7 @@ func createRetryMiddleware(retry *v1alpha1.Retry) (*dynamic.Retry, error) { return r, nil } -func (p *Provider) createErrorPageMiddleware(client Client, namespace string, errorPage *v1alpha1.ErrorPage) (*dynamic.ErrorPage, *dynamic.Service, error) { +func (p *Provider) createErrorPageMiddleware(client Client, namespace string, errorPage *traefikv1alpha1.ErrorPage) (*dynamic.ErrorPage, *dynamic.Service, error) { if errorPage == nil { return nil, nil, nil } @@ -616,7 +616,7 @@ func (p *Provider) createErrorPageMiddleware(client Client, namespace string, er return errorPageMiddleware, balancerServerHTTP, nil } -func createForwardAuthMiddleware(k8sClient Client, namespace string, auth *v1alpha1.ForwardAuth) (*dynamic.ForwardAuth, error) { +func createForwardAuthMiddleware(k8sClient Client, namespace string, auth *traefikv1alpha1.ForwardAuth) (*dynamic.ForwardAuth, error) { if auth == nil { return nil, nil } @@ -708,7 +708,7 @@ func loadAuthTLSSecret(namespace, secretName string, k8sClient Client) (string, return getCertificateBlocks(secret, namespace, secretName) } -func createBasicAuthMiddleware(client Client, namespace string, basicAuth *v1alpha1.BasicAuth) (*dynamic.BasicAuth, error) { +func createBasicAuthMiddleware(client Client, namespace string, basicAuth *traefikv1alpha1.BasicAuth) (*dynamic.BasicAuth, error) { if basicAuth == nil { return nil, nil } @@ -755,7 +755,7 @@ func createBasicAuthMiddleware(client Client, namespace string, basicAuth *v1alp }, nil } -func createDigestAuthMiddleware(client Client, namespace string, digestAuth *v1alpha1.DigestAuth) (*dynamic.DigestAuth, error) { +func createDigestAuthMiddleware(client Client, namespace string, digestAuth *traefikv1alpha1.DigestAuth) (*dynamic.DigestAuth, error) { if digestAuth == nil { return nil, nil } @@ -830,7 +830,7 @@ func loadAuthCredentials(secret *corev1.Secret) ([]string, error) { return credentials, nil } -func createChainMiddleware(ctx context.Context, namespace string, chain *v1alpha1.Chain) *dynamic.Chain { +func createChainMiddleware(ctx context.Context, namespace string, chain *traefikv1alpha1.Chain) *dynamic.Chain { if chain == nil { return nil } @@ -996,7 +996,7 @@ func buildTLSStores(ctx context.Context, client Client) (map[string]tls.Store, m } // buildCertificates loads TLSStore certificates from secrets and sets them into tlsConfigs. -func buildCertificates(client Client, tlsStore, namespace string, certificates []v1alpha1.Certificate, tlsConfigs map[string]*tls.CertAndStores) error { +func buildCertificates(client Client, tlsStore, namespace string, certificates []traefikv1alpha1.Certificate, tlsConfigs map[string]*tls.CertAndStores) error { for _, c := range certificates { configKey := namespace + "/" + c.SecretName if _, tlsExists := tlsConfigs[configKey]; !tlsExists { diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index ba8314584..9425915c8 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -11,7 +11,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/tls" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -84,8 +84,8 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli serviceName := normalized if len(route.Services) > 1 { - spec := v1alpha1.TraefikServiceSpec{ - Weighted: &v1alpha1.WeightedRoundRobin{ + spec := traefikv1alpha1.TraefikServiceSpec{ + Weighted: &traefikv1alpha1.WeightedRoundRobin{ Services: route.Services, }, } @@ -155,7 +155,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli return conf } -func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace string, middlewares []v1alpha1.MiddlewareRef) ([]string, error) { +func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace string, middlewares []traefikv1alpha1.MiddlewareRef) ([]string, error) { var mds []string for _, mi := range middlewares { @@ -203,7 +203,7 @@ type configBuilder struct { // buildTraefikService creates the configuration for the traefik service defined in tService, // and adds it to the given conf map. -func (c configBuilder) buildTraefikService(ctx context.Context, tService *v1alpha1.TraefikService, conf map[string]*dynamic.Service) error { +func (c configBuilder) buildTraefikService(ctx context.Context, tService *traefikv1alpha1.TraefikService, conf map[string]*dynamic.Service) error { id := provider.Normalize(makeID(tService.Namespace, tService.Name)) if tService.Spec.Weighted != nil { @@ -217,7 +217,7 @@ func (c configBuilder) buildTraefikService(ctx context.Context, tService *v1alph // buildServicesLB creates the configuration for the load-balancer of services named id, and defined in tService. // It adds it to the given conf map. -func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tService v1alpha1.TraefikServiceSpec, id string, conf map[string]*dynamic.Service) error { +func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tService traefikv1alpha1.TraefikServiceSpec, id string, conf map[string]*dynamic.Service) error { var wrrServices []dynamic.WRRService for _, service := range tService.Weighted.Services { @@ -252,7 +252,7 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS // buildMirroring creates the configuration for the mirroring service named id, and defined by tService. // It adds it to the given conf map. -func (c configBuilder) buildMirroring(ctx context.Context, tService *v1alpha1.TraefikService, id string, conf map[string]*dynamic.Service) error { +func (c configBuilder) buildMirroring(ctx context.Context, tService *traefikv1alpha1.TraefikService, id string, conf map[string]*dynamic.Service) error { fullNameMain, k8sService, err := c.nameAndService(ctx, tService.Namespace, tService.Spec.Mirroring.LoadBalancerSpec) if err != nil { return err @@ -291,7 +291,7 @@ func (c configBuilder) buildMirroring(ctx context.Context, tService *v1alpha1.Tr } // buildServersLB creates the configuration for the load-balancer of servers defined by svc. -func (c configBuilder) buildServersLB(namespace string, svc v1alpha1.LoadBalancerSpec) (*dynamic.Service, error) { +func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.LoadBalancerSpec) (*dynamic.Service, error) { servers, err := c.loadServers(namespace, svc) if err != nil { return nil, err @@ -338,7 +338,7 @@ func (c *configBuilder) makeServersTransportKey(parentNamespace string, serversT return provider.Normalize(makeID(parentNamespace, serversTransportName)), nil } -func (c configBuilder) loadServers(parentNamespace string, svc v1alpha1.LoadBalancerSpec) ([]dynamic.Server, error) { +func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.LoadBalancerSpec) ([]dynamic.Server, error) { strategy := svc.Strategy if strategy == "" { strategy = roundRobinStrategy @@ -446,7 +446,7 @@ func (c configBuilder) loadServers(parentNamespace string, svc v1alpha1.LoadBala // In addition, if the service is a Kubernetes one, // it generates and returns the configuration part for such a service, // so that the caller can add it to the global config map. -func (c configBuilder) nameAndService(ctx context.Context, parentNamespace string, service v1alpha1.LoadBalancerSpec) (string, *dynamic.Service, error) { +func (c configBuilder) nameAndService(ctx context.Context, parentNamespace string, service traefikv1alpha1.LoadBalancerSpec) (string, *dynamic.Service, error) { svcCtx := log.With(ctx, log.Str(log.ServiceName, service.Name)) namespace := namespaceOrFallback(service, parentNamespace) @@ -481,7 +481,7 @@ func splitSvcNameProvider(name string) (string, string) { return svc, pvd } -func fullServiceName(ctx context.Context, namespace string, service v1alpha1.LoadBalancerSpec, port intstr.IntOrString) string { +func fullServiceName(ctx context.Context, namespace string, service traefikv1alpha1.LoadBalancerSpec, port intstr.IntOrString) string { if (port.Type == intstr.Int && port.IntVal != 0) || (port.Type == intstr.String && port.StrVal != "") { return provider.Normalize(fmt.Sprintf("%s-%s-%s", namespace, service.Name, &port)) } @@ -502,7 +502,7 @@ func fullServiceName(ctx context.Context, namespace string, service v1alpha1.Loa return provider.Normalize(name) + providerNamespaceSeparator + pName } -func namespaceOrFallback(lb v1alpha1.LoadBalancerSpec, fallback string) string { +func namespaceOrFallback(lb traefikv1alpha1.LoadBalancerSpec, fallback string) string { if lb.Namespace != "" { return lb.Namespace } @@ -510,7 +510,7 @@ func namespaceOrFallback(lb v1alpha1.LoadBalancerSpec, fallback string) string { } // getTLSHTTP mutates tlsConfigs. -func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { +func getTLSHTTP(ctx context.Context, ingressRoute *traefikv1alpha1.IngressRoute, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { if ingressRoute.Spec.TLS == nil { return nil } diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index 63028e4ab..0a9442715 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -11,7 +11,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/tls" corev1 "k8s.io/api/core/v1" ) @@ -141,7 +141,7 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client return conf } -func (p *Provider) makeMiddlewareTCPKeys(ctx context.Context, ingRouteTCPNamespace string, middlewares []v1alpha1.ObjectReference) ([]string, error) { +func (p *Provider) makeMiddlewareTCPKeys(ctx context.Context, ingRouteTCPNamespace string, middlewares []traefikv1alpha1.ObjectReference) ([]string, error) { var mds []string for _, mi := range middlewares { @@ -170,7 +170,7 @@ func (p *Provider) makeMiddlewareTCPKeys(ctx context.Context, ingRouteTCPNamespa return mds, nil } -func (p *Provider) createLoadBalancerServerTCP(client Client, parentNamespace string, service v1alpha1.ServiceTCP) (*dynamic.TCPService, error) { +func (p *Provider) createLoadBalancerServerTCP(client Client, parentNamespace string, service traefikv1alpha1.ServiceTCP) (*dynamic.TCPService, error) { ns := parentNamespace if len(service.Namespace) > 0 { if !isNamespaceAllowed(p.AllowCrossNamespace, parentNamespace, service.Namespace) { @@ -207,7 +207,7 @@ func (p *Provider) createLoadBalancerServerTCP(client Client, parentNamespace st return tcpService, nil } -func (p *Provider) loadTCPServers(client Client, namespace string, svc v1alpha1.ServiceTCP) ([]dynamic.TCPServer, error) { +func (p *Provider) loadTCPServers(client Client, namespace string, svc traefikv1alpha1.ServiceTCP) ([]dynamic.TCPServer, error) { service, exists, err := client.GetService(namespace, svc.Name) if err != nil { return nil, err @@ -279,7 +279,7 @@ func (p *Provider) loadTCPServers(client Client, namespace string, svc v1alpha1. } // getTLSTCP mutates tlsConfigs. -func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { +func getTLSTCP(ctx context.Context, ingressRoute *traefikv1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { if ingressRoute.Spec.TLS == nil { return nil } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index c572e9c56..e5178eb37 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -14,8 +14,8 @@ import ( ptypes "github.com/traefik/paerser/types" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/provider" - crdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikcrdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/types" @@ -5905,23 +5905,23 @@ func TestCrossNamespace(t *testing.T) { switch o := obj.(type) { case *corev1.Service, *corev1.Endpoints, *corev1.Secret: k8sObjects = append(k8sObjects, o) - case *v1alpha1.IngressRoute: + case *traefikv1alpha1.IngressRoute: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteTCP: + case *traefikv1alpha1.IngressRouteTCP: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteUDP: + case *traefikv1alpha1.IngressRouteUDP: crdObjects = append(crdObjects, o) - case *v1alpha1.Middleware: + case *traefikv1alpha1.Middleware: crdObjects = append(crdObjects, o) - case *v1alpha1.MiddlewareTCP: + case *traefikv1alpha1.MiddlewareTCP: crdObjects = append(crdObjects, o) - case *v1alpha1.TraefikService: + case *traefikv1alpha1.TraefikService: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSOption: + case *traefikv1alpha1.TLSOption: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSStore: + case *traefikv1alpha1.TLSStore: crdObjects = append(crdObjects, o) - case *v1alpha1.ServersTransport: + case *traefikv1alpha1.ServersTransport: crdObjects = append(crdObjects, o) default: } @@ -5929,7 +5929,7 @@ func TestCrossNamespace(t *testing.T) { } kubeClient := kubefake.NewSimpleClientset(k8sObjects...) - crdClient := crdfake.NewSimpleClientset(crdObjects...) + crdClient := traefikcrdfake.NewSimpleClientset(crdObjects...) client := newClientImpl(kubeClient, crdClient) @@ -6200,19 +6200,19 @@ func TestExternalNameService(t *testing.T) { switch o := obj.(type) { case *corev1.Service, *corev1.Endpoints, *corev1.Secret: k8sObjects = append(k8sObjects, o) - case *v1alpha1.IngressRoute: + case *traefikv1alpha1.IngressRoute: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteTCP: + case *traefikv1alpha1.IngressRouteTCP: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteUDP: + case *traefikv1alpha1.IngressRouteUDP: crdObjects = append(crdObjects, o) - case *v1alpha1.Middleware: + case *traefikv1alpha1.Middleware: crdObjects = append(crdObjects, o) - case *v1alpha1.TraefikService: + case *traefikv1alpha1.TraefikService: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSOption: + case *traefikv1alpha1.TLSOption: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSStore: + case *traefikv1alpha1.TLSStore: crdObjects = append(crdObjects, o) default: } @@ -6220,7 +6220,7 @@ func TestExternalNameService(t *testing.T) { } kubeClient := kubefake.NewSimpleClientset(k8sObjects...) - crdClient := crdfake.NewSimpleClientset(crdObjects...) + crdClient := traefikcrdfake.NewSimpleClientset(crdObjects...) client := newClientImpl(kubeClient, crdClient) @@ -6408,19 +6408,19 @@ func TestNativeLB(t *testing.T) { switch o := obj.(type) { case *corev1.Service, *corev1.Endpoints, *corev1.Secret: k8sObjects = append(k8sObjects, o) - case *v1alpha1.IngressRoute: + case *traefikv1alpha1.IngressRoute: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteTCP: + case *traefikv1alpha1.IngressRouteTCP: crdObjects = append(crdObjects, o) - case *v1alpha1.IngressRouteUDP: + case *traefikv1alpha1.IngressRouteUDP: crdObjects = append(crdObjects, o) - case *v1alpha1.Middleware: + case *traefikv1alpha1.Middleware: crdObjects = append(crdObjects, o) - case *v1alpha1.TraefikService: + case *traefikv1alpha1.TraefikService: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSOption: + case *traefikv1alpha1.TLSOption: crdObjects = append(crdObjects, o) - case *v1alpha1.TLSStore: + case *traefikv1alpha1.TLSStore: crdObjects = append(crdObjects, o) default: } @@ -6428,7 +6428,7 @@ func TestNativeLB(t *testing.T) { } kubeClient := kubefake.NewSimpleClientset(k8sObjects...) - crdClient := crdfake.NewSimpleClientset(crdObjects...) + crdClient := traefikcrdfake.NewSimpleClientset(crdObjects...) client := newClientImpl(kubeClient, crdClient) @@ -6452,7 +6452,6 @@ func TestNativeLB(t *testing.T) { func TestCreateBasicAuthCredentials(t *testing.T) { var k8sObjects []runtime.Object - var crdObjects []runtime.Object yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/basic_auth_secrets.yml")) if err != nil { panic(err) @@ -6468,7 +6467,7 @@ func TestCreateBasicAuthCredentials(t *testing.T) { } kubeClient := kubefake.NewSimpleClientset(k8sObjects...) - crdClient := crdfake.NewSimpleClientset(crdObjects...) + crdClient := traefikcrdfake.NewSimpleClientset() client := newClientImpl(kubeClient, crdClient) @@ -6477,13 +6476,13 @@ func TestCreateBasicAuthCredentials(t *testing.T) { eventCh, err := client.WatchAll([]string{"default"}, stopCh) require.NoError(t, err) - if k8sObjects != nil || crdObjects != nil { + if k8sObjects != nil { // just wait for the first event <-eventCh } // Testing for username/password components in basic-auth secret - basicAuth, secretErr := createBasicAuthMiddleware(client, "default", &v1alpha1.BasicAuth{Secret: "basic-auth-secret"}) + basicAuth, secretErr := createBasicAuthMiddleware(client, "default", &traefikv1alpha1.BasicAuth{Secret: "basic-auth-secret"}) require.NoError(t, secretErr) require.Len(t, basicAuth.Users, 1) @@ -6498,7 +6497,7 @@ func TestCreateBasicAuthCredentials(t *testing.T) { assert.True(t, auth.CheckSecret("password", hashedPassword)) // Testing for username/password components in htpasswd secret - basicAuth, secretErr = createBasicAuthMiddleware(client, "default", &v1alpha1.BasicAuth{Secret: "auth-secret"}) + basicAuth, secretErr = createBasicAuthMiddleware(client, "default", &traefikv1alpha1.BasicAuth{Secret: "auth-secret"}) require.NoError(t, secretErr) require.Len(t, basicAuth.Users, 2) diff --git a/pkg/provider/kubernetes/crd/kubernetes_udp.go b/pkg/provider/kubernetes/crd/kubernetes_udp.go index c79b39af4..cc965eb2d 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_udp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_udp.go @@ -9,7 +9,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" corev1 "k8s.io/api/core/v1" ) @@ -77,7 +77,7 @@ func (p *Provider) loadIngressRouteUDPConfiguration(ctx context.Context, client return conf } -func (p *Provider) createLoadBalancerServerUDP(client Client, parentNamespace string, service v1alpha1.ServiceUDP) (*dynamic.UDPService, error) { +func (p *Provider) createLoadBalancerServerUDP(client Client, parentNamespace string, service traefikv1alpha1.ServiceUDP) (*dynamic.UDPService, error) { ns := parentNamespace if len(service.Namespace) > 0 { if !isNamespaceAllowed(p.AllowCrossNamespace, parentNamespace, service.Namespace) { @@ -101,7 +101,7 @@ func (p *Provider) createLoadBalancerServerUDP(client Client, parentNamespace st return udpService, nil } -func (p *Provider) loadUDPServers(client Client, namespace string, svc v1alpha1.ServiceUDP) ([]dynamic.UDPServer, error) { +func (p *Provider) loadUDPServers(client Client, namespace string, svc traefikv1alpha1.ServiceUDP) ([]dynamic.UDPServer, error) { service, exists, err := client.GetService(namespace, svc.Name) if err != nil { return nil, err diff --git a/pkg/provider/kubernetes/crd/scheme.go b/pkg/provider/kubernetes/crd/scheme.go index e2ee711fb..581a7983f 100644 --- a/pkg/provider/kubernetes/crd/scheme.go +++ b/pkg/provider/kubernetes/crd/scheme.go @@ -4,51 +4,51 @@ import ( "fmt" "github.com/traefik/traefik/v2/pkg/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + traefikscheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" containousv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/conversion" k8sruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" + kschema "k8s.io/apimachinery/pkg/runtime/schema" ) var GroupVersioner k8sruntime.GroupVersioner func init() { GroupVersioner = k8sruntime.NewMultiGroupVersioner( - v1alpha1.SchemeGroupVersion, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRoute{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRouteTCP{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRouteUDP{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.Middleware{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.MiddlewareTCP{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TLSOption{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TLSStore{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.ServersTransport{}.Kind}, - schema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TraefikService{}.Kind}, + traefikv1alpha1.SchemeGroupVersion, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRoute{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRouteTCP{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.IngressRouteUDP{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.Middleware{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.MiddlewareTCP{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TLSOption{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TLSStore{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.ServersTransport{}.Kind}, + kschema.GroupKind{Group: containousv1alpha1.GroupName, Kind: containousv1alpha1.TraefikService{}.Kind}, ) convert := map[interface{}]interface{}{} - convert[&containousv1alpha1.IngressRoute{}] = &v1alpha1.IngressRoute{} - convert[&containousv1alpha1.IngressRouteTCP{}] = &v1alpha1.IngressRouteTCP{} - convert[&containousv1alpha1.IngressRouteUDP{}] = &v1alpha1.IngressRouteUDP{} - convert[&containousv1alpha1.Middleware{}] = &v1alpha1.Middleware{} - convert[&containousv1alpha1.MiddlewareTCP{}] = &v1alpha1.MiddlewareTCP{} - convert[&containousv1alpha1.TLSOption{}] = &v1alpha1.TLSOption{} - convert[&containousv1alpha1.TLSStore{}] = &v1alpha1.TLSStore{} - convert[&containousv1alpha1.ServersTransport{}] = &v1alpha1.ServersTransport{} - convert[&containousv1alpha1.TraefikService{}] = &v1alpha1.TraefikService{} + convert[&containousv1alpha1.IngressRoute{}] = &traefikv1alpha1.IngressRoute{} + convert[&containousv1alpha1.IngressRouteTCP{}] = &traefikv1alpha1.IngressRouteTCP{} + convert[&containousv1alpha1.IngressRouteUDP{}] = &traefikv1alpha1.IngressRouteUDP{} + convert[&containousv1alpha1.Middleware{}] = &traefikv1alpha1.Middleware{} + convert[&containousv1alpha1.MiddlewareTCP{}] = &traefikv1alpha1.MiddlewareTCP{} + convert[&containousv1alpha1.TLSOption{}] = &traefikv1alpha1.TLSOption{} + convert[&containousv1alpha1.TLSStore{}] = &traefikv1alpha1.TLSStore{} + convert[&containousv1alpha1.ServersTransport{}] = &traefikv1alpha1.ServersTransport{} + convert[&containousv1alpha1.TraefikService{}] = &traefikv1alpha1.TraefikService{} for interfaceA, interfaceB := range convert { - err := scheme.Scheme.AddConversionFunc(interfaceA, interfaceB, func(a, b interface{}, scope conversion.Scope) error { + err := traefikscheme.Scheme.AddConversionFunc(interfaceA, interfaceB, func(a, b interface{}, scope conversion.Scope) error { unstruct, err := k8sruntime.DefaultUnstructuredConverter.ToUnstructured(a) if err != nil { return fmt.Errorf("failed to unstruct interface: %w", err) } u := &unstructured.Unstructured{Object: unstruct} - u.SetGroupVersionKind(v1alpha1.SchemeGroupVersion.WithKind(u.GetKind())) + u.SetGroupVersionKind(traefikv1alpha1.SchemeGroupVersion.WithKind(u.GetKind())) if err = k8sruntime.DefaultUnstructuredConverter.FromUnstructured(u.Object, b); err != nil { return fmt.Errorf("failed to convert interface: %w", err) diff --git a/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/register.go b/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/register.go index e87a2ff65..f9d063f3d 100644 --- a/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/register.go +++ b/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/register.go @@ -3,7 +3,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" + kschema "k8s.io/apimachinery/pkg/runtime/schema" ) // GroupName is the group name for Traefik. @@ -18,15 +18,15 @@ var ( ) // SchemeGroupVersion is group version used to register these objects. -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = kschema.GroupVersion{Group: GroupName, Version: "v1alpha1"} // Kind takes an unqualified kind and returns back a Group qualified GroupKind. -func Kind(kind string) schema.GroupKind { +func Kind(kind string) kschema.GroupKind { return SchemeGroupVersion.WithKind(kind).GroupKind() } // Resource takes an unqualified resource and returns a Group qualified GroupResource. -func Resource(resource string) schema.GroupResource { +func Resource(resource string) kschema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go index d04564380..72d36ba77 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go @@ -3,7 +3,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" + kschema "k8s.io/apimachinery/pkg/runtime/schema" ) // GroupName is the group name for Traefik. @@ -18,15 +18,15 @@ var ( ) // SchemeGroupVersion is group version used to register these objects. -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = kschema.GroupVersion{Group: GroupName, Version: "v1alpha1"} // Kind takes an unqualified kind and returns back a Group qualified GroupKind. -func Kind(kind string) schema.GroupKind { +func Kind(kind string) kschema.GroupKind { return SchemeGroupVersion.WithKind(kind).GroupKind() } // Resource takes an unqualified resource and returns a Group qualified GroupResource. -func Resource(resource string) schema.GroupResource { +func Resource(resource string) kschema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } diff --git a/pkg/provider/kubernetes/gateway/client.go b/pkg/provider/kubernetes/gateway/client.go index 1561ad472..59f29fbb4 100644 --- a/pkg/provider/kubernetes/gateway/client.go +++ b/pkg/provider/kubernetes/gateway/client.go @@ -9,16 +9,16 @@ import ( "github.com/traefik/traefik/v2/pkg/log" corev1 "k8s.io/api/core/v1" - kubeerror "k8s.io/apimachinery/pkg/api/errors" + kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/informers" - "k8s.io/client-go/kubernetes" + kinformers "k8s.io/client-go/informers" + kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "sigs.k8s.io/gateway-api/apis/v1alpha2" - "sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned" - "sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions" + gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gateclientset "sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned" + gateinformers "sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions" ) const resyncPeriod = 10 * time.Minute @@ -33,7 +33,7 @@ func (reh *resourceEventHandler) OnAdd(obj interface{}) { func (reh *resourceEventHandler) OnUpdate(oldObj, newObj interface{}) { switch oldObj.(type) { - case *v1alpha2.GatewayClass: + case *gatev1alpha2.GatewayClass: // Skip update for gateway classes. We only manage addition or deletion for this cluster-wide resource. return default: @@ -50,13 +50,13 @@ func (reh *resourceEventHandler) OnDelete(obj interface{}) { // The stores can then be accessed via the Get* functions. type Client interface { WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) - GetGatewayClasses() ([]*v1alpha2.GatewayClass, error) - UpdateGatewayStatus(gateway *v1alpha2.Gateway, gatewayStatus v1alpha2.GatewayStatus) error - UpdateGatewayClassStatus(gatewayClass *v1alpha2.GatewayClass, condition metav1.Condition) error - GetGateways() []*v1alpha2.Gateway - GetHTTPRoutes(namespaces []string) ([]*v1alpha2.HTTPRoute, error) - GetTCPRoutes(namespaces []string) ([]*v1alpha2.TCPRoute, error) - GetTLSRoutes(namespaces []string) ([]*v1alpha2.TLSRoute, error) + GetGatewayClasses() ([]*gatev1alpha2.GatewayClass, error) + UpdateGatewayStatus(gateway *gatev1alpha2.Gateway, gatewayStatus gatev1alpha2.GatewayStatus) error + UpdateGatewayClassStatus(gatewayClass *gatev1alpha2.GatewayClass, condition metav1.Condition) error + GetGateways() []*gatev1alpha2.Gateway + GetHTTPRoutes(namespaces []string) ([]*gatev1alpha2.HTTPRoute, error) + GetTCPRoutes(namespaces []string) ([]*gatev1alpha2.TCPRoute, error) + GetTLSRoutes(namespaces []string) ([]*gatev1alpha2.TLSRoute, error) GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) @@ -64,14 +64,14 @@ type Client interface { } type clientWrapper struct { - csGateway versioned.Interface - csKube kubernetes.Interface + csGateway gateclientset.Interface + csKube kclientset.Interface - factoryNamespace informers.SharedInformerFactory - factoryGatewayClass externalversions.SharedInformerFactory - factoriesGateway map[string]externalversions.SharedInformerFactory - factoriesKube map[string]informers.SharedInformerFactory - factoriesSecret map[string]informers.SharedInformerFactory + factoryNamespace kinformers.SharedInformerFactory + factoryGatewayClass gateinformers.SharedInformerFactory + factoriesGateway map[string]gateinformers.SharedInformerFactory + factoriesKube map[string]kinformers.SharedInformerFactory + factoriesSecret map[string]kinformers.SharedInformerFactory isNamespaceAll bool watchedNamespaces []string @@ -80,12 +80,12 @@ type clientWrapper struct { } func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { - csGateway, err := versioned.NewForConfig(c) + csGateway, err := gateclientset.NewForConfig(c) if err != nil { return nil, err } - csKube, err := kubernetes.NewForConfig(c) + csKube, err := kclientset.NewForConfig(c) if err != nil { return nil, err } @@ -93,13 +93,13 @@ func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { return newClientImpl(csKube, csGateway), nil } -func newClientImpl(csKube kubernetes.Interface, csGateway versioned.Interface) *clientWrapper { +func newClientImpl(csKube kclientset.Interface, csGateway gateclientset.Interface) *clientWrapper { return &clientWrapper{ csGateway: csGateway, csKube: csKube, - factoriesGateway: make(map[string]externalversions.SharedInformerFactory), - factoriesKube: make(map[string]informers.SharedInformerFactory), - factoriesSecret: make(map[string]informers.SharedInformerFactory), + factoriesGateway: make(map[string]gateinformers.SharedInformerFactory), + factoriesKube: make(map[string]kinformers.SharedInformerFactory), + factoriesSecret: make(map[string]kinformers.SharedInformerFactory), } } @@ -126,8 +126,7 @@ func newExternalClusterClientFromFile(file string) (*clientWrapper, error) { return createClientFromConfig(configFromFlags) } -// newExternalClusterClient returns a new Provider client that may run outside -// of the cluster. +// newExternalClusterClient returns a new Provider client that may run outside of the cluster. // The endpoint parameter must not be empty. func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrapper, error) { if endpoint == "" { @@ -171,13 +170,13 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< options.LabelSelector = c.labelSelector } - c.factoryNamespace = informers.NewSharedInformerFactory(c.csKube, resyncPeriod) + c.factoryNamespace = kinformers.NewSharedInformerFactory(c.csKube, resyncPeriod) _, err := c.factoryNamespace.Core().V1().Namespaces().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err } - c.factoryGatewayClass = externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithTweakListOptions(labelSelectorOptions)) + c.factoryGatewayClass = gateinformers.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, gateinformers.WithTweakListOptions(labelSelectorOptions)) _, err = c.factoryGatewayClass.Gateway().V1alpha2().GatewayClasses().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -187,7 +186,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.ReferencePolicy for _, ns := range namespaces { - factoryGateway := externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithNamespace(ns)) + factoryGateway := gateinformers.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, gateinformers.WithNamespace(ns)) _, err = factoryGateway.Gateway().V1alpha2().Gateways().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -205,7 +204,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< return nil, err } - factoryKube := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns)) + factoryKube := kinformers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, kinformers.WithNamespace(ns)) _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -215,7 +214,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< return nil, err } - factorySecret := informers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) + factorySecret := kinformers.NewSharedInformerFactoryWithOptions(c.csKube, resyncPeriod, kinformers.WithNamespace(ns), kinformers.WithTweakListOptions(notOwnedByHelm)) _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -287,8 +286,8 @@ func (c *clientWrapper) GetNamespaces(selector labels.Selector) ([]string, error return namespaces, nil } -func (c *clientWrapper) GetHTTPRoutes(namespaces []string) ([]*v1alpha2.HTTPRoute, error) { - var httpRoutes []*v1alpha2.HTTPRoute +func (c *clientWrapper) GetHTTPRoutes(namespaces []string) ([]*gatev1alpha2.HTTPRoute, error) { + var httpRoutes []*gatev1alpha2.HTTPRoute for _, namespace := range namespaces { if !c.isWatchedNamespace(namespace) { log.WithoutContext().Warnf("Failed to get HTTPRoutes: %q is not within watched namespaces", namespace) @@ -311,8 +310,8 @@ func (c *clientWrapper) GetHTTPRoutes(namespaces []string) ([]*v1alpha2.HTTPRout return httpRoutes, nil } -func (c *clientWrapper) GetTCPRoutes(namespaces []string) ([]*v1alpha2.TCPRoute, error) { - var tcpRoutes []*v1alpha2.TCPRoute +func (c *clientWrapper) GetTCPRoutes(namespaces []string) ([]*gatev1alpha2.TCPRoute, error) { + var tcpRoutes []*gatev1alpha2.TCPRoute for _, namespace := range namespaces { if !c.isWatchedNamespace(namespace) { log.WithoutContext().Warnf("Failed to get TCPRoutes: %q is not within watched namespaces", namespace) @@ -334,8 +333,8 @@ func (c *clientWrapper) GetTCPRoutes(namespaces []string) ([]*v1alpha2.TCPRoute, return tcpRoutes, nil } -func (c *clientWrapper) GetTLSRoutes(namespaces []string) ([]*v1alpha2.TLSRoute, error) { - var tlsRoutes []*v1alpha2.TLSRoute +func (c *clientWrapper) GetTLSRoutes(namespaces []string) ([]*gatev1alpha2.TLSRoute, error) { + var tlsRoutes []*gatev1alpha2.TLSRoute for _, namespace := range namespaces { if !c.isWatchedNamespace(namespace) { log.WithoutContext().Warnf("Failed to get TLSRoutes: %q is not within watched namespaces", namespace) @@ -357,8 +356,8 @@ func (c *clientWrapper) GetTLSRoutes(namespaces []string) ([]*v1alpha2.TLSRoute, return tlsRoutes, nil } -func (c *clientWrapper) GetGateways() []*v1alpha2.Gateway { - var result []*v1alpha2.Gateway +func (c *clientWrapper) GetGateways() []*gatev1alpha2.Gateway { + var result []*gatev1alpha2.Gateway for ns, factory := range c.factoriesGateway { gateways, err := factory.Gateway().V1alpha2().Gateways().Lister().List(labels.Everything()) @@ -372,11 +371,11 @@ func (c *clientWrapper) GetGateways() []*v1alpha2.Gateway { return result } -func (c *clientWrapper) GetGatewayClasses() ([]*v1alpha2.GatewayClass, error) { +func (c *clientWrapper) GetGatewayClasses() ([]*gatev1alpha2.GatewayClass, error) { return c.factoryGatewayClass.Gateway().V1alpha2().GatewayClasses().Lister().List(labels.Everything()) } -func (c *clientWrapper) UpdateGatewayClassStatus(gatewayClass *v1alpha2.GatewayClass, condition metav1.Condition) error { +func (c *clientWrapper) UpdateGatewayClassStatus(gatewayClass *gatev1alpha2.GatewayClass, condition metav1.Condition) error { gc := gatewayClass.DeepCopy() var newConditions []metav1.Condition @@ -407,7 +406,7 @@ func (c *clientWrapper) UpdateGatewayClassStatus(gatewayClass *v1alpha2.GatewayC return nil } -func (c *clientWrapper) UpdateGatewayStatus(gateway *v1alpha2.Gateway, gatewayStatus v1alpha2.GatewayStatus) error { +func (c *clientWrapper) UpdateGatewayStatus(gateway *gatev1alpha2.Gateway, gatewayStatus gatev1alpha2.GatewayStatus) error { if !c.isWatchedNamespace(gateway.Namespace) { return fmt.Errorf("cannot update Gateway status %s/%s: namespace is not within watched namespaces", gateway.Namespace, gateway.Name) } @@ -430,7 +429,7 @@ func (c *clientWrapper) UpdateGatewayStatus(gateway *v1alpha2.Gateway, gatewaySt return nil } -func statusEquals(oldStatus, newStatus v1alpha2.GatewayStatus) bool { +func statusEquals(oldStatus, newStatus gatev1alpha2.GatewayStatus) bool { if len(oldStatus.Listeners) != len(newStatus.Listeners) { return false } @@ -537,7 +536,7 @@ func eventHandlerFunc(events chan<- interface{}, obj interface{}) { // translateNotFoundError will translate a "not found" error to a boolean return // value which indicates if the resource exists and a nil error. func translateNotFoundError(err error) (bool, error) { - if kubeerror.IsNotFound(err) { + if kerror.IsNotFound(err) { return false, nil } return err == nil, err diff --git a/pkg/provider/kubernetes/gateway/client_mock_test.go b/pkg/provider/kubernetes/gateway/client_mock_test.go index 010ce6635..aa8c2e567 100644 --- a/pkg/provider/kubernetes/gateway/client_mock_test.go +++ b/pkg/provider/kubernetes/gateway/client_mock_test.go @@ -9,15 +9,15 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/gateway-api/apis/v1alpha2" + kscheme "k8s.io/client-go/kubernetes/scheme" + gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) var _ Client = (*clientMock)(nil) func init() { // required by k8s.MustParseYaml - err := v1alpha2.AddToScheme(scheme.Scheme) + err := gatev1alpha2.AddToScheme(kscheme.Scheme) if err != nil { panic(err) } @@ -33,11 +33,11 @@ type clientMock struct { apiSecretError error apiEndpointsError error - gatewayClasses []*v1alpha2.GatewayClass - gateways []*v1alpha2.Gateway - httpRoutes []*v1alpha2.HTTPRoute - tcpRoutes []*v1alpha2.TCPRoute - tlsRoutes []*v1alpha2.TLSRoute + gatewayClasses []*gatev1alpha2.GatewayClass + gateways []*gatev1alpha2.Gateway + httpRoutes []*gatev1alpha2.HTTPRoute + tcpRoutes []*gatev1alpha2.TCPRoute + tlsRoutes []*gatev1alpha2.TLSRoute watchChan chan interface{} } @@ -62,15 +62,15 @@ func newClientMock(paths ...string) clientMock { c.namespaces = append(c.namespaces, o) case *corev1.Endpoints: c.endpoints = append(c.endpoints, o) - case *v1alpha2.GatewayClass: + case *gatev1alpha2.GatewayClass: c.gatewayClasses = append(c.gatewayClasses, o) - case *v1alpha2.Gateway: + case *gatev1alpha2.Gateway: c.gateways = append(c.gateways, o) - case *v1alpha2.HTTPRoute: + case *gatev1alpha2.HTTPRoute: c.httpRoutes = append(c.httpRoutes, o) - case *v1alpha2.TCPRoute: + case *gatev1alpha2.TCPRoute: c.tcpRoutes = append(c.tcpRoutes, o) - case *v1alpha2.TLSRoute: + case *gatev1alpha2.TLSRoute: c.tlsRoutes = append(c.tlsRoutes, o) default: panic(fmt.Sprintf("Unknown runtime object %+v %T", o, o)) @@ -81,7 +81,7 @@ func newClientMock(paths ...string) clientMock { return c } -func (c clientMock) UpdateGatewayStatus(gateway *v1alpha2.Gateway, gatewayStatus v1alpha2.GatewayStatus) error { +func (c clientMock) UpdateGatewayStatus(gateway *gatev1alpha2.Gateway, gatewayStatus gatev1alpha2.GatewayStatus) error { for _, g := range c.gateways { if g.Name == gateway.Name { if !statusEquals(g.Status, gatewayStatus) { @@ -94,7 +94,7 @@ func (c clientMock) UpdateGatewayStatus(gateway *v1alpha2.Gateway, gatewayStatus return nil } -func (c clientMock) UpdateGatewayClassStatus(gatewayClass *v1alpha2.GatewayClass, condition metav1.Condition) error { +func (c clientMock) UpdateGatewayClassStatus(gatewayClass *gatev1alpha2.GatewayClass, condition metav1.Condition) error { for _, gc := range c.gatewayClasses { if gc.Name == gatewayClass.Name { for _, c := range gc.Status.Conditions { @@ -110,7 +110,7 @@ func (c clientMock) UpdateGatewayClassStatus(gatewayClass *v1alpha2.GatewayClass return nil } -func (c clientMock) UpdateGatewayStatusConditions(gateway *v1alpha2.Gateway, condition metav1.Condition) error { +func (c clientMock) UpdateGatewayStatusConditions(gateway *gatev1alpha2.Gateway, condition metav1.Condition) error { for _, g := range c.gatewayClasses { if g.Name == gateway.Name { for _, c := range g.Status.Conditions { @@ -126,11 +126,11 @@ func (c clientMock) UpdateGatewayStatusConditions(gateway *v1alpha2.Gateway, con return nil } -func (c clientMock) GetGatewayClasses() ([]*v1alpha2.GatewayClass, error) { +func (c clientMock) GetGatewayClasses() ([]*gatev1alpha2.GatewayClass, error) { return c.gatewayClasses, nil } -func (c clientMock) GetGateways() []*v1alpha2.Gateway { +func (c clientMock) GetGateways() []*gatev1alpha2.Gateway { return c.gateways } @@ -148,8 +148,8 @@ func (c clientMock) GetNamespaces(selector labels.Selector) ([]string, error) { return ns, nil } -func (c clientMock) GetHTTPRoutes(namespaces []string) ([]*v1alpha2.HTTPRoute, error) { - var httpRoutes []*v1alpha2.HTTPRoute +func (c clientMock) GetHTTPRoutes(namespaces []string) ([]*gatev1alpha2.HTTPRoute, error) { + var httpRoutes []*gatev1alpha2.HTTPRoute for _, namespace := range namespaces { for _, httpRoute := range c.httpRoutes { if inNamespace(httpRoute.ObjectMeta, namespace) { @@ -160,8 +160,8 @@ func (c clientMock) GetHTTPRoutes(namespaces []string) ([]*v1alpha2.HTTPRoute, e return httpRoutes, nil } -func (c clientMock) GetTCPRoutes(namespaces []string) ([]*v1alpha2.TCPRoute, error) { - var tcpRoutes []*v1alpha2.TCPRoute +func (c clientMock) GetTCPRoutes(namespaces []string) ([]*gatev1alpha2.TCPRoute, error) { + var tcpRoutes []*gatev1alpha2.TCPRoute for _, namespace := range namespaces { for _, tcpRoute := range c.tcpRoutes { if inNamespace(tcpRoute.ObjectMeta, namespace) { @@ -172,8 +172,8 @@ func (c clientMock) GetTCPRoutes(namespaces []string) ([]*v1alpha2.TCPRoute, err return tcpRoutes, nil } -func (c clientMock) GetTLSRoutes(namespaces []string) ([]*v1alpha2.TLSRoute, error) { - var tlsRoutes []*v1alpha2.TLSRoute +func (c clientMock) GetTLSRoutes(namespaces []string) ([]*gatev1alpha2.TLSRoute, error) { + var tlsRoutes []*gatev1alpha2.TLSRoute for _, namespace := range namespaces { for _, tlsRoute := range c.tlsRoutes { if inNamespace(tlsRoute.ObjectMeta, namespace) { diff --git a/pkg/provider/kubernetes/gateway/client_test.go b/pkg/provider/kubernetes/gateway/client_test.go index f90f7dfae..794f7d6a8 100644 --- a/pkg/provider/kubernetes/gateway/client_test.go +++ b/pkg/provider/kubernetes/gateway/client_test.go @@ -5,32 +5,32 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) func TestStatusEquals(t *testing.T) { testCases := []struct { desc string - statusA v1alpha2.GatewayStatus - statusB v1alpha2.GatewayStatus + statusA gatev1alpha2.GatewayStatus + statusB gatev1alpha2.GatewayStatus expected bool }{ { desc: "Empty", - statusA: v1alpha2.GatewayStatus{}, - statusB: v1alpha2.GatewayStatus{}, + statusA: gatev1alpha2.GatewayStatus{}, + statusB: gatev1alpha2.GatewayStatus{}, expected: true, }, { desc: "Same status", - statusA: v1alpha2.GatewayStatus{ + statusA: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobar", Reason: "foobar", }, }, - Listeners: []v1alpha2.ListenerStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "foo", Conditions: []metav1.Condition{ @@ -42,14 +42,14 @@ func TestStatusEquals(t *testing.T) { }, }, }, - statusB: v1alpha2.GatewayStatus{ + statusB: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobar", Reason: "foobar", }, }, - Listeners: []v1alpha2.ListenerStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "foo", Conditions: []metav1.Condition{ @@ -65,11 +65,11 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Listeners length not equal", - statusA: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{}, + statusA: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{}, }, - statusB: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusB: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ {}, }, }, @@ -77,10 +77,10 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway conditions length not equal", - statusA: v1alpha2.GatewayStatus{ + statusA: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{}, }, - statusB: v1alpha2.GatewayStatus{ + statusB: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ {}, }, @@ -89,14 +89,14 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway conditions different types", - statusA: v1alpha2.GatewayStatus{ + statusA: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobar", }, }, }, - statusB: v1alpha2.GatewayStatus{ + statusB: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobir", @@ -107,14 +107,14 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway conditions same types but different reason", - statusA: v1alpha2.GatewayStatus{ + statusA: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobar", }, }, }, - statusB: v1alpha2.GatewayStatus{ + statusB: gatev1alpha2.GatewayStatus{ Conditions: []metav1.Condition{ { Type: "foobar", @@ -126,16 +126,16 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway listeners conditions length", - statusA: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusA: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "foo", Conditions: []metav1.Condition{}, }, }, }, - statusB: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusB: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "foo", Conditions: []metav1.Condition{ @@ -148,8 +148,8 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway listeners conditions same types but different status", - statusA: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusA: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Conditions: []metav1.Condition{ { @@ -159,8 +159,8 @@ func TestStatusEquals(t *testing.T) { }, }, }, - statusB: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusB: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Conditions: []metav1.Condition{ { @@ -175,8 +175,8 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway listeners conditions same types but different message", - statusA: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusA: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Conditions: []metav1.Condition{ { @@ -186,8 +186,8 @@ func TestStatusEquals(t *testing.T) { }, }, }, - statusB: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusB: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Conditions: []metav1.Condition{ { @@ -202,8 +202,8 @@ func TestStatusEquals(t *testing.T) { }, { desc: "Gateway listeners conditions same types/reason but different names", - statusA: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusA: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "foo", Conditions: []metav1.Condition{ @@ -215,8 +215,8 @@ func TestStatusEquals(t *testing.T) { }, }, }, - statusB: v1alpha2.GatewayStatus{ - Listeners: []v1alpha2.ListenerStatus{ + statusB: gatev1alpha2.GatewayStatus{ + Listeners: []gatev1alpha2.ListenerStatus{ { Name: "bar", Conditions: []metav1.Condition{ diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index 85980dfa4..a74104957 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/utils/pointer" "k8s.io/utils/strings/slices" - "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) const ( @@ -209,14 +209,14 @@ func (p *Provider) loadConfigurationFromGateway(ctx context.Context, client Clie gatewayClassNames[gatewayClass.Name] = struct{}{} err := client.UpdateGatewayClassStatus(gatewayClass, metav1.Condition{ - Type: string(v1alpha2.GatewayClassConditionStatusAccepted), + Type: string(gatev1alpha2.GatewayClassConditionStatusAccepted), Status: metav1.ConditionTrue, Reason: "Handled", Message: "Handled by Traefik controller", LastTransitionTime: metav1.Now(), }) if err != nil { - logger.Errorf("Failed to update %s condition: %v", v1alpha2.GatewayClassConditionStatusAccepted, err) + logger.Errorf("Failed to update %s condition: %v", gatev1alpha2.GatewayClassConditionStatusAccepted, err) } } } @@ -272,7 +272,7 @@ func (p *Provider) loadConfigurationFromGateway(ctx context.Context, client Clie return conf } -func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway *v1alpha2.Gateway) (*dynamic.Configuration, error) { +func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway *gatev1alpha2.Gateway) (*dynamic.Configuration, error) { conf := &dynamic.Configuration{ UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -315,15 +315,15 @@ func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway return conf, nil } -func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *v1alpha2.Gateway, conf *dynamic.Configuration, tlsConfigs map[string]*tls.CertAndStores) []v1alpha2.ListenerStatus { +func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *gatev1alpha2.Gateway, conf *dynamic.Configuration, tlsConfigs map[string]*tls.CertAndStores) []gatev1alpha2.ListenerStatus { logger := log.FromContext(ctx) - listenerStatuses := make([]v1alpha2.ListenerStatus, len(gateway.Spec.Listeners)) + listenerStatuses := make([]gatev1alpha2.ListenerStatus, len(gateway.Spec.Listeners)) allocatedListeners := make(map[string]struct{}) for i, listener := range gateway.Spec.Listeners { - listenerStatuses[i] = v1alpha2.ListenerStatus{ + listenerStatuses[i] = gatev1alpha2.ListenerStatus{ Name: listener.Name, - SupportedKinds: []v1alpha2.RouteGroupKind{}, + SupportedKinds: []gatev1alpha2.RouteGroupKind{}, Conditions: []metav1.Condition{}, } @@ -345,7 +345,7 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * if _, ok := allocatedListeners[listenerKey]; ok { listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionConflicted), + Type: string(gatev1alpha2.ListenerConditionConflicted), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), Reason: "DuplicateListener", @@ -361,19 +361,19 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * if err != nil { // update "Detached" status with "PortUnavailable" reason listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonPortUnavailable), + Reason: string(gatev1alpha2.ListenerReasonPortUnavailable), Message: fmt.Sprintf("Cannot find entryPoint for Gateway: %v", err), }) continue } - if (listener.Protocol == v1alpha2.HTTPProtocolType || listener.Protocol == v1alpha2.TCPProtocolType) && listener.TLS != nil { + if (listener.Protocol == gatev1alpha2.HTTPProtocolType || listener.Protocol == gatev1alpha2.TCPProtocolType) && listener.TLS != nil { listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), Reason: "InvalidTLSConfiguration", // TODO check the spec if a proper reason is introduced at some point @@ -384,11 +384,11 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * } // TLS - if listener.Protocol == v1alpha2.HTTPSProtocolType || listener.Protocol == v1alpha2.TLSProtocolType { - if listener.TLS == nil || (len(listener.TLS.CertificateRefs) == 0 && listener.TLS.Mode != nil && *listener.TLS.Mode != v1alpha2.TLSModePassthrough) { + if listener.Protocol == gatev1alpha2.HTTPSProtocolType || listener.Protocol == gatev1alpha2.TLSProtocolType { + if listener.TLS == nil || (len(listener.TLS.CertificateRefs) == 0 && listener.TLS.Mode != nil && *listener.TLS.Mode != gatev1alpha2.TLSModePassthrough) { // update "Detached" status with "UnsupportedProtocol" reason listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), Reason: "InvalidTLSConfiguration", // TODO check the spec if a proper reason is introduced at some point @@ -399,12 +399,12 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * continue } - var tlsModeType v1alpha2.TLSModeType + var tlsModeType gatev1alpha2.TLSModeType if listener.TLS.Mode != nil { tlsModeType = *listener.TLS.Mode } - isTLSPassthrough := tlsModeType == v1alpha2.TLSModePassthrough + isTLSPassthrough := tlsModeType == gatev1alpha2.TLSModePassthrough if isTLSPassthrough && len(listener.TLS.CertificateRefs) > 0 { // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.GatewayTLSConfig @@ -415,12 +415,12 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * // Protocol TLS -> Passthrough -> TLSRoute/TCPRoute // Protocol TLS -> Terminate -> TLSRoute/TCPRoute // Protocol HTTPS -> Terminate -> HTTPRoute - if listener.Protocol == v1alpha2.HTTPSProtocolType && isTLSPassthrough { + if listener.Protocol == gatev1alpha2.HTTPSProtocolType && isTLSPassthrough { listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonUnsupportedProtocol), + Reason: string(gatev1alpha2.ListenerReasonUnsupportedProtocol), Message: "HTTPS protocol is not supported with TLS mode Passthrough", }) @@ -431,10 +431,10 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * if len(listener.TLS.CertificateRefs) == 0 { // update "ResolvedRefs" status true with "InvalidCertificateRef" reason listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonInvalidCertificateRef), + Reason: string(gatev1alpha2.ListenerReasonInvalidCertificateRef), Message: "One TLS CertificateRef is required in Terminate mode", }) @@ -448,10 +448,10 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * certificateRef.Group == nil || (*certificateRef.Group != "" && *certificateRef.Group != "core") { // update "ResolvedRefs" status true with "InvalidCertificateRef" reason listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonInvalidCertificateRef), + Reason: string(gatev1alpha2.ListenerReasonInvalidCertificateRef), Message: fmt.Sprintf("Unsupported TLS CertificateRef group/kind: %v/%v", certificateRef.Group, certificateRef.Kind), }) @@ -461,10 +461,10 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * // TODO Support ReferencePolicy to support cross namespace references. if certificateRef.Namespace != nil && string(*certificateRef.Namespace) != gateway.Namespace { listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonInvalidCertificateRef), + Reason: string(gatev1alpha2.ListenerReasonInvalidCertificateRef), Message: "Cross namespace secrets are not supported", }) @@ -477,10 +477,10 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * if err != nil { // update "ResolvedRefs" status true with "InvalidCertificateRef" reason listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonInvalidCertificateRef), + Reason: string(gatev1alpha2.ListenerReasonInvalidCertificateRef), Message: fmt.Sprintf("Error while retrieving certificate: %v", err), }) @@ -507,10 +507,10 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway * return listenerStatuses } -func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) (v1alpha2.GatewayStatus, error) { +func (p *Provider) makeGatewayStatus(listenerStatuses []gatev1alpha2.ListenerStatus) (gatev1alpha2.GatewayStatus, error) { // As Status.Addresses are not implemented yet, we initialize an empty array to follow the API expectations. - gatewayStatus := v1alpha2.GatewayStatus{ - Addresses: []v1alpha2.GatewayAddress{}, + gatewayStatus := gatev1alpha2.GatewayStatus{ + Addresses: []gatev1alpha2.GatewayAddress{}, } var result error @@ -518,7 +518,7 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) if len(listener.Conditions) == 0 { // GatewayConditionReady "Ready", GatewayConditionReason "ListenerReady" listenerStatuses[i].Conditions = append(listenerStatuses[i].Conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionReady), + Type: string(gatev1alpha2.ListenerConditionReady), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), Reason: "ListenerReady", @@ -536,10 +536,10 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) if result != nil { // GatewayConditionReady "Ready", GatewayConditionReason "ListenersNotValid" gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{ - Type: string(v1alpha2.GatewayConditionReady), + Type: string(gatev1alpha2.GatewayConditionReady), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.GatewayReasonListenersNotValid), + Reason: string(gatev1alpha2.GatewayReasonListenersNotValid), Message: "All Listeners must be valid", }) @@ -551,7 +551,7 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) gatewayStatus.Conditions = append(gatewayStatus.Conditions, // update "Scheduled" status with "ResourcesAvailable" reason metav1.Condition{ - Type: string(v1alpha2.GatewayConditionScheduled), + Type: string(gatev1alpha2.GatewayConditionScheduled), Status: metav1.ConditionTrue, Reason: "ResourcesAvailable", Message: "Resources available", @@ -559,7 +559,7 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) }, // update "Ready" status with "ListenersValid" reason metav1.Condition{ - Type: string(v1alpha2.GatewayConditionReady), + Type: string(gatev1alpha2.GatewayConditionReady), Status: metav1.ConditionTrue, Reason: "ListenersValid", Message: "Listeners valid", @@ -570,14 +570,14 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha2.ListenerStatus) return gatewayStatus, nil } -func (p *Provider) entryPointName(port v1alpha2.PortNumber, protocol v1alpha2.ProtocolType) (string, error) { +func (p *Provider) entryPointName(port gatev1alpha2.PortNumber, protocol gatev1alpha2.ProtocolType) (string, error) { portStr := strconv.FormatInt(int64(port), 10) for name, entryPoint := range p.EntryPoints { if strings.HasSuffix(entryPoint.Address, ":"+portStr) { // If the protocol is HTTP the entryPoint must have no TLS conf - // Not relevant for v1alpha2.TLSProtocolType && v1alpha2.TCPProtocolType - if protocol == v1alpha2.HTTPProtocolType && entryPoint.HasHTTPTLSConf { + // Not relevant for gatev1alpha2.TLSProtocolType && gatev1alpha2.TCPProtocolType + if protocol == gatev1alpha2.HTTPProtocolType && entryPoint.HasHTTPTLSConf { continue } @@ -588,43 +588,43 @@ func (p *Provider) entryPointName(port v1alpha2.PortNumber, protocol v1alpha2.Pr return "", fmt.Errorf("no matching entryPoint for port %d and protocol %q", port, protocol) } -func supportedRouteKinds(protocol v1alpha2.ProtocolType) ([]v1alpha2.RouteGroupKind, []metav1.Condition) { - group := v1alpha2.Group(v1alpha2.GroupName) +func supportedRouteKinds(protocol gatev1alpha2.ProtocolType) ([]gatev1alpha2.RouteGroupKind, []metav1.Condition) { + group := gatev1alpha2.Group(gatev1alpha2.GroupName) switch protocol { - case v1alpha2.TCPProtocolType: - return []v1alpha2.RouteGroupKind{{Kind: kindTCPRoute, Group: &group}}, nil + case gatev1alpha2.TCPProtocolType: + return []gatev1alpha2.RouteGroupKind{{Kind: kindTCPRoute, Group: &group}}, nil - case v1alpha2.HTTPProtocolType, v1alpha2.HTTPSProtocolType: - return []v1alpha2.RouteGroupKind{{Kind: kindHTTPRoute, Group: &group}}, nil + case gatev1alpha2.HTTPProtocolType, gatev1alpha2.HTTPSProtocolType: + return []gatev1alpha2.RouteGroupKind{{Kind: kindHTTPRoute, Group: &group}}, nil - case v1alpha2.TLSProtocolType: - return []v1alpha2.RouteGroupKind{ + case gatev1alpha2.TLSProtocolType: + return []gatev1alpha2.RouteGroupKind{ {Kind: kindTCPRoute, Group: &group}, {Kind: kindTLSRoute, Group: &group}, }, nil } return nil, []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonUnsupportedProtocol), + Reason: string(gatev1alpha2.ListenerReasonUnsupportedProtocol), Message: fmt.Sprintf("Unsupported listener protocol %q", protocol), }} } -func getAllowedRouteKinds(listener v1alpha2.Listener, supportedKinds []v1alpha2.RouteGroupKind) ([]v1alpha2.RouteGroupKind, []metav1.Condition) { +func getAllowedRouteKinds(listener gatev1alpha2.Listener, supportedKinds []gatev1alpha2.RouteGroupKind) ([]gatev1alpha2.RouteGroupKind, []metav1.Condition) { if listener.AllowedRoutes == nil || len(listener.AllowedRoutes.Kinds) == 0 { return supportedKinds, nil } var ( - routeKinds []v1alpha2.RouteGroupKind + routeKinds []gatev1alpha2.RouteGroupKind conditions []metav1.Condition ) - uniqRouteKinds := map[v1alpha2.Kind]struct{}{} + uniqRouteKinds := map[gatev1alpha2.Kind]struct{}{} for _, routeKind := range listener.AllowedRoutes.Kinds { var isSupported bool for _, kind := range supportedKinds { @@ -636,10 +636,10 @@ func getAllowedRouteKinds(listener v1alpha2.Listener, supportedKinds []v1alpha2. if !isSupported { conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionDetached), + Type: string(gatev1alpha2.ListenerConditionDetached), Status: metav1.ConditionTrue, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonInvalidRouteKinds), + Reason: string(gatev1alpha2.ListenerReasonInvalidRouteKinds), Message: fmt.Sprintf("Listener protocol %q does not support RouteGroupKind %v/%s", listener.Protocol, routeKind.Group, routeKind.Kind), }) continue @@ -654,7 +654,7 @@ func getAllowedRouteKinds(listener v1alpha2.Listener, supportedKinds []v1alpha2. return routeKinds, conditions } -func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha2.Listener, gateway *v1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { +func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener gatev1alpha2.Listener, gateway *gatev1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { if listener.AllowedRoutes == nil { // Should not happen due to validation. return nil @@ -664,7 +664,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouteNamespacesSelector", // Should never happen as the selector is validated by kubernetes @@ -676,10 +676,10 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonRefNotPermitted), + Reason: string(gatev1alpha2.ListenerReasonRefNotPermitted), Message: fmt.Sprintf("Cannot fetch HTTPRoutes: %v", err), }} } @@ -705,7 +705,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha hostRule, err := hostRule(hostnames) if err != nil { conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouteHostname", // TODO check the spec if a proper reason is introduced at some point @@ -719,7 +719,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "UnsupportedPathOrHeaderType", // TODO check the spec if a proper reason is introduced at some point @@ -732,7 +732,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha EntryPoints: []string{ep}, } - if listener.Protocol == v1alpha2.HTTPSProtocolType && listener.TLS != nil { + if listener.Protocol == gatev1alpha2.HTTPSProtocolType && listener.TLS != nil { // TODO support let's encrypt router.TLS = &dynamic.RouterTLSConfig{} } @@ -743,7 +743,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouterKey", // Should never happen @@ -766,7 +766,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidBackendRefs", // TODO check the spec if a proper reason is introduced at some point @@ -795,7 +795,7 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha return conditions } -func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2.Listener, gateway *v1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { +func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener gatev1alpha2.Listener, gateway *gatev1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { if listener.AllowedRoutes == nil { // Should not happen due to validation. return nil @@ -805,7 +805,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouteNamespacesSelector", // TODO should never happen as the selector is validated by Kubernetes @@ -817,10 +817,10 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonRefNotPermitted), + Reason: string(gatev1alpha2.ListenerReasonRefNotPermitted), Message: fmt.Sprintf("Cannot fetch TCPRoutes: %v", err), }} } @@ -841,10 +841,10 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. EntryPoints: []string{ep}, } - if listener.Protocol == v1alpha2.TLSProtocolType && listener.TLS != nil { + if listener.Protocol == gatev1alpha2.TLSProtocolType && listener.TLS != nil { // TODO support let's encrypt router.TLS = &dynamic.RouterTCPTLSConfig{ - Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == v1alpha2.TLSModePassthrough, + Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1alpha2.TLSModePassthrough, } } @@ -854,7 +854,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouterKey", // Should never happen @@ -879,7 +879,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidBackendRefs", // TODO check the spec if a proper reason is introduced at some point @@ -925,7 +925,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. return conditions } -func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2.Listener, gateway *v1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { +func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener gatev1alpha2.Listener, gateway *gatev1alpha2.Gateway, client Client, conf *dynamic.Configuration) []metav1.Condition { if listener.AllowedRoutes == nil { // Should not happen due to validation. return nil @@ -935,7 +935,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouteNamespacesSelector", // TODO should never happen as the selector is validated by Kubernetes @@ -947,10 +947,10 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "InvalidRoutesRef" reason return []metav1.Condition{{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), - Reason: string(v1alpha2.ListenerReasonRefNotPermitted), + Reason: string(gatev1alpha2.ListenerReasonRefNotPermitted), Message: fmt.Sprintf("Cannot fetch TLSRoutes: %v", err), }} } @@ -977,7 +977,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidHostnames", // TODO check the spec if a proper reason is introduced at some point @@ -991,7 +991,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. Rule: rule, EntryPoints: []string{ep}, TLS: &dynamic.RouterTCPTLSConfig{ - Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == v1alpha2.TLSModePassthrough, + Passthrough: listener.TLS.Mode != nil && *listener.TLS.Mode == gatev1alpha2.TLSModePassthrough, }, } @@ -1001,7 +1001,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidRouterKey", // Should never happen @@ -1026,7 +1026,7 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. if err != nil { // update "ResolvedRefs" status true with "DroppedRoutes" reason conditions = append(conditions, metav1.Condition{ - Type: string(v1alpha2.ListenerConditionResolvedRefs), + Type: string(gatev1alpha2.ListenerConditionResolvedRefs), Status: metav1.ConditionFalse, LastTransitionTime: metav1.Now(), Reason: "InvalidBackendRefs", // TODO check the spec if a proper reason is introduced at some point @@ -1074,18 +1074,18 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. // Because of Kubernetes validation we admit that the given Hostnames are valid. // https://github.com/kubernetes-sigs/gateway-api/blob/ff9883da4cad8554cd300394f725ab3a27502785/apis/v1alpha2/shared_types.go#L252 -func matchingHostnames(listener v1alpha2.Listener, hostnames []v1alpha2.Hostname) []v1alpha2.Hostname { +func matchingHostnames(listener gatev1alpha2.Listener, hostnames []gatev1alpha2.Hostname) []gatev1alpha2.Hostname { if listener.Hostname == nil || *listener.Hostname == "" { return hostnames } if len(hostnames) == 0 { - return []v1alpha2.Hostname{*listener.Hostname} + return []gatev1alpha2.Hostname{*listener.Hostname} } listenerLabels := strings.Split(string(*listener.Hostname), ".") - var matches []v1alpha2.Hostname + var matches []gatev1alpha2.Hostname for _, hostname := range hostnames { if hostname == *listener.Hostname { @@ -1116,9 +1116,9 @@ func matchingHostnames(listener v1alpha2.Listener, hostnames []v1alpha2.Hostname return matches } -func shouldAttach(gateway *v1alpha2.Gateway, listener v1alpha2.Listener, routeNamespace string, routeSpec v1alpha2.CommonRouteSpec) bool { +func shouldAttach(gateway *gatev1alpha2.Gateway, listener gatev1alpha2.Listener, routeNamespace string, routeSpec gatev1alpha2.CommonRouteSpec) bool { for _, parentRef := range routeSpec.ParentRefs { - if parentRef.Group == nil || *parentRef.Group != v1alpha2.GroupName { + if parentRef.Group == nil || *parentRef.Group != gatev1alpha2.GroupName { continue } @@ -1143,19 +1143,19 @@ func shouldAttach(gateway *v1alpha2.Gateway, listener v1alpha2.Listener, routeNa return false } -func getRouteBindingSelectorNamespace(client Client, gatewayNamespace string, routeNamespaces *v1alpha2.RouteNamespaces) ([]string, error) { +func getRouteBindingSelectorNamespace(client Client, gatewayNamespace string, routeNamespaces *gatev1alpha2.RouteNamespaces) ([]string, error) { if routeNamespaces == nil || routeNamespaces.From == nil { return []string{gatewayNamespace}, nil } switch *routeNamespaces.From { - case v1alpha2.NamespacesFromAll: + case gatev1alpha2.NamespacesFromAll: return []string{metav1.NamespaceAll}, nil - case v1alpha2.NamespacesFromSame: + case gatev1alpha2.NamespacesFromSame: return []string{gatewayNamespace}, nil - case v1alpha2.NamespacesFromSelector: + case gatev1alpha2.NamespacesFromSelector: selector, err := metav1.LabelSelectorAsSelector(routeNamespaces.Selector) if err != nil { return nil, fmt.Errorf("malformed selector: %w", err) @@ -1167,7 +1167,7 @@ func getRouteBindingSelectorNamespace(client Client, gatewayNamespace string, ro return nil, fmt.Errorf("unsupported RouteSelectType: %q", *routeNamespaces.From) } -func hostRule(hostnames []v1alpha2.Hostname) (string, error) { +func hostRule(hostnames []gatev1alpha2.Hostname) (string, error) { var hostNames []string var hostRegexNames []string @@ -1212,9 +1212,9 @@ func hostRule(hostnames []v1alpha2.Hostname) (string, error) { return hostRegexp, nil } -func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { +func hostSNIRule(hostnames []gatev1alpha2.Hostname) (string, error) { var matchers []string - uniqHostnames := map[v1alpha2.Hostname]struct{}{} + uniqHostnames := map[gatev1alpha2.Hostname]struct{}{} for _, hostname := range hostnames { if len(hostname) == 0 { @@ -1243,7 +1243,7 @@ func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { return "HostSNI(" + strings.Join(matchers, ",") + ")", nil } -func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, error) { +func extractRule(routeRule gatev1alpha2.HTTPRouteRule, hostRule string) (string, error) { var rule string var matchesRules []string @@ -1257,9 +1257,9 @@ func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, err if match.Path != nil && match.Path.Type != nil && match.Path.Value != nil { // TODO handle other path types switch *match.Path.Type { - case v1alpha2.PathMatchExact: + case gatev1alpha2.PathMatchExact: matchRules = append(matchRules, fmt.Sprintf("Path(`%s`)", *match.Path.Value)) - case v1alpha2.PathMatchPathPrefix: + case gatev1alpha2.PathMatchPathPrefix: matchRules = append(matchRules, fmt.Sprintf("PathPrefix(`%s`)", *match.Path.Value)) default: return "", fmt.Errorf("unsupported path match %s", *match.Path.Type) @@ -1300,7 +1300,7 @@ func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, err return rule + "(" + strings.Join(matchesRules, " || ") + ")", nil } -func extractHeaderRules(headers []v1alpha2.HTTPHeaderMatch) ([]string, error) { +func extractHeaderRules(headers []gatev1alpha2.HTTPHeaderMatch) ([]string, error) { var headerRules []string // TODO handle other headers types @@ -1311,7 +1311,7 @@ func extractHeaderRules(headers []v1alpha2.HTTPHeaderMatch) ([]string, error) { } switch *header.Type { - case v1alpha2.HeaderMatchExact: + case gatev1alpha2.HeaderMatchExact: headerRules = append(headerRules, fmt.Sprintf("Headers(`%s`,`%s`)", header.Name, header.Value)) default: return nil, fmt.Errorf("unsupported header match type %s", *header.Type) @@ -1340,7 +1340,7 @@ func makeID(namespace, name string) string { return namespace + "-" + name } -func getTLS(k8sClient Client, secretName v1alpha2.ObjectName, namespace string) (*tls.CertAndStores, error) { +func getTLS(k8sClient Client, secretName gatev1alpha2.ObjectName, namespace string) (*tls.CertAndStores, error) { secret, exists, err := k8sClient.GetSecret(namespace, string(secretName)) if err != nil { return nil, fmt.Errorf("failed to fetch secret %s/%s: %w", namespace, secretName, err) @@ -1414,7 +1414,7 @@ func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) ( } // loadServices is generating a WRR service, even when there is only one target. -func loadServices(client Client, namespace string, backendRefs []v1alpha2.HTTPBackendRef) (*dynamic.Service, map[string]*dynamic.Service, error) { +func loadServices(client Client, namespace string, backendRefs []gatev1alpha2.HTTPBackendRef) (*dynamic.Service, map[string]*dynamic.Service, error) { services := map[string]*dynamic.Service{} wrrSvc := &dynamic.Service{ @@ -1538,7 +1538,7 @@ func loadServices(client Client, namespace string, backendRefs []v1alpha2.HTTPBa } // loadTCPServices is generating a WRR service, even when there is only one target. -func loadTCPServices(client Client, namespace string, backendRefs []v1alpha2.BackendRef) (*dynamic.TCPService, map[string]*dynamic.TCPService, error) { +func loadTCPServices(client Client, namespace string, backendRefs []gatev1alpha2.BackendRef) (*dynamic.TCPService, map[string]*dynamic.TCPService, error) { services := map[string]*dynamic.TCPService{} wrrSvc := &dynamic.TCPService{ @@ -1695,7 +1695,7 @@ func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *s return eventsChanBuffered } -func isTraefikService(ref v1alpha2.BackendRef) bool { +func isTraefikService(ref gatev1alpha2.BackendRef) bool { if ref.Kind == nil || ref.Group == nil { return false } @@ -1703,13 +1703,13 @@ func isTraefikService(ref v1alpha2.BackendRef) bool { return (*ref.Group == containousv1alpha1.GroupName || *ref.Group == traefikv1alpha1.GroupName) && *ref.Kind == kindTraefikService } -func isInternalService(ref v1alpha2.BackendRef) bool { +func isInternalService(ref gatev1alpha2.BackendRef) bool { return isTraefikService(ref) && strings.HasSuffix(string(ref.Name), "@internal") } // makeListenerKey joins protocol, hostname, and port of a listener into a string key. -func makeListenerKey(l v1alpha2.Listener) string { - var hostname v1alpha2.Hostname +func makeListenerKey(l gatev1alpha2.Listener) string { + var hostname gatev1alpha2.Hostname if l.Hostname != nil { hostname = *l.Hostname } diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index a3ce54924..2f13d0d9f 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -11,7 +11,7 @@ import ( "github.com/traefik/traefik/v2/pkg/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" - "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) var _ provider.Provider = (*Provider)(nil) @@ -4269,7 +4269,7 @@ func TestLoadMixedRoutes(t *testing.T) { func Test_hostRule(t *testing.T) { testCases := []struct { desc string - hostnames []v1alpha2.Hostname + hostnames []gatev1alpha2.Hostname expectedRule string expectErr bool }{ @@ -4279,14 +4279,14 @@ func Test_hostRule(t *testing.T) { }, { desc: "One Host", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "Foo", }, expectedRule: "Host(`Foo`)", }, { desc: "Multiple Hosts", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "Foo", "Bar", "Bir", @@ -4295,7 +4295,7 @@ func Test_hostRule(t *testing.T) { }, { desc: "Multiple Hosts with empty one", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "Foo", "", "Bir", @@ -4304,7 +4304,7 @@ func Test_hostRule(t *testing.T) { }, { desc: "Multiple empty hosts", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "", "", "", @@ -4313,7 +4313,7 @@ func Test_hostRule(t *testing.T) { }, { desc: "Several Host and wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "*.bar.foo", "bar.foo", "foo.foo", @@ -4322,21 +4322,21 @@ func Test_hostRule(t *testing.T) { }, { desc: "Host with wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "*.bar.foo", }, expectedRule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.bar.foo`)", }, { desc: "Alone wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "*", "*.foo.foo", }, }, { desc: "Multiple alone Wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "foo.foo", "*.*", }, @@ -4344,7 +4344,7 @@ func Test_hostRule(t *testing.T) { }, { desc: "Multiple Wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "foo.foo", "*.toto.*.bar.foo", }, @@ -4352,7 +4352,7 @@ func Test_hostRule(t *testing.T) { }, { desc: "Multiple subdomain with misplaced wildcard", - hostnames: []v1alpha2.Hostname{ + hostnames: []gatev1alpha2.Hostname{ "foo.foo", "toto.*.bar.foo", }, @@ -4377,7 +4377,7 @@ func Test_hostRule(t *testing.T) { func Test_extractRule(t *testing.T) { testCases := []struct { desc string - routeRule v1alpha2.HTTPRouteRule + routeRule gatev1alpha2.HTTPRouteRule hostRule string expectedRule string expectedError bool @@ -4393,8 +4393,8 @@ func Test_extractRule(t *testing.T) { }, { desc: "One HTTPRouteMatch with nil HTTPHeaderMatch", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ {Headers: nil}, }, }, @@ -4402,10 +4402,10 @@ func Test_extractRule(t *testing.T) { }, { desc: "One HTTPRouteMatch with nil HTTPHeaderMatch Type", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Headers: []v1alpha2.HTTPHeaderMatch{ + Headers: []gatev1alpha2.HTTPHeaderMatch{ {Type: nil, Name: "foo", Value: "bar"}, }, }, @@ -4415,8 +4415,8 @@ func Test_extractRule(t *testing.T) { }, { desc: "One HTTPRouteMatch with nil HTTPPathMatch", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ {Path: nil}, }, }, @@ -4424,10 +4424,10 @@ func Test_extractRule(t *testing.T) { }, { desc: "One HTTPRouteMatch with nil HTTPPathMatch Type", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ + Path: &gatev1alpha2.HTTPPathMatch{ Type: nil, Value: pointer.String("/foo/"), }, @@ -4438,11 +4438,11 @@ func Test_extractRule(t *testing.T) { }, { desc: "One HTTPRouteMatch with nil HTTPPathMatch Values", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: nil, }, }, @@ -4452,11 +4452,11 @@ func Test_extractRule(t *testing.T) { }, { desc: "One Path in matches", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, }, @@ -4466,16 +4466,16 @@ func Test_extractRule(t *testing.T) { }, { desc: "One Path in matches and another unknown", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, }, { - Path: &v1alpha2.HTTPPathMatch{ + Path: &gatev1alpha2.HTTPPathMatch{ Type: pathMatchTypePtr("unknown"), Value: pointer.String("/foo/"), }, @@ -4486,11 +4486,11 @@ func Test_extractRule(t *testing.T) { }, { desc: "One Path in matches and another empty", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, }, @@ -4501,18 +4501,18 @@ func Test_extractRule(t *testing.T) { }, { desc: "Path OR Header rules", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, }, { - Headers: []v1alpha2.HTTPHeaderMatch{ + Headers: []gatev1alpha2.HTTPHeaderMatch{ { - Type: headerMatchTypePtr(v1alpha2.HeaderMatchExact), + Type: headerMatchTypePtr(gatev1alpha2.HeaderMatchExact), Name: "my-header", Value: "foo", }, @@ -4524,16 +4524,16 @@ func Test_extractRule(t *testing.T) { }, { desc: "Path && Header rules", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, - Headers: []v1alpha2.HTTPHeaderMatch{ + Headers: []gatev1alpha2.HTTPHeaderMatch{ { - Type: headerMatchTypePtr(v1alpha2.HeaderMatchExact), + Type: headerMatchTypePtr(gatev1alpha2.HeaderMatchExact), Name: "my-header", Value: "foo", }, @@ -4546,16 +4546,16 @@ func Test_extractRule(t *testing.T) { { desc: "Host && Path && Header rules", hostRule: "Host(`foo.com`)", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, - Headers: []v1alpha2.HTTPHeaderMatch{ + Headers: []gatev1alpha2.HTTPHeaderMatch{ { - Type: headerMatchTypePtr(v1alpha2.HeaderMatchExact), + Type: headerMatchTypePtr(gatev1alpha2.HeaderMatchExact), Name: "my-header", Value: "foo", }, @@ -4568,18 +4568,18 @@ func Test_extractRule(t *testing.T) { { desc: "Host && (Path || Header) rules", hostRule: "Host(`foo.com`)", - routeRule: v1alpha2.HTTPRouteRule{ - Matches: []v1alpha2.HTTPRouteMatch{ + routeRule: gatev1alpha2.HTTPRouteRule{ + Matches: []gatev1alpha2.HTTPRouteMatch{ { - Path: &v1alpha2.HTTPPathMatch{ - Type: pathMatchTypePtr(v1alpha2.PathMatchExact), + Path: &gatev1alpha2.HTTPPathMatch{ + Type: pathMatchTypePtr(gatev1alpha2.PathMatchExact), Value: pointer.String("/foo/"), }, }, { - Headers: []v1alpha2.HTTPHeaderMatch{ + Headers: []gatev1alpha2.HTTPHeaderMatch{ { - Type: headerMatchTypePtr(v1alpha2.HeaderMatchExact), + Type: headerMatchTypePtr(gatev1alpha2.HeaderMatchExact), Name: "my-header", Value: "foo", }, @@ -4611,7 +4611,7 @@ func Test_extractRule(t *testing.T) { func Test_hostSNIRule(t *testing.T) { testCases := []struct { desc string - hostnames []v1alpha2.Hostname + hostnames []gatev1alpha2.Hostname expectedRule string expectError bool }{ @@ -4621,37 +4621,37 @@ func Test_hostSNIRule(t *testing.T) { }, { desc: "Empty hostname", - hostnames: []v1alpha2.Hostname{""}, + hostnames: []gatev1alpha2.Hostname{""}, expectedRule: "HostSNI(`*`)", }, { desc: "Unsupported wildcard", - hostnames: []v1alpha2.Hostname{"*"}, + hostnames: []gatev1alpha2.Hostname{"*"}, expectError: true, }, { desc: "Multiple malformed wildcard", - hostnames: []v1alpha2.Hostname{"*.foo.*"}, + hostnames: []gatev1alpha2.Hostname{"*.foo.*"}, expectError: true, }, { desc: "Some empty hostnames", - hostnames: []v1alpha2.Hostname{"foo", "", "bar"}, + hostnames: []gatev1alpha2.Hostname{"foo", "", "bar"}, expectedRule: "HostSNI(`foo`,`bar`)", }, { desc: "Valid hostname", - hostnames: []v1alpha2.Hostname{"foo"}, + hostnames: []gatev1alpha2.Hostname{"foo"}, expectedRule: "HostSNI(`foo`)", }, { desc: "Multiple valid hostnames", - hostnames: []v1alpha2.Hostname{"foo", "bar"}, + hostnames: []gatev1alpha2.Hostname{"foo", "bar"}, expectedRule: "HostSNI(`foo`,`bar`)", }, { desc: "Multiple overlapping hostnames", - hostnames: []v1alpha2.Hostname{"foo", "bar", "foo", "baz"}, + hostnames: []gatev1alpha2.Hostname{"foo", "bar", "foo", "baz"}, expectedRule: "HostSNI(`foo`,`bar`,`baz`)", }, } @@ -4676,49 +4676,49 @@ func Test_hostSNIRule(t *testing.T) { func Test_shouldAttach(t *testing.T) { testCases := []struct { desc string - gateway *v1alpha2.Gateway - listener v1alpha2.Listener + gateway *gatev1alpha2.Gateway + listener gatev1alpha2.Listener routeNamespace string - routeSpec v1alpha2.CommonRouteSpec + routeSpec gatev1alpha2.CommonRouteSpec expectedAttach bool }{ { desc: "No ParentRefs", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ + routeSpec: gatev1alpha2.CommonRouteSpec{ ParentRefs: nil, }, expectedAttach: false, }, { desc: "Unsupported Kind", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", Namespace: namespacePtr("default"), Kind: kindPtr("Foo"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4726,18 +4726,18 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Unsupported Group", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", @@ -4751,23 +4751,23 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Kind is nil", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", Namespace: namespacePtr("default"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4775,18 +4775,18 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Group is nil", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", @@ -4799,23 +4799,23 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "SectionName does not match a listener desc", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", Namespace: namespacePtr("default"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), Kind: kindPtr("Gateway"), }, }, @@ -4824,23 +4824,23 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Namespace does not match the Gateway namespace", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", Namespace: namespacePtr("bar"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), Kind: kindPtr("Gateway"), }, }, @@ -4849,22 +4849,22 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Route namespace does not match the Gateway namespace", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "bar", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), Kind: kindPtr("Gateway"), }, }, @@ -4873,24 +4873,24 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Unsupported Kind", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("bar"), Name: "gateway", Namespace: namespacePtr("default"), Kind: kindPtr("Gateway"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4898,23 +4898,23 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Route namespace matches the Gateway namespace", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "default", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("foo"), Name: "gateway", Kind: kindPtr("Gateway"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4922,24 +4922,24 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Namespace matches the Gateway namespace", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "bar", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { SectionName: sectionNamePtr("foo"), Name: "gateway", Namespace: namespacePtr("default"), Kind: kindPtr("Gateway"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4947,29 +4947,29 @@ func Test_shouldAttach(t *testing.T) { }, { desc: "Only one ParentRef matches the Gateway", - gateway: &v1alpha2.Gateway{ + gateway: &gatev1alpha2.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "gateway", Namespace: "default", }, }, - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Name: "foo", }, routeNamespace: "bar", - routeSpec: v1alpha2.CommonRouteSpec{ - ParentRefs: []v1alpha2.ParentRef{ + routeSpec: gatev1alpha2.CommonRouteSpec{ + ParentRefs: []gatev1alpha2.ParentRef{ { Name: "gateway2", Namespace: namespacePtr("default"), Kind: kindPtr("Gateway"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, { Name: "gateway", Namespace: namespacePtr("default"), Kind: kindPtr("Gateway"), - Group: groupPtr(v1alpha2.GroupName), + Group: groupPtr(gatev1alpha2.GroupName), }, }, }, @@ -4991,93 +4991,93 @@ func Test_shouldAttach(t *testing.T) { func Test_matchingHostnames(t *testing.T) { testCases := []struct { desc string - listener v1alpha2.Listener - hostnames []v1alpha2.Hostname - want []v1alpha2.Hostname + listener gatev1alpha2.Listener + hostnames []gatev1alpha2.Hostname + want []gatev1alpha2.Hostname }{ { desc: "Empty", }, { desc: "Only listener hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("foo.com"), }, - want: []v1alpha2.Hostname{"foo.com"}, + want: []gatev1alpha2.Hostname{"foo.com"}, }, { desc: "Only Route hostname", - hostnames: []v1alpha2.Hostname{"foo.com"}, - want: []v1alpha2.Hostname{"foo.com"}, + hostnames: []gatev1alpha2.Hostname{"foo.com"}, + want: []gatev1alpha2.Hostname{"foo.com"}, }, { desc: "Matching hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("foo.com"), }, - hostnames: []v1alpha2.Hostname{"foo.com"}, - want: []v1alpha2.Hostname{"foo.com"}, + hostnames: []gatev1alpha2.Hostname{"foo.com"}, + want: []gatev1alpha2.Hostname{"foo.com"}, }, { desc: "Matching hostname with wildcard", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.foo.com"), }, - hostnames: []v1alpha2.Hostname{"*.foo.com"}, - want: []v1alpha2.Hostname{"*.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"*.foo.com"}, + want: []gatev1alpha2.Hostname{"*.foo.com"}, }, { desc: "Matching subdomain with listener wildcard", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.foo.com"), }, - hostnames: []v1alpha2.Hostname{"bar.foo.com"}, - want: []v1alpha2.Hostname{"bar.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"bar.foo.com"}, + want: []gatev1alpha2.Hostname{"bar.foo.com"}, }, { desc: "Matching subdomain with route hostname wildcard", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("bar.foo.com"), }, - hostnames: []v1alpha2.Hostname{"*.foo.com"}, - want: []v1alpha2.Hostname{"bar.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"*.foo.com"}, + want: []gatev1alpha2.Hostname{"bar.foo.com"}, }, { desc: "Non matching root domain with listener wildcard", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.foo.com"), }, - hostnames: []v1alpha2.Hostname{"foo.com"}, + hostnames: []gatev1alpha2.Hostname{"foo.com"}, }, { desc: "Non matching root domain with route hostname wildcard", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("foo.com"), }, - hostnames: []v1alpha2.Hostname{"*.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"*.foo.com"}, }, { desc: "Multiple route hostnames with one matching route hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.foo.com"), }, - hostnames: []v1alpha2.Hostname{"bar.com", "test.foo.com", "test.buz.com"}, - want: []v1alpha2.Hostname{"test.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"bar.com", "test.foo.com", "test.buz.com"}, + want: []gatev1alpha2.Hostname{"test.foo.com"}, }, { desc: "Multiple route hostnames with non matching route hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.fuz.com"), }, - hostnames: []v1alpha2.Hostname{"bar.com", "test.foo.com", "test.buz.com"}, + hostnames: []gatev1alpha2.Hostname{"bar.com", "test.foo.com", "test.buz.com"}, }, { desc: "Multiple route hostnames with multiple matching route hostnames", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Hostname: hostnamePtr("*.foo.com"), }, - hostnames: []v1alpha2.Hostname{"toto.foo.com", "test.foo.com", "test.buz.com"}, - want: []v1alpha2.Hostname{"toto.foo.com", "test.foo.com"}, + hostnames: []gatev1alpha2.Hostname{"toto.foo.com", "test.foo.com", "test.buz.com"}, + want: []gatev1alpha2.Hostname{"toto.foo.com", "test.foo.com"}, }, } @@ -5095,9 +5095,9 @@ func Test_matchingHostnames(t *testing.T) { func Test_getAllowedRoutes(t *testing.T) { testCases := []struct { desc string - listener v1alpha2.Listener - supportedRouteKinds []v1alpha2.RouteGroupKind - wantKinds []v1alpha2.RouteGroupKind + listener gatev1alpha2.Listener + supportedRouteKinds []gatev1alpha2.RouteGroupKind + wantKinds []gatev1alpha2.RouteGroupKind wantErr bool }{ { @@ -5105,90 +5105,90 @@ func Test_getAllowedRoutes(t *testing.T) { }, { desc: "Empty AllowedRoutes", - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, - wantKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + wantKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, }, { desc: "AllowedRoutes with unsupported Group", - listener: v1alpha2.Listener{ - AllowedRoutes: &v1alpha2.AllowedRoutes{ - Kinds: []v1alpha2.RouteGroupKind{{ + listener: gatev1alpha2.Listener{ + AllowedRoutes: &gatev1alpha2.AllowedRoutes{ + Kinds: []gatev1alpha2.RouteGroupKind{{ Kind: kindTLSRoute, Group: groupPtr("foo"), }}, }, }, - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, wantErr: true, }, { desc: "AllowedRoutes with nil Group", - listener: v1alpha2.Listener{ - AllowedRoutes: &v1alpha2.AllowedRoutes{ - Kinds: []v1alpha2.RouteGroupKind{{ + listener: gatev1alpha2.Listener{ + AllowedRoutes: &gatev1alpha2.AllowedRoutes{ + Kinds: []gatev1alpha2.RouteGroupKind{{ Kind: kindTLSRoute, Group: nil, }}, }, }, - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, wantErr: true, }, { desc: "AllowedRoutes with unsupported Kind", - listener: v1alpha2.Listener{ - AllowedRoutes: &v1alpha2.AllowedRoutes{ - Kinds: []v1alpha2.RouteGroupKind{{ - Kind: "foo", Group: groupPtr(v1alpha2.GroupName), + listener: gatev1alpha2.Listener{ + AllowedRoutes: &gatev1alpha2.AllowedRoutes{ + Kinds: []gatev1alpha2.RouteGroupKind{{ + Kind: "foo", Group: groupPtr(gatev1alpha2.GroupName), }}, }, }, - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, wantErr: true, }, { desc: "Supported AllowedRoutes", - listener: v1alpha2.Listener{ - AllowedRoutes: &v1alpha2.AllowedRoutes{ - Kinds: []v1alpha2.RouteGroupKind{{ - Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName), + listener: gatev1alpha2.Listener{ + AllowedRoutes: &gatev1alpha2.AllowedRoutes{ + Kinds: []gatev1alpha2.RouteGroupKind{{ + Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName), }}, }, }, - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, - wantKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, + wantKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, }, { desc: "Supported AllowedRoutes with duplicates", - listener: v1alpha2.Listener{ - AllowedRoutes: &v1alpha2.AllowedRoutes{ - Kinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, - {Kind: kindTCPRoute, Group: groupPtr(v1alpha2.GroupName)}, - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, - {Kind: kindTCPRoute, Group: groupPtr(v1alpha2.GroupName)}, + listener: gatev1alpha2.Listener{ + AllowedRoutes: &gatev1alpha2.AllowedRoutes{ + Kinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, + {Kind: kindTCPRoute, Group: groupPtr(gatev1alpha2.GroupName)}, + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, + {Kind: kindTCPRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, }, }, - supportedRouteKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, - {Kind: kindTCPRoute, Group: groupPtr(v1alpha2.GroupName)}, + supportedRouteKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, + {Kind: kindTCPRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, - wantKinds: []v1alpha2.RouteGroupKind{ - {Kind: kindTLSRoute, Group: groupPtr(v1alpha2.GroupName)}, - {Kind: kindTCPRoute, Group: groupPtr(v1alpha2.GroupName)}, + wantKinds: []gatev1alpha2.RouteGroupKind{ + {Kind: kindTLSRoute, Group: groupPtr(gatev1alpha2.GroupName)}, + {Kind: kindTCPRoute, Group: groupPtr(gatev1alpha2.GroupName)}, }, }, } @@ -5213,7 +5213,7 @@ func Test_getAllowedRoutes(t *testing.T) { func Test_makeListenerKey(t *testing.T) { testCases := []struct { desc string - listener v1alpha2.Listener + listener gatev1alpha2.Listener expectedKey string }{ { @@ -5222,18 +5222,18 @@ func Test_makeListenerKey(t *testing.T) { }, { desc: "listener with port, protocol and hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Port: 443, - Protocol: v1alpha2.HTTPSProtocolType, + Protocol: gatev1alpha2.HTTPSProtocolType, Hostname: hostnamePtr("www.example.com"), }, expectedKey: "HTTPS|www.example.com|443", }, { desc: "listener with port, protocol and nil hostname", - listener: v1alpha2.Listener{ + listener: gatev1alpha2.Listener{ Port: 443, - Protocol: v1alpha2.HTTPSProtocolType, + Protocol: gatev1alpha2.HTTPSProtocolType, }, expectedKey: "HTTPS||443", }, @@ -5249,26 +5249,26 @@ func Test_makeListenerKey(t *testing.T) { } } -func hostnamePtr(hostname v1alpha2.Hostname) *v1alpha2.Hostname { +func hostnamePtr(hostname gatev1alpha2.Hostname) *gatev1alpha2.Hostname { return &hostname } -func groupPtr(group v1alpha2.Group) *v1alpha2.Group { +func groupPtr(group gatev1alpha2.Group) *gatev1alpha2.Group { return &group } -func sectionNamePtr(sectionName v1alpha2.SectionName) *v1alpha2.SectionName { +func sectionNamePtr(sectionName gatev1alpha2.SectionName) *gatev1alpha2.SectionName { return §ionName } -func namespacePtr(namespace v1alpha2.Namespace) *v1alpha2.Namespace { +func namespacePtr(namespace gatev1alpha2.Namespace) *gatev1alpha2.Namespace { return &namespace } -func kindPtr(kind v1alpha2.Kind) *v1alpha2.Kind { +func kindPtr(kind gatev1alpha2.Kind) *gatev1alpha2.Kind { return &kind } -func pathMatchTypePtr(p v1alpha2.PathMatchType) *v1alpha2.PathMatchType { return &p } +func pathMatchTypePtr(p gatev1alpha2.PathMatchType) *gatev1alpha2.PathMatchType { return &p } -func headerMatchTypePtr(h v1alpha2.HeaderMatchType) *v1alpha2.HeaderMatchType { return &h } +func headerMatchTypePtr(h gatev1alpha2.HeaderMatchType) *gatev1alpha2.HeaderMatchType { return &h } diff --git a/pkg/provider/kubernetes/ingress/builder_ingress_test.go b/pkg/provider/kubernetes/ingress/builder_ingress_test.go index 56ba2d286..bd9bfb9a3 100644 --- a/pkg/provider/kubernetes/ingress/builder_ingress_test.go +++ b/pkg/provider/kubernetes/ingress/builder_ingress_test.go @@ -1,9 +1,9 @@ package ingress -import networkingv1 "k8s.io/api/networking/v1" +import netv1 "k8s.io/api/networking/v1" -func buildIngress(opts ...func(*networkingv1.Ingress)) *networkingv1.Ingress { - i := &networkingv1.Ingress{} +func buildIngress(opts ...func(*netv1.Ingress)) *netv1.Ingress { + i := &netv1.Ingress{} i.Kind = "Ingress" for _, opt := range opts { opt(i) @@ -11,15 +11,15 @@ func buildIngress(opts ...func(*networkingv1.Ingress)) *networkingv1.Ingress { return i } -func iNamespace(value string) func(*networkingv1.Ingress) { - return func(i *networkingv1.Ingress) { +func iNamespace(value string) func(*netv1.Ingress) { + return func(i *netv1.Ingress) { i.Namespace = value } } -func iRules(opts ...func(*networkingv1.IngressSpec)) func(*networkingv1.Ingress) { - return func(i *networkingv1.Ingress) { - s := &networkingv1.IngressSpec{} +func iRules(opts ...func(*netv1.IngressSpec)) func(*netv1.Ingress) { + return func(i *netv1.Ingress) { + s := &netv1.IngressSpec{} for _, opt := range opts { opt(s) } @@ -27,9 +27,9 @@ func iRules(opts ...func(*networkingv1.IngressSpec)) func(*networkingv1.Ingress) } } -func iRule(opts ...func(*networkingv1.IngressRule)) func(*networkingv1.IngressSpec) { - return func(spec *networkingv1.IngressSpec) { - r := &networkingv1.IngressRule{} +func iRule(opts ...func(*netv1.IngressRule)) func(*netv1.IngressSpec) { + return func(spec *netv1.IngressSpec) { + r := &netv1.IngressRule{} for _, opt := range opts { opt(r) } @@ -37,24 +37,24 @@ func iRule(opts ...func(*networkingv1.IngressRule)) func(*networkingv1.IngressSp } } -func iHost(name string) func(*networkingv1.IngressRule) { - return func(rule *networkingv1.IngressRule) { +func iHost(name string) func(*netv1.IngressRule) { + return func(rule *netv1.IngressRule) { rule.Host = name } } -func iTLSes(opts ...func(*networkingv1.IngressTLS)) func(*networkingv1.Ingress) { - return func(i *networkingv1.Ingress) { +func iTLSes(opts ...func(*netv1.IngressTLS)) func(*netv1.Ingress) { + return func(i *netv1.Ingress) { for _, opt := range opts { - iTLS := networkingv1.IngressTLS{} + iTLS := netv1.IngressTLS{} opt(&iTLS) i.Spec.TLS = append(i.Spec.TLS, iTLS) } } } -func iTLS(secret string, hosts ...string) func(*networkingv1.IngressTLS) { - return func(i *networkingv1.IngressTLS) { +func iTLS(secret string, hosts ...string) func(*netv1.IngressTLS) { + return func(i *netv1.IngressTLS) { i.SecretName = secret i.Hosts = hosts } diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index a2d6bfe31..3d2c002f4 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -14,14 +14,14 @@ import ( "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" traefikversion "github.com/traefik/traefik/v2/pkg/version" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" - kubeerror "k8s.io/apimachinery/pkg/api/errors" + netv1 "k8s.io/api/networking/v1" + netv1beta1 "k8s.io/api/networking/v1beta1" + kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/client-go/informers" - "k8s.io/client-go/kubernetes" + kinformers "k8s.io/client-go/informers" + kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -36,21 +36,21 @@ const ( // The stores can then be accessed via the Get* functions. type Client interface { WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) - GetIngresses() []*networkingv1.Ingress - GetIngressClasses() ([]*networkingv1.IngressClass, error) + GetIngresses() []*netv1.Ingress + GetIngressClasses() ([]*netv1.IngressClass, error) GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error) - UpdateIngressStatus(ing *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error + UpdateIngressStatus(ing *netv1.Ingress, ingStatus []netv1.IngressLoadBalancerIngress) error GetServerVersion() *version.Version } type clientWrapper struct { - clientset kubernetes.Interface - factoriesKube map[string]informers.SharedInformerFactory - factoriesSecret map[string]informers.SharedInformerFactory - factoriesIngress map[string]informers.SharedInformerFactory - clusterFactory informers.SharedInformerFactory + clientset kclientset.Interface + factoriesKube map[string]kinformers.SharedInformerFactory + factoriesSecret map[string]kinformers.SharedInformerFactory + factoriesIngress map[string]kinformers.SharedInformerFactory + clusterFactory kinformers.SharedInformerFactory ingressLabelSelector string isNamespaceAll bool watchedNamespaces []string @@ -113,7 +113,7 @@ func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { runtime.GOARCH, ) - clientset, err := kubernetes.NewForConfig(c) + clientset, err := kclientset.NewForConfig(c) if err != nil { return nil, err } @@ -121,12 +121,12 @@ func createClientFromConfig(c *rest.Config) (*clientWrapper, error) { return newClientImpl(clientset), nil } -func newClientImpl(clientset kubernetes.Interface) *clientWrapper { +func newClientImpl(clientset kclientset.Interface) *clientWrapper { return &clientWrapper{ clientset: clientset, - factoriesSecret: make(map[string]informers.SharedInformerFactory), - factoriesIngress: make(map[string]informers.SharedInformerFactory), - factoriesKube: make(map[string]informers.SharedInformerFactory), + factoriesSecret: make(map[string]kinformers.SharedInformerFactory), + factoriesIngress: make(map[string]kinformers.SharedInformerFactory), + factoriesKube: make(map[string]kinformers.SharedInformerFactory), } } @@ -164,7 +164,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } for _, ns := range namespaces { - factoryIngress := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(matchesLabelSelector)) + factoryIngress := kinformers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, kinformers.WithNamespace(ns), kinformers.WithTweakListOptions(matchesLabelSelector)) if supportsNetworkingV1Ingress(serverVersion) { _, err = factoryIngress.Networking().V1().Ingresses().Informer().AddEventHandler(eventHandler) @@ -180,7 +180,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< c.factoriesIngress[ns] = factoryIngress - factoryKube := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns)) + factoryKube := kinformers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, kinformers.WithNamespace(ns)) _, err = factoryKube.Core().V1().Services().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -191,7 +191,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } c.factoriesKube[ns] = factoryKube - factorySecret := informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(notOwnedByHelm)) + factorySecret := kinformers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod, kinformers.WithNamespace(ns), kinformers.WithTweakListOptions(notOwnedByHelm)) _, err = factorySecret.Core().V1().Secrets().Informer().AddEventHandler(eventHandler) if err != nil { return nil, err @@ -226,7 +226,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } if supportsIngressClass(serverVersion) { - c.clusterFactory = informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod) + c.clusterFactory = kinformers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod) if supportsNetworkingV1Ingress(serverVersion) { _, err = c.clusterFactory.Networking().V1().IngressClasses().Informer().AddEventHandler(eventHandler) @@ -253,8 +253,8 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } // GetIngresses returns all Ingresses for observed namespaces in the cluster. -func (c *clientWrapper) GetIngresses() []*networkingv1.Ingress { - var results []*networkingv1.Ingress +func (c *clientWrapper) GetIngresses() []*netv1.Ingress { + var results []*netv1.Ingress isNetworkingV1Supported := supportsNetworkingV1Ingress(c.serverVersion) @@ -279,7 +279,7 @@ func (c *clientWrapper) GetIngresses() []*networkingv1.Ingress { } for _, ing := range list { - n, err := convert[networkingv1.Ingress](ing) + n, err := convert[netv1.Ingress](ing) if err != nil { log.WithoutContext().Errorf("Failed to convert ingress %s from networking/v1beta1 to networking/v1: %v", ns, err) continue @@ -293,9 +293,9 @@ func (c *clientWrapper) GetIngresses() []*networkingv1.Ingress { return results } -func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingress) { +func addServiceFromV1Beta1(ing *netv1.Ingress, old netv1beta1.Ingress) { if old.Spec.Backend != nil { - port := networkingv1.ServiceBackendPort{} + port := netv1.ServiceBackendPort{} if old.Spec.Backend.ServicePort.Type == intstr.Int { port.Number = old.Spec.Backend.ServicePort.IntVal } else { @@ -303,8 +303,8 @@ func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingr } if old.Spec.Backend.ServiceName != "" { - ing.Spec.DefaultBackend = &networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ + ing.Spec.DefaultBackend = &netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ Name: old.Spec.Backend.ServiceName, Port: port, }, @@ -320,14 +320,14 @@ func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingr if path.Backend.Service == nil { oldBackend := old.Spec.Rules[rc].HTTP.Paths[pc].Backend - port := networkingv1.ServiceBackendPort{} + port := netv1.ServiceBackendPort{} if oldBackend.ServicePort.Type == intstr.Int { port.Number = oldBackend.ServicePort.IntVal } else { port.Name = oldBackend.ServicePort.StrVal } - svc := networkingv1.IngressServiceBackend{ + svc := netv1.IngressServiceBackend{ Name: oldBackend.ServiceName, Port: port, } @@ -339,7 +339,7 @@ func addServiceFromV1Beta1(ing *networkingv1.Ingress, old networkingv1beta1.Ingr } // UpdateIngressStatus updates an Ingress with a provided status. -func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error { +func (c *clientWrapper) UpdateIngressStatus(src *netv1.Ingress, ingStatus []netv1.IngressLoadBalancerIngress) error { if !c.isWatchedNamespace(src.Namespace) { return fmt.Errorf("failed to get ingress %s/%s: namespace is not within watched namespaces", src.Namespace, src.Name) } @@ -361,7 +361,7 @@ func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus } ingCopy := ing.DeepCopy() - ingCopy.Status = networkingv1.IngressStatus{LoadBalancer: networkingv1.IngressLoadBalancerStatus{Ingress: ingStatus}} + ingCopy.Status = netv1.IngressStatus{LoadBalancer: netv1.IngressLoadBalancerStatus{Ingress: ingStatus}} ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() @@ -375,7 +375,7 @@ func (c *clientWrapper) UpdateIngressStatus(src *networkingv1.Ingress, ingStatus return nil } -func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingStatus []networkingv1.IngressLoadBalancerIngress) error { +func (c *clientWrapper) updateIngressStatusOld(src *netv1.Ingress, ingStatus []netv1.IngressLoadBalancerIngress) error { ing, err := c.factoriesIngress[c.lookupNamespace(src.Namespace)].Networking().V1beta1().Ingresses().Lister().Ingresses(src.Namespace).Get(src.Name) if err != nil { return fmt.Errorf("failed to get ingress %s/%s: %w", src.Namespace, src.Name, err) @@ -383,7 +383,7 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingSta logger := log.WithoutContext().WithField("namespace", ing.Namespace).WithField("ingress", ing.Name) - ingresses, err := convertSlice[networkingv1.IngressLoadBalancerIngress](ing.Status.LoadBalancer.Ingress) + ingresses, err := convertSlice[netv1.IngressLoadBalancerIngress](ing.Status.LoadBalancer.Ingress) if err != nil { return err } @@ -393,13 +393,13 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingSta return nil } - ingressesBeta1, err := convertSlice[networkingv1beta1.IngressLoadBalancerIngress](ingStatus) + ingressesBeta1, err := convertSlice[netv1beta1.IngressLoadBalancerIngress](ingStatus) if err != nil { return err } ingCopy := ing.DeepCopy() - ingCopy.Status = networkingv1beta1.IngressStatus{LoadBalancer: networkingv1beta1.IngressLoadBalancerStatus{Ingress: ingressesBeta1}} + ingCopy.Status = netv1beta1.IngressStatus{LoadBalancer: netv1beta1.IngressLoadBalancerStatus{Ingress: ingressesBeta1}} ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() @@ -413,7 +413,7 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1.Ingress, ingSta } // isLoadBalancerIngressEquals returns true if the given slices are equal, false otherwise. -func isLoadBalancerIngressEquals(aSlice, bSlice []networkingv1.IngressLoadBalancerIngress) bool { +func isLoadBalancerIngressEquals(aSlice, bSlice []netv1.IngressLoadBalancerIngress) bool { if len(aSlice) != len(bSlice) { return false } @@ -465,12 +465,12 @@ func (c *clientWrapper) GetSecret(namespace, name string) (*corev1.Secret, bool, return secret, exist, err } -func (c *clientWrapper) GetIngressClasses() ([]*networkingv1.IngressClass, error) { +func (c *clientWrapper) GetIngressClasses() ([]*netv1.IngressClass, error) { if c.clusterFactory == nil { return nil, errors.New("cluster factory not loaded") } - var ics []*networkingv1.IngressClass + var ics []*netv1.IngressClass if !supportsNetworkingV1Ingress(c.serverVersion) { ingressClasses, err := c.clusterFactory.Networking().V1beta1().IngressClasses().Lister().List(labels.Everything()) if err != nil { @@ -479,7 +479,7 @@ func (c *clientWrapper) GetIngressClasses() ([]*networkingv1.IngressClass, error for _, ic := range ingressClasses { if ic.Spec.Controller == traefikDefaultIngressClassController { - icN, err := convert[networkingv1.IngressClass](ic) + icN, err := convert[netv1.IngressClass](ic) if err != nil { log.WithoutContext().Errorf("Failed to convert ingress class %s from networking/v1beta1 to networking/v1: %v", ic.Name, err) continue @@ -526,7 +526,7 @@ func (c *clientWrapper) GetServerVersion() *version.Version { // translateNotFoundError will translate a "not found" error to a boolean return // value which indicates if the resource exists and a nil error. func translateNotFoundError(err error) (bool, error) { - if kubeerror.IsNotFound(err) { + if kerror.IsNotFound(err) { return false, nil } return err == nil, err @@ -555,8 +555,8 @@ func supportsIngressClass(serverVersion *version.Version) bool { } // filterIngressClassByName return a slice containing ingressclasses with the correct name. -func filterIngressClassByName(ingressClassName string, ics []*networkingv1.IngressClass) []*networkingv1.IngressClass { - var ingressClasses []*networkingv1.IngressClass +func filterIngressClassByName(ingressClassName string, ics []*netv1.IngressClass) []*netv1.IngressClass { + var ingressClasses []*netv1.IngressClass for _, ic := range ics { if ic.Name == ingressClassName { diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index 21883ca67..3ee622c8d 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -7,18 +7,18 @@ import ( "github.com/hashicorp/go-version" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + netv1 "k8s.io/api/networking/v1" + netv1beta1 "k8s.io/api/networking/v1beta1" ) var _ Client = (*clientMock)(nil) type clientMock struct { - ingresses []*networkingv1.Ingress + ingresses []*netv1.Ingress services []*corev1.Service secrets []*corev1.Secret endpoints []*corev1.Endpoints - ingressClasses []*networkingv1.IngressClass + ingressClasses []*netv1.IngressClass serverVersion *version.Version @@ -50,22 +50,22 @@ func newClientMock(serverVersion string, paths ...string) clientMock { c.secrets = append(c.secrets, o) case *corev1.Endpoints: c.endpoints = append(c.endpoints, o) - case *networkingv1beta1.Ingress: - ing, err := convert[networkingv1.Ingress](o) + case *netv1beta1.Ingress: + ing, err := convert[netv1.Ingress](o) if err != nil { panic(err) } addServiceFromV1Beta1(ing, *o) c.ingresses = append(c.ingresses, ing) - case *networkingv1.Ingress: + case *netv1.Ingress: c.ingresses = append(c.ingresses, o) - case *networkingv1beta1.IngressClass: - ic, err := convert[networkingv1.IngressClass](o) + case *netv1beta1.IngressClass: + ic, err := convert[netv1.IngressClass](o) if err != nil { panic(err) } c.ingressClasses = append(c.ingressClasses, ic) - case *networkingv1.IngressClass: + case *netv1.IngressClass: c.ingressClasses = append(c.ingressClasses, o) default: panic(fmt.Sprintf("Unknown runtime object %+v %T", o, o)) @@ -76,7 +76,7 @@ func newClientMock(serverVersion string, paths ...string) clientMock { return c } -func (c clientMock) GetIngresses() []*networkingv1.Ingress { +func (c clientMock) GetIngresses() []*netv1.Ingress { return c.ingresses } @@ -124,7 +124,7 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err return nil, false, nil } -func (c clientMock) GetIngressClasses() ([]*networkingv1.IngressClass, error) { +func (c clientMock) GetIngressClasses() ([]*netv1.IngressClass, error) { return c.ingressClasses, nil } @@ -132,6 +132,6 @@ func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-cha return c.watchChan, nil } -func (c clientMock) UpdateIngressStatus(_ *networkingv1.Ingress, _ []networkingv1.IngressLoadBalancerIngress) error { +func (c clientMock) UpdateIngressStatus(_ *netv1.Ingress, _ []netv1.IngressLoadBalancerIngress) error { return c.apiIngressStatusError } diff --git a/pkg/provider/kubernetes/ingress/client_test.go b/pkg/provider/kubernetes/ingress/client_test.go index 11eb03f4b..402da8e45 100644 --- a/pkg/provider/kubernetes/ingress/client_test.go +++ b/pkg/provider/kubernetes/ingress/client_test.go @@ -9,13 +9,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - "k8s.io/api/networking/v1beta1" - kubeerror "k8s.io/apimachinery/pkg/api/errors" + netv1 "k8s.io/api/networking/v1" + netv1beta1 "k8s.io/api/networking/v1beta1" + kerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/version" - fakediscovery "k8s.io/client-go/discovery/fake" + kschema "k8s.io/apimachinery/pkg/runtime/schema" + kversion "k8s.io/apimachinery/pkg/version" + discoveryfake "k8s.io/client-go/discovery/fake" kubefake "k8s.io/client-go/kubernetes/fake" ) @@ -28,7 +28,7 @@ func TestTranslateNotFoundError(t *testing.T) { }{ { desc: "kubernetes not found error", - err: kubeerror.NewNotFound(schema.GroupResource{}, "foo"), + err: kerror.NewNotFound(kschema.GroupResource{}, "foo"), expectedExists: false, expectedError: nil, }, @@ -61,8 +61,8 @@ func TestTranslateNotFoundError(t *testing.T) { func TestIsLoadBalancerIngressEquals(t *testing.T) { testCases := []struct { desc string - aSlice []networkingv1.IngressLoadBalancerIngress - bSlice []networkingv1.IngressLoadBalancerIngress + aSlice []netv1.IngressLoadBalancerIngress + bSlice []netv1.IngressLoadBalancerIngress expectedEqual bool }{ { @@ -71,28 +71,28 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "not the same length", - bSlice: []networkingv1.IngressLoadBalancerIngress{ + bSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, expectedEqual: false, }, { desc: "same ordered content", - aSlice: []networkingv1.IngressLoadBalancerIngress{ + aSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, - bSlice: []networkingv1.IngressLoadBalancerIngress{ + bSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, }, expectedEqual: true, }, { desc: "same unordered content", - aSlice: []networkingv1.IngressLoadBalancerIngress{ + aSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []networkingv1.IngressLoadBalancerIngress{ + bSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.2", Hostname: "traefik2"}, {IP: "192.168.1.1", Hostname: "traefik"}, }, @@ -100,11 +100,11 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "different ordered content", - aSlice: []networkingv1.IngressLoadBalancerIngress{ + aSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []networkingv1.IngressLoadBalancerIngress{ + bSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik"}, }, @@ -112,11 +112,11 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) { }, { desc: "different unordered content", - aSlice: []networkingv1.IngressLoadBalancerIngress{ + aSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.1", Hostname: "traefik"}, {IP: "192.168.1.2", Hostname: "traefik2"}, }, - bSlice: []networkingv1.IngressLoadBalancerIngress{ + bSlice: []netv1.IngressLoadBalancerIngress{ {IP: "192.168.1.2", Hostname: "traefik3"}, {IP: "192.168.1.1", Hostname: "traefik"}, }, @@ -154,8 +154,8 @@ func TestClientIgnoresHelmOwnedSecrets(t *testing.T) { kubeClient := kubefake.NewSimpleClientset(helmSecret, secret) - discovery, _ := kubeClient.Discovery().(*fakediscovery.FakeDiscovery) - discovery.FakedServerVersion = &version.Info{ + discovery, _ := kubeClient.Discovery().(*discoveryfake.FakeDiscovery) + discovery.FakedServerVersion = &kversion.Info{ GitVersion: "v1.19", } @@ -223,8 +223,8 @@ func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) { kubeClient := kubefake.NewSimpleClientset(emptyEndpoint, filledEndpoint) - discovery, _ := kubeClient.Discovery().(*fakediscovery.FakeDiscovery) - discovery.FakedServerVersion = &version.Info{ + discovery, _ := kubeClient.Discovery().(*discoveryfake.FakeDiscovery) + discovery.FakedServerVersion = &kversion.Info{ GitVersion: "v1.19", } @@ -291,14 +291,14 @@ func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) { } func TestClientUsesCorrectServerVersion(t *testing.T) { - ingressV1Beta := &v1beta1.Ingress{ + ingressV1Beta := &netv1beta1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "ingress-v1beta", }, } - ingressV1 := &networkingv1.Ingress{ + ingressV1 := &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "ingress-v1", @@ -307,8 +307,8 @@ func TestClientUsesCorrectServerVersion(t *testing.T) { kubeClient := kubefake.NewSimpleClientset(ingressV1Beta, ingressV1) - discovery, _ := kubeClient.Discovery().(*fakediscovery.FakeDiscovery) - discovery.FakedServerVersion = &version.Info{ + discovery, _ := kubeClient.Discovery().(*discoveryfake.FakeDiscovery) + discovery.FakedServerVersion = &kversion.Info{ GitVersion: "v1.18.12+foobar", } @@ -321,7 +321,7 @@ func TestClientUsesCorrectServerVersion(t *testing.T) { select { case event := <-eventCh: - ingress, ok := event.(*v1beta1.Ingress) + ingress, ok := event.(*netv1beta1.Ingress) require.True(t, ok) assert.Equal(t, "ingress-v1beta", ingress.Name) @@ -335,7 +335,7 @@ func TestClientUsesCorrectServerVersion(t *testing.T) { case <-time.After(50 * time.Millisecond): } - discovery.FakedServerVersion = &version.Info{ + discovery.FakedServerVersion = &kversion.Info{ GitVersion: "v1.19", } @@ -344,7 +344,7 @@ func TestClientUsesCorrectServerVersion(t *testing.T) { select { case event := <-eventCh: - ingress, ok := event.(*networkingv1.Ingress) + ingress, ok := event.(*netv1.Ingress) require.True(t, ok) assert.Equal(t, "ingress-v1", ingress.Name) diff --git a/pkg/provider/kubernetes/ingress/convert.go b/pkg/provider/kubernetes/ingress/convert.go index c4482ec13..b0274d660 100644 --- a/pkg/provider/kubernetes/ingress/convert.go +++ b/pkg/provider/kubernetes/ingress/convert.go @@ -4,8 +4,8 @@ import ( "errors" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + netv1 "k8s.io/api/networking/v1" + netv1beta1 "k8s.io/api/networking/v1beta1" ) type marshaler interface { @@ -17,7 +17,7 @@ type unmarshaler interface { } type LoadBalancerIngress interface { - corev1.LoadBalancerIngress | networkingv1beta1.IngressLoadBalancerIngress | networkingv1.IngressLoadBalancerIngress + corev1.LoadBalancerIngress | netv1beta1.IngressLoadBalancerIngress | netv1.IngressLoadBalancerIngress } // convertSlice converts slice of LoadBalancerIngress to slice of LoadBalancerIngress. diff --git a/pkg/provider/kubernetes/ingress/convert_test.go b/pkg/provider/kubernetes/ingress/convert_test.go index 4a4759313..0002b2b3a 100644 --- a/pkg/provider/kubernetes/ingress/convert_test.go +++ b/pkg/provider/kubernetes/ingress/convert_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + netv1 "k8s.io/api/networking/v1" + netv1beta1 "k8s.io/api/networking/v1beta1" ) func Test_convertSlice_corev1_to_networkingv1(t *testing.T) { @@ -25,14 +25,14 @@ func Test_convertSlice_corev1_to_networkingv1(t *testing.T) { }, } - actual, err := convertSlice[networkingv1.IngressLoadBalancerIngress](g) + actual, err := convertSlice[netv1.IngressLoadBalancerIngress](g) require.NoError(t, err) - expected := []networkingv1.IngressLoadBalancerIngress{ + expected := []netv1.IngressLoadBalancerIngress{ { IP: "132456", Hostname: "foo", - Ports: []networkingv1.IngressPortStatus{ + Ports: []netv1.IngressPortStatus{ { Port: 123, Protocol: "https", @@ -46,11 +46,11 @@ func Test_convertSlice_corev1_to_networkingv1(t *testing.T) { } func Test_convertSlice_networkingv1beta1_to_networkingv1(t *testing.T) { - g := []networkingv1beta1.IngressLoadBalancerIngress{ + g := []netv1beta1.IngressLoadBalancerIngress{ { IP: "132456", Hostname: "foo", - Ports: []networkingv1beta1.IngressPortStatus{ + Ports: []netv1beta1.IngressPortStatus{ { Port: 123, Protocol: "https", @@ -60,14 +60,14 @@ func Test_convertSlice_networkingv1beta1_to_networkingv1(t *testing.T) { }, } - actual, err := convertSlice[networkingv1.IngressLoadBalancerIngress](g) + actual, err := convertSlice[netv1.IngressLoadBalancerIngress](g) require.NoError(t, err) - expected := []networkingv1.IngressLoadBalancerIngress{ + expected := []netv1.IngressLoadBalancerIngress{ { IP: "132456", Hostname: "foo", - Ports: []networkingv1.IngressPortStatus{ + Ports: []netv1.IngressPortStatus{ { Port: 123, Protocol: "https", @@ -81,11 +81,11 @@ func Test_convertSlice_networkingv1beta1_to_networkingv1(t *testing.T) { } func Test_convertSlice_networkingv1_to_networkingv1beta1(t *testing.T) { - g := []networkingv1.IngressLoadBalancerIngress{ + g := []netv1.IngressLoadBalancerIngress{ { IP: "132456", Hostname: "foo", - Ports: []networkingv1.IngressPortStatus{ + Ports: []netv1.IngressPortStatus{ { Port: 123, Protocol: "https", @@ -95,14 +95,14 @@ func Test_convertSlice_networkingv1_to_networkingv1beta1(t *testing.T) { }, } - actual, err := convertSlice[networkingv1beta1.IngressLoadBalancerIngress](g) + actual, err := convertSlice[netv1beta1.IngressLoadBalancerIngress](g) require.NoError(t, err) - expected := []networkingv1beta1.IngressLoadBalancerIngress{ + expected := []netv1beta1.IngressLoadBalancerIngress{ { IP: "132456", Hostname: "foo", - Ports: []networkingv1beta1.IngressPortStatus{ + Ports: []netv1beta1.IngressPortStatus{ { Port: 123, Protocol: "https", @@ -128,13 +128,13 @@ func Test_convert(t *testing.T) { }, } - actual, err := convert[networkingv1.IngressLoadBalancerIngress](g) + actual, err := convert[netv1.IngressLoadBalancerIngress](g) require.NoError(t, err) - expected := &networkingv1.IngressLoadBalancerIngress{ + expected := &netv1.IngressLoadBalancerIngress{ IP: "132456", Hostname: "foo", - Ports: []networkingv1.IngressPortStatus{ + Ports: []netv1.IngressPortStatus{ { Port: 123, Protocol: "https", diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 8724b09dd..31821bf33 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -23,7 +23,7 @@ import ( "github.com/traefik/traefik/v2/pkg/safe" "github.com/traefik/traefik/v2/pkg/tls" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" + netv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -191,7 +191,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl serverVersion := client.GetServerVersion() - var ingressClasses []*networkingv1.IngressClass + var ingressClasses []*netv1.IngressClass if supportsIngressClass(serverVersion) { ics, err := client.GetIngressClasses() @@ -339,7 +339,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl return conf } -func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Client) error { +func (p *Provider) updateIngressStatus(ing *netv1.Ingress, k8sClient Client) error { // Only process if an EndpointIngress has been configured. if p.IngressEndpoint == nil { return nil @@ -350,7 +350,7 @@ func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Clie return errors.New("publishedService or ip or hostname must be defined") } - return k8sClient.UpdateIngressStatus(ing, []networkingv1.IngressLoadBalancerIngress{{IP: p.IngressEndpoint.IP, Hostname: p.IngressEndpoint.Hostname}}) + return k8sClient.UpdateIngressStatus(ing, []netv1.IngressLoadBalancerIngress{{IP: p.IngressEndpoint.IP, Hostname: p.IngressEndpoint.Hostname}}) } serviceInfo := strings.Split(p.IngressEndpoint.PublishedService, "/") @@ -375,7 +375,7 @@ func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Clie return fmt.Errorf("missing service: %s", p.IngressEndpoint.PublishedService) } - ingresses, err := convertSlice[networkingv1.IngressLoadBalancerIngress](service.Status.LoadBalancer.Ingress) + ingresses, err := convertSlice[netv1.IngressLoadBalancerIngress](service.Status.LoadBalancer.Ingress) if err != nil { return err } @@ -383,7 +383,7 @@ func (p *Provider) updateIngressStatus(ing *networkingv1.Ingress, k8sClient Clie return k8sClient.UpdateIngressStatus(ing, ingresses) } -func (p *Provider) shouldProcessIngress(ingress *networkingv1.Ingress, ingressClasses []*networkingv1.IngressClass) bool { +func (p *Provider) shouldProcessIngress(ingress *netv1.Ingress, ingressClasses []*netv1.IngressClass) bool { // configuration through the new kubernetes ingressClass if ingress.Spec.IngressClassName != nil { for _, ic := range ingressClasses { @@ -407,7 +407,7 @@ func buildHostRule(host string) string { return "Host(`" + host + "`)" } -func getCertificates(ctx context.Context, ingress *networkingv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { +func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { for _, t := range ingress.Spec.TLS { if t.SecretName == "" { log.FromContext(ctx).Debugf("Skipping TLS sub-section: No secret name provided") @@ -492,7 +492,7 @@ func getTLSConfig(tlsConfigs map[string]*tls.CertAndStores) []*tls.CertAndStores return configs } -func (p *Provider) loadService(client Client, namespace string, backend networkingv1.IngressBackend) (*dynamic.Service, error) { +func (p *Provider) loadService(client Client, namespace string, backend netv1.IngressBackend) (*dynamic.Service, error) { service, exists, err := client.GetService(namespace, backend.Service.Name) if err != nil { return nil, err @@ -643,7 +643,7 @@ func makeRouterKeyWithHash(key, rule string) (string, error) { return dupKey, nil } -func loadRouter(rule networkingv1.IngressRule, pa networkingv1.HTTPIngressPath, rtConfig *RouterConfig, serviceName string) *dynamic.Router { +func loadRouter(rule netv1.IngressRule, pa netv1.HTTPIngressPath, rtConfig *RouterConfig, serviceName string) *dynamic.Router { var rules []string if len(rule.Host) > 0 { rules = []string{buildHostRule(rule.Host)} @@ -652,11 +652,11 @@ func loadRouter(rule networkingv1.IngressRule, pa networkingv1.HTTPIngressPath, if len(pa.Path) > 0 { matcher := defaultPathMatcher - if pa.PathType == nil || *pa.PathType == "" || *pa.PathType == networkingv1.PathTypeImplementationSpecific { + if pa.PathType == nil || *pa.PathType == "" || *pa.PathType == netv1.PathTypeImplementationSpecific { if rtConfig != nil && rtConfig.Router != nil && rtConfig.Router.PathMatcher != "" { matcher = rtConfig.Router.PathMatcher } - } else if *pa.PathType == networkingv1.PathTypeExact { + } else if *pa.PathType == netv1.PathTypeExact { matcher = "Path" } diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index 6f4977e61..329ca0735 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -15,7 +15,7 @@ import ( "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/types" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" + netv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -1898,7 +1898,7 @@ func TestGetCertificates(t *testing.T) { testCases := []struct { desc string - ingress *networkingv1.Ingress + ingress *netv1.Ingress client Client result map[string]*tls.CertAndStores errResult string diff --git a/pkg/provider/kubernetes/k8s/event_handler_test.go b/pkg/provider/kubernetes/k8s/event_handler_test.go index 8f75ebbd2..e8b7a31a2 100644 --- a/pkg/provider/kubernetes/k8s/event_handler_test.go +++ b/pkg/provider/kubernetes/k8s/event_handler_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/networking/v1" + netv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -63,12 +63,12 @@ func Test_detectChanges(t *testing.T) { }, { name: "Ingress With same version", - oldObj: &v1.Ingress{ + oldObj: &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, }, - newObj: &v1.Ingress{ + newObj: &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, @@ -76,12 +76,12 @@ func Test_detectChanges(t *testing.T) { }, { name: "Ingress With different version", - oldObj: &v1.Ingress{ + oldObj: &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "1", }, }, - newObj: &v1.Ingress{ + newObj: &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ ResourceVersion: "2", }, diff --git a/pkg/provider/kubernetes/k8s/parser.go b/pkg/provider/kubernetes/k8s/parser.go index 6a3e94f7b..987aa50ec 100644 --- a/pkg/provider/kubernetes/k8s/parser.go +++ b/pkg/provider/kubernetes/k8s/parser.go @@ -7,7 +7,7 @@ import ( "github.com/traefik/traefik/v2/pkg/log" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" + kscheme "k8s.io/client-go/kubernetes/scheme" ) // MustParseYaml parses a YAML to objects. @@ -21,7 +21,7 @@ func MustParseYaml(content []byte) []runtime.Object { continue } - decode := scheme.Codecs.UniversalDeserializer().Decode + decode := kscheme.Codecs.UniversalDeserializer().Decode obj, groupVersionKind, err := decode([]byte(file), nil, nil) if err != nil { panic(fmt.Sprintf("Error while decoding YAML object. Err was: %s", err)) From 01f346f23936b171f462a34318ed3125086ae097 Mon Sep 17 00:00:00 2001 From: yingshaoxo Date: Tue, 4 Apr 2023 20:36:11 +0800 Subject: [PATCH 07/14] Add accessControlAllowHeaders example --- docs/content/middlewares/http/headers.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/content/middlewares/http/headers.md b/docs/content/middlewares/http/headers.md index e79a627b0..432ab008c 100644 --- a/docs/content/middlewares/http/headers.md +++ b/docs/content/middlewares/http/headers.md @@ -207,11 +207,14 @@ http: CORS (Cross-Origin Resource Sharing) headers can be added and configured in a manner similar to the custom headers above. This functionality allows for more advanced security features to quickly be set. If CORS headers are set, then the middleware does not pass preflight requests to any service, -instead the response will be generated and sent back to the client directly. +instead the response will be generated and sent back to the client directly. +Please note that the example below is by no means authoritative or exhaustive, +and should not be used as is for production. ```yaml tab="Docker" labels: - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" + - "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*" - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org" - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" - "traefik.http.middlewares.testheader.headers.addvaryheader=true" @@ -228,6 +231,7 @@ spec: - "GET" - "OPTIONS" - "PUT" + accessControlAllowHeaders: "*" accessControlAllowOriginList: - "https://foo.bar.org" - "https://example.org" @@ -237,6 +241,7 @@ spec: ```yaml tab="Consul Catalog" - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" +- "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*" - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org" - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" - "traefik.http.middlewares.testheader.headers.addvaryheader=true" @@ -245,6 +250,7 @@ spec: ```json tab="Marathon" "labels": { "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT", + "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*", "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist": "https://foo.bar.org,https://example.org", "traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100", "traefik.http.middlewares.testheader.headers.addvaryheader": "true" @@ -254,6 +260,7 @@ spec: ```yaml tab="Rancher" labels: - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" + - "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*" - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org" - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" - "traefik.http.middlewares.testheader.headers.addvaryheader=true" @@ -268,6 +275,7 @@ http: - GET - OPTIONS - PUT + accessControlAllowHeaders: "*" accessControlAllowOriginList: - https://foo.bar.org - https://example.org @@ -279,6 +287,7 @@ http: [http.middlewares] [http.middlewares.testHeader.headers] accessControlAllowMethods= ["GET", "OPTIONS", "PUT"] + accessControlAllowHeaders= "*" accessControlAllowOriginList = ["https://foo.bar.org","https://example.org"] accessControlMaxAge = 100 addVaryHeader = true From 5f514b0d165bcde5af9139b3f070cc20bd5cbbed Mon Sep 17 00:00:00 2001 From: sven Date: Tue, 4 Apr 2023 16:42:06 +0200 Subject: [PATCH 08/14] Update Call To Actions --- .../includes/traefik-for-business-applications.md | 11 +++-------- docs/content/index.md | 12 +++++------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/docs/content/includes/traefik-for-business-applications.md b/docs/content/includes/traefik-for-business-applications.md index bbc2a602a..c07d1a41d 100644 --- a/docs/content/includes/traefik-for-business-applications.md +++ b/docs/content/includes/traefik-for-business-applications.md @@ -2,15 +2,10 @@ !!! question "Using Traefik for Business Applications?" - If you are using Traefik for commercial applications, - consider the [Enterprise Edition](https://traefik.io/traefik-enterprise/). - You can use it as your: + If you are using Traefik in your organization, consider [Traefik Enterprise](https://traefik.io/traefik-enterprise/). You can use it as your: + - [API Gateway](https://traefik.io/solutions/api-gateway/) - [Kubernetes Ingress Controller](https://traefik.io/solutions/kubernetes-ingress/) - [Docker Swarm Ingress Controller](https://traefik.io/solutions/docker-swarm-ingress/) - - [API Gateway](https://traefik.io/solutions/api-gateway/) - Traefik Enterprise enables centralized access management, - distributed Let's Encrypt, - and other advanced capabilities. - Learn more in [this 15-minute technical walkthrough](https://info.traefik.io/watch-traefikee-demo). + Traefik Enterprise simplifies the discovery, security, and deployment of APIs and microservices across any environment. See it in action in [this short video walkthrough](https://info.traefik.io/watch-traefikee-demo). diff --git a/docs/content/index.md b/docs/content/index.md index b882fb148..11d996ea6 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -24,10 +24,8 @@ Developing Traefik, our main goal is to make it simple to use, and we're sure yo !!! info - Join our user friendly and active [Community Forum](https://community.traefik.io) to discuss, learn, and connect with the traefik community. - - Using Traefik for commercial applications? - Consider the [Enterprise Edition](https://traefik.io/traefik-enterprise/) of Traefik as your [Kubernetes Ingress](https://traefik.io/solutions/kubernetes-ingress/), - your [Docker Swarm Load Balancer](https://traefik.io/solutions/docker-swarm-ingress/), - or your [API gateway](https://traefik.io/solutions/api-gateway/). - Get started with a [free 30-day trial](https://info.traefik.io/get-traefik-enterprise-free-for-30-days). + 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. + + Using Traefik in your organization? Consider [Traefik Enterprise](https://traefik.io/traefik-enterprise/ "Lino to Traefik Enterprise"), our unified API Gateway and Ingress that simplifies the discovery, security, and deployment of APIs and microservices across any environment. + + See it in action in [this short video walkthrough](https://info.traefik.io/watch-traefikee-demo "Link to video walkthrough"). From 4c9765b52da006038056b4f6a518a44b1d4b6f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ty=C3=A1s=20Somfai?= Date: Tue, 4 Apr 2023 18:12:06 +0200 Subject: [PATCH 09/14] Display period setting of the RateLimit middleware in the webui --- webui/src/components/_commons/PanelMiddlewares.vue | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/webui/src/components/_commons/PanelMiddlewares.vue b/webui/src/components/_commons/PanelMiddlewares.vue index 2c9c5f4dd..50068f503 100644 --- a/webui/src/components/_commons/PanelMiddlewares.vue +++ b/webui/src/components/_commons/PanelMiddlewares.vue @@ -723,7 +723,7 @@ - +
@@ -742,6 +742,14 @@ {{ exData(middleware).burst }}
+
+
Period
+ + {{ exData(middleware).period }} + +
From 0d1bb72306d720cf481c7800ed9cc129fcabef29 Mon Sep 17 00:00:00 2001 From: sven Date: Wed, 5 Apr 2023 14:16:06 +0200 Subject: [PATCH 10/14] docs: update wording - add link descriptions --- .../docker-compose/basic-example/index.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/content/user-guides/docker-compose/basic-example/index.md b/docs/content/user-guides/docker-compose/basic-example/index.md index dccf3cbb4..f91520fae 100644 --- a/docs/content/user-guides/docker-compose/basic-example/index.md +++ b/docs/content/user-guides/docker-compose/basic-example/index.md @@ -1,12 +1,12 @@ --- title: "Traefik Docker Documentation" -description: "This guide covers a basic docker-compose file exposing a simple service using the docker provider in Traefik Proxy. Read the technical documentation." +description: "This guide covers a Docker Compose file exposing a service using the Docker provider in Traefik Proxy. Read the technical documentation." --- -# Docker-compose basic example +# Docker Compose example -In this section we quickly go over a basic docker-compose file exposing a simple service using the docker provider. -This will also be used as a starting point for the other docker-compose guides. +In this section, we quickly go over a Docker Compose file exposing a service using the Docker provider. +This will also be used as a starting point for the other Docker Compose guides. ## Setup @@ -19,9 +19,9 @@ This will also be used as a starting point for the other docker-compose guides. ??? Networking The Traefik container has to be attached to the same network as the containers to be exposed. - If no networks are specified in the docker-compose file, Docker creates a default one that allows Traefik to reach the containers defined in the same file. - You can [customize the network](https://docs.docker.com/compose/networking/#specify-custom-networks) as described in the example below. - You can use a [pre-existing network](https://docs.docker.com/compose/networking/#use-a-pre-existing-network) too. + If no networks are specified in the Docker Compose file, Docker creates a default one that allows Traefik to reach the containers defined in the same file. + You can [customize the network](https://docs.docker.com/compose/networking/#specify-custom-networks "Link to docs about custom networks with Docker Compose") as described in the example below. + You can use a [pre-existing network](https://docs.docker.com/compose/networking/#use-a-pre-existing-network "Link to Docker Compose networking docs") too. ```yaml version: "3.3" @@ -49,7 +49,7 @@ This will also be used as a starting point for the other docker-compose guides. - Run `docker-compose up -d` within the folder where you created the previous file. - Wait a bit and visit `http://your_own_domain` to confirm everything went fine. You should see the output of the whoami service. Something similar to: - + ```text Hostname: d7f919e54651 IP: 127.0.0.1 @@ -69,9 +69,9 @@ This will also be used as a starting point for the other docker-compose guides. ## Details -- As an example we use [whoami](https://github.com/traefik/whoami) (a tiny Go server that prints os information and HTTP request to output) which was used to define our `simple-service` container. +- As an example, we use [whoami](https://github.com/traefik/whoami "Link to the GitHub repo of whoami") (a tiny Go server that prints OS information and HTTP request to output) which was used to define our `simple-service` container. -- We define an entry point, along with the exposure of the matching port within docker-compose, which basically allow us to "open and accept" HTTP traffic: +- We define an entry point, along with the exposure of the matching port within Docker Compose, which allow us to "open and accept" HTTP traffic: ```yaml command: @@ -95,8 +95,8 @@ ports: !!! Note - If you are working on a remote server, you can use the following command to display configuration (require `curl` & `jq`): - + If you are working on a remote server, you can use the following command to display configuration (require `curl` & `jq`): + ```bash curl -s 127.0.0.1:8080/api/rawdata | jq . ``` @@ -106,7 +106,7 @@ ports: ```yaml traefik: command: - # Enabling docker provider + # Enabling Docker provider - "--providers.docker=true" # Do not expose containers unless explicitly told so - "--providers.docker.exposedbydefault=false" From 11966c209895410e1bc27b0f8bddb13dd590db86 Mon Sep 17 00:00:00 2001 From: sven Date: Wed, 5 Apr 2023 14:44:06 +0200 Subject: [PATCH 11/14] Improve concepts page --- docs/content/getting-started/concepts.md | 39 +++++++++++++++++------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/docs/content/getting-started/concepts.md b/docs/content/getting-started/concepts.md index ea0119837..2e99906a3 100644 --- a/docs/content/getting-started/concepts.md +++ b/docs/content/getting-started/concepts.md @@ -1,19 +1,34 @@ --- -title: "Traefik Concepts Documentation" -description: "Get started with Traefik Proxy. Read the technical documentation for an introduction into the key concepts behind our open source edge router." +title: Concepts +description: Traefik - base concepts and main features --- # Concepts -Everything You Need to Know -{: .subtitle } +This page explains the base concepts of Traefik. + +--- + +## Introduction + +Traefik is based on the concept of EntryPoints, Routers, Middelwares and Services. + +The main features include dynamic configuration, automatic service discovery, and support for multiple backends and protocols. + +1. [EntryPoints](../routing/entrypoints.md "Link to docs about EntryPoints"): EntryPoints are the network entry points into Traefik. They define the port which will receive the packets, and whether to listen for TCP or UDP. + +2. [Routers](../routing/routers/index.md "Link to docs about routers"): A router is in charge of connecting incoming requests to the services that can handle them. + +3. [Middlewares](../middlewares/overview.md "Link to docs about middlewares"): Attached to the routers, middlewares can modify the requests or responses before they are sent to your service + +4. [Services](../routing/services/index.md "Link to docs about services"): Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests. ## Edge Router -Traefik is an _Edge Router_, it means that it's the door to your platform, and that it intercepts and routes every incoming request: -it knows all the logic and every rule that determine which services handle which requests (based on the [path](../routing/routers/index.md#rule), the [host](../routing/routers/index.md#rule), [headers](../routing/routers/index.md#rule), [and so on](../routing/routers/index.md#rule) ...). +Traefik is an *Edge Router*, it means that it's the door to your platform, and that it intercepts and routes every incoming request: +it knows all the logic and every [rule](../routing/routers/index.md#rule "Link to docs about routing rules") that determine which services handle which requests (based on the *path*, the *host*, *headers*, etc.). -![The Door to Your Infrastructure](../assets/img/traefik-concepts-1.png) +![The Door to Your Infrastructure](../assets/img/traefik-concepts-1.png "Picture explaining the infrastructure") ## Auto Service Discovery @@ -21,7 +36,7 @@ Where traditionally edge routers (or reverse proxies) need a configuration file Deploying your services, you attach information that tells Traefik the characteristics of the requests the services can handle. -![Decentralized Configuration](../assets/img/traefik-concepts-2.png) +![Decentralized Configuration](../assets/img/traefik-concepts-2.png "Picture about Decentralized Configuration") It means that when a service is deployed, Traefik detects it immediately and updates the routing rules in real time. Similarly, when a service is removed from the infrastructure, the corresponding route is deleted accordingly. @@ -30,14 +45,16 @@ You no longer need to create and synchronize configuration files cluttered with !!! info "Many different rules" - In the example above, we used the request [path](../routing/routers/index.md#rule) to determine which service was in charge, but of course you can use many other different [rules](../routing/routers/index.md#rule). + In the example above, we used the request [path rule](../routing/routers/index.md#rule "Link to docs about routing rules") to determine which service was in charge. + Certainly, you can use many other different [rules](../routing/routers/index.md#rule "Link to docs about routing rules"). !!! info "Updating the requests" - In the [middleware](../middlewares/overview.md) section, you can learn about how to update the requests before forwarding them to the services. + In the [middleware](../middlewares/overview.md "Link to middleware documentation") section, you can learn about how to update the requests before forwarding them to the services. !!! question "How does Traefik discover the services?" - Traefik is able to use your cluster API to discover the services and read the attached information. In Traefik, these connectors are called [providers](../providers/overview.md) because they _provide_ the configuration to Traefik. To learn more about them, read the [provider overview](../providers/overview.md) section. + Traefik is able to use your cluster API to discover the services and read the attached information. + In Traefik, these connectors are called [providers](../providers/overview.md "Link to overview about Traefik providers") because they *provide* the configuration to Traefik. {!traefik-for-business-applications.md!} From 4ed3964b3586565519249bbdc55eb1b961c08c49 Mon Sep 17 00:00:00 2001 From: mpl Date: Thu, 6 Apr 2023 18:10:03 +0200 Subject: [PATCH 12/14] Prepare release v2.9.10 --- CHANGELOG.md | 3 + docs/content/https/acme.md | 230 ++++++++++++++++----------------- docs/scripts/verify.sh | 2 +- script/gcg/traefik-bugfix.toml | 6 +- 4 files changed, 122 insertions(+), 119 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cba002d75..3dea602eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [v2.9.10](https://github.com/traefik/traefik/tree/v2.9.10) (2023-04-06) +[All Commits](https://github.com/traefik/traefik/compare/v2.9.9...v2.9.10) + ## [v2.9.9](https://github.com/traefik/traefik/tree/v2.9.9) (2023-03-21) [All Commits](https://github.com/traefik/traefik/compare/v2.9.8...v2.9.9) diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index 640e0098a..1df23c23d 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -308,121 +308,121 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used For complete details, refer to your provider's _Additional configuration_ link. -| Provider Name | Provider Code | Environment Variables | | -|----------------------------------------------------------------------------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| -| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | -| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | -| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) | -| [ArvanCloud](https://www.arvancloud.com/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) | -| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | -| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) | -| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | -| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | -| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | -| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) | -| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) | -| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) | -| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | -| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | -| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | -| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) | -| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) | -| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) | -| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | -| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | -| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) | -| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | -| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | -| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | -| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) | -| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) | -| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) | -| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) | -| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) | -| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) | -| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | -| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) | -| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) | -| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | -| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) | -| [G-Core Lab](https://gcorelabs.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) | -| [Gandi v5](https://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | -| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | -| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | -| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | -| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | -| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) | -| [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) | -| [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) | -| [IIJ DNS Platform Service](https://www.iij.ad.jp) | `iijdpf` | `IIJ_DPF_API_TOKEN` , `IIJ_DPF_DPM_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iijdpf) | -| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | -| [Infoblox](https://www.infoblox.com/) | `infoblox` | `INFOBLOX_USERNAME`, `INFOBLOX_PASSWORD`, `INFOBLOX_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/infoblox) | -| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) | -| [Internet.bs](https://internetbs.net) | `internetbs` | `INTERNET_BS_API_KEY`, `INTERNET_BS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/internetbs) | -| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | -| [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) | -| [iwantmyname](https://iwantmyname.com) | `iwantmyname` | `IWANTMYNAME_USERNAME` , `IWANTMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/iwantmyname) | -| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | -| [Liara](https://liara.ir) | `liara` | `LIARA_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/liara) | -| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | -| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | -| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | -| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) | -| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) | -| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | -| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) | -| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) | -| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | -| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) | -| [NearlyFreeSpeech.NET](https://www.nearlyfreespeech.net/) | `nearlyfreespeech` | `NEARLYFREESPEECH_API_KEY`, `NEARLYFREESPEECH_LOGIN` | [Additional configuration](https://go-acme.github.io/lego/dns/nearlyfreespeech) | -| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) | -| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) | -| [Nicmanager](https://www.nicmanager.com) | `nicmanager` | `NICMANAGER_API_EMAIL`, `NICMANAGER_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/nicmanager) | -| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) | -| [Njalla](https://njal.la) | `njalla` | `NJALLA_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/njalla) | -| [NS1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) | -| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) | -| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) | -| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) | -| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) | -| [Porkbun](https://porkbun.com/) | `porkbun` | `PORKBUN_SECRET_API_KEY`, `PORKBUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/porkbun) | -| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) | -| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) | -| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) | -| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) | -| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) | -| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) | -| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) | -| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCALEWAY_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) | -| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | -| [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) | -| [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) | -| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) | -| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) | -| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) | -| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | -| [UKFast SafeDNS](https://www.ans.co.uk/cloud-and-infrastructure/dedicated-servers/dns-management/) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) | -| [Ultradns](https://neustarsecurityservices.com/dns-services) | `ultradns` | `ULTRADNS_USERNAME`, `ULTRADNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/ultradns) | -| [Variomedia](https://www.variomedia.de/) | `variomedia` | `VARIOMEDIA_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/variomedia) | -| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | -| [Vercel](https://vercel.com) | `vercel` | `VERCEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vercel) | -| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) | -| [VinylDNS](https://www.vinyldns.io) | `vinyldns` | `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, `VINYLDNS_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/vinyldns) | -| [VK Cloud](https://mcs.mail.ru/) | `vkcloud` | `VK_CLOUD_PASSWORD`, `VK_CLOUD_PROJECT_ID`, `VK_CLOUD_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/vkcloud) | -| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | -| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | -| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) | -| [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) | -| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) | -| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) | -| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) | -| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) | -| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) | -| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | -| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press Enter. | | +| Provider Name | Provider Code | Environment Variables | | +|------------------------------------------------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | +| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | +| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) | +| [ArvanCloud](https://www.arvancloud.com/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) | +| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | +| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) | +| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | +| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | +| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | +| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) | +| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) | +| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) | +| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | +| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | +| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | +| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) | +| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) | +| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) | +| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | +| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | +| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) | +| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | +| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | +| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | +| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) | +| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) | +| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) | +| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) | +| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) | +| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) | +| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | +| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) | +| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) | +| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) | +| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) | +| [G-Core Lab](https://gcorelabs.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) | +| [Gandi v5](https://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) | +| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) | +| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) | +| [GoDaddy](https://www.godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) | +| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) | +| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) | +| [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) | +| [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) | +| [IIJ DNS Platform Service](https://www.iij.ad.jp) | `iijdpf` | `IIJ_DPF_API_TOKEN` , `IIJ_DPF_DPM_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iijdpf) | +| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | +| [Infoblox](https://www.infoblox.com/) | `infoblox` | `INFOBLOX_USERNAME`, `INFOBLOX_PASSWORD`, `INFOBLOX_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/infoblox) | +| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) | +| [Internet.bs](https://internetbs.net) | `internetbs` | `INTERNET_BS_API_KEY`, `INTERNET_BS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/internetbs) | +| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | +| [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) | +| [iwantmyname](https://iwantmyname.com) | `iwantmyname` | `IWANTMYNAME_USERNAME` , `IWANTMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/iwantmyname) | +| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | +| [Liara](https://liara.ir) | `liara` | `LIARA_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/liara) | +| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | +| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | +| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | +| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) | +| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) | +| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | +| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) | +| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) | +| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | +| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) | +| [NearlyFreeSpeech.NET](https://www.nearlyfreespeech.net/) | `nearlyfreespeech` | `NEARLYFREESPEECH_API_KEY`, `NEARLYFREESPEECH_LOGIN` | [Additional configuration](https://go-acme.github.io/lego/dns/nearlyfreespeech) | +| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) | +| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) | +| [Nicmanager](https://www.nicmanager.com) | `nicmanager` | `NICMANAGER_API_EMAIL`, `NICMANAGER_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/nicmanager) | +| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) | +| [Njalla](https://njal.la) | `njalla` | `NJALLA_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/njalla) | +| [NS1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) | +| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) | +| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) | +| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) | +| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) | +| [Porkbun](https://porkbun.com/) | `porkbun` | `PORKBUN_SECRET_API_KEY`, `PORKBUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/porkbun) | +| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) | +| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) | +| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) | +| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) | +| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) | +| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) | +| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) | +| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCALEWAY_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) | +| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) | +| [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) | +| [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) | +| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) | +| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) | +| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) | +| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | +| [UKFast SafeDNS](https://docs.ukfast.co.uk/domains/safedns/index.html) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) | +| [Ultradns](https://neustarsecurityservices.com/dns-services) | `ultradns` | `ULTRADNS_USERNAME`, `ULTRADNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/ultradns) | +| [Variomedia](https://www.variomedia.de/) | `variomedia` | `VARIOMEDIA_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/variomedia) | +| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | +| [Vercel](https://vercel.com) | `vercel` | `VERCEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vercel) | +| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) | +| [VinylDNS](https://www.vinyldns.io) | `vinyldns` | `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, `VINYLDNS_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/vinyldns) | +| [VK Cloud](https://mcs.mail.ru/) | `vkcloud` | `VK_CLOUD_PASSWORD`, `VK_CLOUD_PROJECT_ID`, `VK_CLOUD_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/vkcloud) | +| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | +| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | +| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) | +| [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) | +| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) | +| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) | +| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) | +| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) | +| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) | +| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | +| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press Enter. | | [^1]: More information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/). [^2]: [Providing credentials to your application](https://cloud.google.com/docs/authentication/production). diff --git a/docs/scripts/verify.sh b/docs/scripts/verify.sh index 970d18988..44835ce79 100755 --- a/docs/scripts/verify.sh +++ b/docs/scripts/verify.sh @@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \ --alt_ignore="/traefikproxy-vertical-logo-color.svg/" \ --http_status_ignore="0,500,501,503" \ --file_ignore="/404.html/" \ - --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/" \ + --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/,/www.godaddy.com/,/internetbs.net/" \ '{}' 1>/dev/null ## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 189f8c451..a9e58517e 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.9.9 +# example new bugfix v2.9.10 CurrentRef = "v2.9" -PreviousRef = "v2.9.8" +PreviousRef = "v2.9.9" BaseBranch = "v2.9" -FutureCurrentRefName = "v2.9.9" +FutureCurrentRefName = "v2.9.10" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From e8878fe6ac4a03f0fa1b11e1ad4e263ab0984747 Mon Sep 17 00:00:00 2001 From: mpl Date: Fri, 7 Apr 2023 11:00:06 +0200 Subject: [PATCH 13/14] Prepare release v2.10.0-rc2 --- CHANGELOG.md | 18 ++++++++++++++++++ script/gcg/traefik-rc-new.toml | 10 +++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 922489424..6a6f202d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## [v2.10.0-rc2](https://github.com/traefik/traefik/tree/v2.10.0-rc2) (2023-04-07) +[All Commits](https://github.com/traefik/traefik/compare/v2.10.0-rc1...v2.10.0-rc2) + +**Enhancements:** +- **[webui]** Display period setting of the RateLimit middleware in the webui ([#9822](https://github.com/traefik/traefik/pull/9822) by [smatyas](https://github.com/smatyas)) + +**Bug fixes:** +- **[docker]** Only warn about missing docker network when network_mode is not host or container ([#9799](https://github.com/traefik/traefik/pull/9799) by [sentriz](https://github.com/sentriz)) +- **[k8s/ingress,k8s]** chore: bump k8s.io/client-go from v0.22.1 to v0.26.3 ([#9808](https://github.com/traefik/traefik/pull/9808) by [ldez](https://github.com/ldez)) +- **[plugins]** Update Yaegi to v0.15.1 ([#9815](https://github.com/traefik/traefik/pull/9815) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[docker]** Update wording - add link descriptions ([#9816](https://github.com/traefik/traefik/pull/9816) by [svx](https://github.com/svx)) +- **[middleware]** Add accessControlAllowHeaders example ([#9810](https://github.com/traefik/traefik/pull/9810) by [yingshaoxo](https://github.com/yingshaoxo)) +- Update Call To Actions ([#9824](https://github.com/traefik/traefik/pull/9824) by [svx](https://github.com/svx)) +- Improve concepts page ([#9813](https://github.com/traefik/traefik/pull/9813) by [svx](https://github.com/svx)) +- Update wording ([#9811](https://github.com/traefik/traefik/pull/9811) by [svx](https://github.com/svx)) + ## [v2.9.10](https://github.com/traefik/traefik/tree/v2.9.10) (2023-04-06) [All Commits](https://github.com/traefik/traefik/compare/v2.9.9...v2.9.10) diff --git a/script/gcg/traefik-rc-new.toml b/script/gcg/traefik-rc-new.toml index a48ac8b2b..61363d378 100644 --- a/script/gcg/traefik-rc-new.toml +++ b/script/gcg/traefik-rc-new.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example RC5 of v2.9.0 -CurrentRef = "v2.9" -PreviousRef = "v2.9.0-rc4" -BaseBranch = "v2.9" -FutureCurrentRefName = "v2.9.0-rc5" +# example RC2 of v2.10.0 +CurrentRef = "v2.10" +PreviousRef = "v2.10.0-rc1" +BaseBranch = "v2.10" +FutureCurrentRefName = "v2.10.0-rc2" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From c4bea197ab079a8e4c6b8f3f356f35ce6df7366d Mon Sep 17 00:00:00 2001 From: mloiseleur <97035654+mloiseleur@users.noreply.github.com> Date: Wed, 12 Apr 2023 12:10:05 +0200 Subject: [PATCH 14/14] More details on for mTLS --- docs/content/https/tls.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index eab018601..0323eb2e6 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -509,15 +509,17 @@ spec: Traefik supports mutual authentication, through the `clientAuth` section. -For authentication policies that require verification of the client certificate, the certificate authority for the certificate should be set in `clientAuth.caFiles`. +For authentication policies that require verification of the client certificate, the certificate authority for the certificates should be set in `clientAuth.caFiles`. + +In Kubernetes environment, CA certificate can be set in `clientAuth.secretNames`. See [TLSOption resource](../../routing/providers/kubernetes-crd#kind-tlsoption) for more details. The `clientAuth.clientAuthType` option governs the behaviour as follows: - `NoClientCert`: disregards any client certificate. - `RequestClientCert`: asks for a certificate but proceeds anyway if none is provided. -- `RequireAnyClientCert`: requires a certificate but does not verify if it is signed by a CA listed in `clientAuth.caFiles`. -- `VerifyClientCertIfGiven`: if a certificate is provided, verifies if it is signed by a CA listed in `clientAuth.caFiles`. Otherwise proceeds without any certificate. -- `RequireAndVerifyClientCert`: requires a certificate, which must be signed by a CA listed in `clientAuth.caFiles`. +- `RequireAnyClientCert`: requires a certificate but does not verify if it is signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`. +- `VerifyClientCertIfGiven`: if a certificate is provided, verifies if it is signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`. Otherwise proceeds without any certificate. +- `RequireAndVerifyClientCert`: requires a certificate, which must be signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`. ```yaml tab="File (YAML)" # Dynamic configuration