Migrate to github.com/moby/moby modules

This commit is contained in:
Michael
2026-05-04 16:06:05 +02:00
committed by GitHub
parent 29d2340ca4
commit e4537f8b04
12 changed files with 491 additions and 513 deletions
+10
View File
@@ -813,3 +813,13 @@ By default, the behavior is unchanged: all original request headers are forwarde
If the error page service is in a separate trust domain, consider using `errorRequestHeaders` to restrict which headers are forwarded.
Please check out the [Error Pages](../middlewares/http/errorpages.md#forwardheaders) middleware documentation for more details.
## v2.11.45
### Docker provider: minimum Docker Engine version
Starting with `v2.11.45`, the Docker provider requires Docker API version v1.40 or
above ([Docker Engine v19.03](https://docs.docker.com/reference/api/engine/#api-version-matrix)).
Users running older (end of life) versions of Docker Engine should update their
Docker Engine or use the [`DOCKER_API_VERSION`](https://docs.docker.com/reference/api/engine/#versioned-api-and-sdk)
environment variable to override the API version used by Traefik.
+17 -20
View File
@@ -17,8 +17,7 @@ require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd // No tag on the repo.
github.com/coreos/go-systemd/v22 v22.5.0
github.com/docker/cli v29.2.1+incompatible
github.com/docker/docker v28.5.2+incompatible
github.com/docker/cli v29.4.0+incompatible
github.com/docker/go-connections v0.6.0
github.com/fatih/structs v1.1.0
github.com/fsnotify/fsnotify v1.9.0
@@ -38,7 +37,7 @@ require (
github.com/influxdata/influxdb-client-go/v2 v2.7.0
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab // No tag on the repo.
github.com/instana/go-sensor v1.38.3
github.com/klauspost/compress v1.18.0
github.com/klauspost/compress v1.18.5
github.com/kvtools/consul v1.0.2
github.com/kvtools/etcdv3 v1.0.2
github.com/kvtools/redis v1.1.0
@@ -49,6 +48,8 @@ require (
github.com/mitchellh/copystructure v1.2.0
github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
github.com/moby/moby/api v1.54.1
github.com/moby/moby/client v0.4.0
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // No tag on the repo.
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
github.com/openzipkin/zipkin-go v0.2.5
@@ -59,10 +60,10 @@ require (
github.com/prometheus/client_model v0.6.1
github.com/quic-go/quic-go v0.57.1
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac // No tag on the repo.
github.com/sirupsen/logrus v1.9.3
github.com/sirupsen/logrus v1.9.4
github.com/stretchr/testify v1.11.1
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 // No tag on the repo.
github.com/testcontainers/testcontainers-go v0.32.0
github.com/testcontainers/testcontainers-go v0.42.0
github.com/traefik/paerser v0.2.2
github.com/traefik/yaegi v0.16.1
github.com/uber/jaeger-client-go v2.30.0+incompatible
@@ -94,7 +95,7 @@ require (
cloud.google.com/go/auth v0.20.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
dario.cat/mergo v1.0.1 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect
@@ -135,7 +136,6 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.13.0 // indirect
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/akamai/AkamaiOPEN-edgegrid-golang/v13 v13.1.0 // indirect
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect
@@ -169,13 +169,12 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/containerd/containerd v1.7.29 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v1.0.0-rc.1 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/cpuguy83/dockercfg v0.3.1 // indirect
github.com/cpuguy83/dockercfg v0.3.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deepmap/oapi-codegen v1.9.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
@@ -186,7 +185,7 @@ require (
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
github.com/ebitengine/purego v0.8.3 // indirect
github.com/ebitengine/purego v0.10.0 // indirect
github.com/elastic/go-sysinfo v1.7.1 // indirect
github.com/elastic/go-windows v1.0.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
@@ -272,7 +271,7 @@ require (
github.com/liquidweb/liquidweb-go v1.6.4 // indirect
github.com/looplab/fsm v0.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
github.com/mailgun/multibuf v0.1.2 // indirect
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
@@ -283,16 +282,14 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.1.0 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/go-archive v0.2.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/namedotcom/go/v4 v4.0.2 // indirect
github.com/nrdcg/auroradns v1.2.0 // indirect
@@ -342,9 +339,7 @@ require (
github.com/segmentio/fasthash v1.0.3 // indirect
github.com/selectel/domains-go v1.1.0 // indirect
github.com/selectel/go-selvpcclient/v4 v4.2.0 // indirect
github.com/shirou/gopsutil/v3 v3.24.4 // indirect
github.com/shirou/gopsutil/v4 v4.25.3 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/shirou/gopsutil/v4 v4.26.3 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/softlayer/softlayer-go v1.2.1 // indirect
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
@@ -357,10 +352,11 @@ require (
github.com/stretchr/objx v0.5.3 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83 // indirect
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0
github.com/tinylib/msgp v1.2.5 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/transip/gotransip/v6 v6.26.2 // indirect
github.com/ucloud/ucloud-sdk-go v0.22.63 // indirect
github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419 // indirect
@@ -396,6 +392,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/ratelimit v0.3.1 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect
golang.org/x/oauth2 v0.36.0 // indirect
+38 -59
View File
@@ -598,8 +598,8 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS
cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M=
cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=
cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
@@ -720,8 +720,6 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA=
github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -929,8 +927,6 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
@@ -960,16 +956,16 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
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/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -993,10 +989,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnsimple/dnsimple-go/v4 v4.0.0 h1:nUCICZSyZDiiqimAAL+E8XL+0sKGks5VRki5S8XotRo=
github.com/dnsimple/dnsimple-go/v4 v4.0.0/go.mod h1:AXT2yfAFOntJx6iMeo1J/zKBw0ggXFYBt4e97dqqPnc=
github.com/docker/cli v29.2.1+incompatible h1:n3Jt0QVCN65eiVBoUTZQM9mcQICCJt3akW4pKAbKdJg=
github.com/docker/cli v29.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/cli v29.4.0+incompatible h1:+IjXULMetlvWJiuSI0Nbor36lcJ5BTcVpUmB21KBoVM=
github.com/docker/cli v29.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -1019,8 +1013,8 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 h1:8EXxF+tCLqaVk8AOC29zl2mnhQjwyLxxOTuhUazWRsg=
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4/go.mod h1:I5sHm0Y0T1u5YjlyqC5GVArM7aNZRUYtTjmJ8mPJFds=
github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc=
github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
@@ -1393,12 +1387,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
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=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo=
@@ -1568,8 +1559,8 @@ github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
@@ -1631,7 +1622,6 @@ github.com/liquidweb/liquidweb-go v1.6.4/go.mod h1:B934JPIIcdA+uTq2Nz5PgOtG6CuCa
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
@@ -1641,8 +1631,9 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailgun/multibuf v0.1.2 h1:QE9kE27lK6LFZB4aYNVtUPlWVHVCT0zpgUr2uoq/+jk=
github.com/mailgun/multibuf v0.1.2/go.mod h1:E+sUhIy69qgT6EM57kCPdUTlHnjTuxQBO/yf6af9Hes=
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAFr1YToMs98dbCdhootQ1hZIvZU28hAQ=
@@ -1730,13 +1721,15 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
github.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4=
github.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw=
github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g=
github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U=
github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
@@ -1755,8 +1748,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
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=
@@ -1906,7 +1897,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
@@ -2009,13 +1999,8 @@ github.com/selectel/domains-go v1.1.0 h1:futG50J43ALLKQAnZk9H9yOtLGnSUh7c5hSvuC5
github.com/selectel/domains-go v1.1.0/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA=
github.com/selectel/go-selvpcclient/v4 v4.2.0 h1:tVqSAdmNcdshv3AgfaIwGHs1oLk4jX8Tm+ccMg1rBmc=
github.com/selectel/go-selvpcclient/v4 v4.2.0/go.mod h1:eFhL1KUW159KOJVeGO7k/Uxl0TYd/sBkWXjuF5WxmYk=
github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE=
github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shirou/gopsutil/v4 v4.26.3 h1:2ESdQt90yU3oXF/CdOlRCJxrP+Am1aBYubTMTfxJ1qc=
github.com/shirou/gopsutil/v4 v4.26.3/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/shoenig/test v1.7.0 h1:eWcHtTXa6QLnBvm0jgEabMRN/uJ4DMV3M8xUGgRkZmk=
github.com/shoenig/test v1.7.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@@ -2028,8 +2013,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@@ -2104,7 +2089,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g=
@@ -2117,19 +2101,19 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.24/go.mod h
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.38/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83 h1:C8ro7XQVV17O+A7zUTe28VK02NuyazuaY0CB2CH5Scw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHPS+/alvLJU/DRxTD/ME=
github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E=
github.com/testcontainers/testcontainers-go v0.42.0 h1:He3IhTzTZOygSXLJPMX7n44XtK+qhjat1nI9cneBbUY=
github.com/testcontainers/testcontainers-go v0.42.0/go.mod h1:vZjdY1YmUA1qEForxOIOazfsrdyORJAbhi0bp8plN30=
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0 h1:bTVmcnYaSHesN6HXXxV/k0+BMkyfo3VBy4w4yRqOIgE=
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0/go.mod h1:2O8+V4WzMb/bjg/Sez+aYci9LpGUbT5cSz7ildfTIb8=
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ=
@@ -2288,10 +2272,6 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:Oyrsyzu
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
go.opentelemetry.io/otel/log v0.11.0 h1:c24Hrlk5WJ8JWcwbQxdBqxZdOK7PcP/LFtOtwpDTe3Y=
go.opentelemetry.io/otel/log v0.11.0/go.mod h1:U/sxQ83FPmT29trrifhQg+Zj2lo1/IPN1PF6RTFqdwc=
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
@@ -2305,8 +2285,6 @@ go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLh
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -2335,6 +2313,8 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -2707,7 +2687,6 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2722,14 +2701,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
@@ -3308,6 +3285,8 @@ modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+12 -7
View File
@@ -11,6 +11,7 @@ import (
"io/fs"
stdlog "log"
"net/http"
"net/netip"
"os"
"os/exec"
"path/filepath"
@@ -22,10 +23,11 @@ import (
"text/template"
"time"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
dockernetwork "github.com/docker/docker/api/types/network"
"github.com/fatih/structs"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/mount"
dockernetwork "github.com/moby/moby/api/types/network"
"github.com/moby/moby/client"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/testcontainers/testcontainers-go"
@@ -37,7 +39,10 @@ import (
var showLog = flag.Bool("tlog", false, "always show Traefik logs")
const tailscaleSecretFilePath = "tailscale.secret"
const (
tailscaleSecretFilePath = "tailscale.secret"
k3sImage = "docker.io/rancher/k3s:v1.21.14-k3s1"
)
type composeConfig struct {
Services map[string]composeService `yaml:"services"`
@@ -87,7 +92,7 @@ func (s *BaseSuite) SetupSuite() {
Driver: "default",
Config: []dockernetwork.IPAMConfig{
{
Subnet: "172.31.42.0/24",
Subnet: netip.MustParsePrefix("172.31.42.0/24"),
},
},
}))
@@ -140,12 +145,12 @@ func isDockerDesktop(ctx context.Context, t *testing.T) bool {
t.Fatalf("failed to create docker client: %s", err)
}
info, err := cli.Info(ctx)
res, err := cli.Info(ctx, client.InfoOptions{})
if err != nil {
t.Fatalf("failed to get docker info: %s", err)
}
return info.OperatingSystem == "Docker Desktop"
return res.Info.OperatingSystem == "Docker Desktop"
}
func (s *BaseSuite) TearDownSuite() {
+30 -28
View File
@@ -7,18 +7,18 @@ import (
"flag"
"fmt"
"io"
"net"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
"time"
"github.com/pmezard/go-difflib/difflib"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/k3s"
"github.com/traefik/traefik/v2/integration/try"
"github.com/traefik/traefik/v2/pkg/api"
"github.com/traefik/traefik/v2/pkg/log"
@@ -27,7 +27,11 @@ import (
var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata")
// K8sSuite tests suite.
type K8sSuite struct{ BaseSuite }
type K8sSuite struct {
BaseSuite
k3sContainer *k3s.K3sContainer
}
func TestK8sSuite(t *testing.T) {
suite.Run(t, new(K8sSuite))
@@ -36,47 +40,45 @@ func TestK8sSuite(t *testing.T) {
func (s *K8sSuite) SetupSuite() {
s.BaseSuite.SetupSuite()
s.createComposeProject("k8s")
s.composeUp()
abs, err := filepath.Abs("./fixtures/k8s/config.skip/kubeconfig.yaml")
manifests, err := filepath.Glob("./fixtures/k8s/*.yml")
require.NoError(s.T(), err)
err = try.Do(60*time.Second, func() error {
_, err := os.Stat(abs)
return err
})
opts := make([]testcontainers.ContainerCustomizer, 0, len(manifests))
for _, m := range manifests {
opts = append(opts, k3s.WithManifest(m))
}
s.k3sContainer, err = k3s.Run(s.T().Context(), k3sImage, opts...)
require.NoError(s.T(), err)
data, err := os.ReadFile(abs)
kubeConfigYaml, err := s.k3sContainer.GetKubeConfig(s.T().Context())
require.NoError(s.T(), err)
content := strings.ReplaceAll(string(data), "https://server:6443", fmt.Sprintf("https://%s", net.JoinHostPort(s.getComposeServiceIP("server"), "6443")))
err = os.WriteFile(abs, []byte(content), 0o644)
kubeconfigPath := filepath.Join(s.T().TempDir(), "kubeconfig.yaml")
err = os.WriteFile(kubeconfigPath, kubeConfigYaml, 0o644)
require.NoError(s.T(), err)
err = os.Setenv("KUBECONFIG", abs)
err = os.Setenv("KUBECONFIG", kubeconfigPath)
require.NoError(s.T(), err)
}
func (s *K8sSuite) TearDownSuite() {
s.BaseSuite.TearDownSuite()
if s.k3sContainer != nil {
if s.T().Failed() || *showLog {
k3sLogs, err := s.k3sContainer.Logs(s.T().Context())
if err == nil {
if res, err := io.ReadAll(k3sLogs); err == nil {
s.T().Log(string(res))
}
}
}
generatedFiles := []string{
"./fixtures/k8s/config.skip/kubeconfig.yaml",
"./fixtures/k8s/config.skip/k3s.log",
"./fixtures/k8s/coredns.yaml",
"./fixtures/k8s/rolebindings.yaml",
"./fixtures/k8s/traefik.yaml",
"./fixtures/k8s/ccm.yaml",
}
for _, filename := range generatedFiles {
if err := os.Remove(filename); err != nil {
if err := s.k3sContainer.Terminate(s.T().Context()); err != nil {
log.WithoutContext().Warning(err)
}
}
s.BaseSuite.TearDownSuite()
}
func (s *K8sSuite) TestIngressConfiguration() {
-34
View File
@@ -1,34 +0,0 @@
version: "3.8"
services:
server:
image: rancher/k3s:v1.20.15-k3s1
privileged: true
command:
- server
- --disable-agent
- --disable=coredns
- --disable=servicelb
- --disable=traefik
- --disable=local-storage
- --disable=metrics-server
- --log=/output/k3s.log
- --bind-address=server
- --tls-san=server
- --tls-san=172.31.42.3
- --tls-san=172.31.42.4
environment:
K3S_CLUSTER_SECRET: somethingtotallyrandom
K3S_TOKEN: somethingtotallyrandom
K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
K3S_KUBECONFIG_MODE: 666
volumes:
- ./fixtures/k8s/config.skip:/output
- ./fixtures/k8s:/var/lib/rancher/k3s/server/manifests
node:
image: rancher/k3s:v1.20.15-k3s1
privileged: true
environment:
K3S_TOKEN: somethingtotallyrandom
K3S_URL: https://server:6443
K3S_CLUSTER_SECRET: somethingtotallyrandom
+38 -21
View File
@@ -1,18 +1,17 @@
package docker
import (
dockercontainertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
"net/netip"
dockercontainertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/network"
"github.com/moby/moby/api/types/swarm"
)
func containerJSON(ops ...func(*dockercontainertypes.InspectResponse)) dockercontainertypes.InspectResponse {
c := &dockercontainertypes.InspectResponse{
ContainerJSONBase: &dockercontainertypes.ContainerJSONBase{
Name: "fake",
HostConfig: &dockercontainertypes.HostConfig{},
},
Name: "fake",
HostConfig: &dockercontainertypes.HostConfig{},
Config: &dockercontainertypes.Config{},
NetworkSettings: &dockercontainertypes.NetworkSettings{},
}
@@ -26,17 +25,17 @@ func containerJSON(ops ...func(*dockercontainertypes.InspectResponse)) dockercon
func name(name string) func(*dockercontainertypes.InspectResponse) {
return func(c *dockercontainertypes.InspectResponse) {
c.ContainerJSONBase.Name = name
c.Name = name
}
}
func networkMode(mode string) func(*dockercontainertypes.InspectResponse) {
return func(c *dockercontainertypes.InspectResponse) {
c.ContainerJSONBase.HostConfig.NetworkMode = dockercontainertypes.NetworkMode(mode)
c.HostConfig.NetworkMode = dockercontainertypes.NetworkMode(mode)
}
}
func ports(portMap nat.PortMap) func(*dockercontainertypes.InspectResponse) {
func ports(portMap network.PortMap) func(*dockercontainertypes.InspectResponse) {
return func(c *dockercontainertypes.InspectResponse) {
c.NetworkSettings.Ports = portMap
}
@@ -56,13 +55,13 @@ func withNetwork(name string, ops ...func(*network.EndpointSettings)) func(*dock
func ipv4(ip string) func(*network.EndpointSettings) {
return func(s *network.EndpointSettings) {
s.IPAddress = ip
s.IPAddress = netip.MustParseAddr(ip).Unmap()
}
}
func ipv6(ip string) func(*network.EndpointSettings) {
return func(s *network.EndpointSettings) {
s.GlobalIPv6Address = ip
s.GlobalIPv6Address = netip.MustParseAddr(ip)
}
}
@@ -91,20 +90,20 @@ func taskNodeID(id string) func(*swarm.Task) {
}
func taskNetworkAttachment(id, name, driver string, addresses []string) func(*swarm.Task) {
prefixes := make([]netip.Prefix, len(addresses))
for i, s := range addresses {
prefixes[i] = mustParseAddrOrPrefix(s)
}
return func(task *swarm.Task) {
task.NetworksAttachments = append(task.NetworksAttachments, swarm.NetworkAttachment{
Network: swarm.Network{
ID: id,
Spec: swarm.NetworkSpec{
Annotations: swarm.Annotations{
Name: name,
},
DriverConfiguration: &swarm.Driver{
Name: driver,
},
Annotations: swarm.Annotations{Name: name},
DriverConfiguration: &swarm.Driver{Name: driver},
},
},
Addresses: addresses,
Addresses: prefixes,
})
}
}
@@ -183,7 +182,7 @@ func virtualIP(networkID, addr string) func(*swarm.Endpoint) {
}
endpoint.VirtualIPs = append(endpoint.VirtualIPs, swarm.EndpointVirtualIP{
NetworkID: networkID,
Addr: addr,
Addr: mustParseAddrOrPrefix(addr),
})
}
}
@@ -207,3 +206,21 @@ func modeDNSRR(spec *swarm.EndpointSpec) {
func modeVIP(spec *swarm.EndpointSpec) {
spec.Mode = swarm.ResolutionModeVIP
}
// mustParseAddrOrPrefix parses addrOrPrefix into a [netip.Prefix].
//
// We should expect only IP-addresses, but for backwards-compatibility,
// the Addresses field on [swarm.NetworkAttachment] accepts a prefix.
func mustParseAddrOrPrefix(addrOrPrefix string) netip.Prefix {
if addrOrPrefix == "" {
return netip.Prefix{}
}
if p, err := netip.ParsePrefix(addrOrPrefix); err == nil {
return p
}
a := netip.MustParseAddr(addrOrPrefix)
if a.Is4() {
return netip.PrefixFrom(a, 32)
}
return netip.PrefixFrom(a, 128)
}
+24 -23
View File
@@ -1,14 +1,17 @@
package docker
import (
"cmp"
"context"
"errors"
"fmt"
"net"
"slices"
"strings"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/go-connections/nat"
containertypes "github.com/moby/moby/api/types/container"
networktypes "github.com/moby/moby/api/types/network"
"github.com/moby/moby/client"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/config/label"
"github.com/traefik/traefik/v2/pkg/log"
@@ -103,7 +106,7 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != string(containertypes.Healthy) {
return nil
}
@@ -127,7 +130,7 @@ func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, container d
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != string(containertypes.Healthy) {
return nil
}
@@ -153,7 +156,7 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, container dock
}
}
if container.Health != "" && container.Health != dockertypes.Healthy {
if container.Health != "" && container.Health != string(containertypes.Healthy) {
return nil
}
@@ -185,7 +188,7 @@ func (p *Provider) keepContainer(ctx context.Context, container dockerData) bool
return false
}
if !p.AllowEmptyServices && container.Health != "" && container.Health != dockertypes.Healthy {
if !p.AllowEmptyServices && container.Health != "" && container.Health != string(containertypes.Healthy) {
logger.Debug("Filtering unhealthy or starting container")
return false
}
@@ -286,10 +289,10 @@ func (p *Provider) getIPPort(ctx context.Context, container dockerData, serverPo
switch {
case err != nil:
logger.Infof("Unable to find a binding for container %q, falling back on its internal IP/Port.", container.Name)
case portBinding.HostIP == "0.0.0.0" || len(portBinding.HostIP) == 0:
case portBinding.HostIP.IsUnspecified() || !portBinding.HostIP.IsValid():
logger.Infof("Cannot determine the IP address (got %q) for %q's binding, falling back on its internal IP/Port.", portBinding.HostIP, container.Name)
default:
ip = portBinding.HostIP
ip = portBinding.HostIP.String()
port = portBinding.HostPort
usedBound = true
}
@@ -345,7 +348,7 @@ func (p *Provider) getIPAddress(ctx context.Context, container dockerData) strin
}
connectedContainer := container.NetworkSettings.NetworkMode.ConnectedContainer()
containerInspected, err := dockerClient.ContainerInspect(context.Background(), connectedContainer)
res, err := dockerClient.ContainerInspect(context.Background(), connectedContainer, client.ContainerInspectOptions{})
if err != nil {
logger.Warnf("Unable to get IP address for container %s : Failed to inspect container ID %s, error: %s", container.Name, connectedContainer, err)
return ""
@@ -353,10 +356,10 @@ func (p *Provider) getIPAddress(ctx context.Context, container dockerData) strin
// Check connected container for traefik.docker.network, falling back to
// the network specified on the current container.
containerParsed := parseContainer(containerInspected)
containerParsed := parseContainer(res.Container)
extraConf, err := p.getConfiguration(containerParsed)
if err != nil {
logger.Warnf("Unable to get IP address for container %s : failed to get extra configuration for container %s: %s", container.Name, containerInspected.Name, err)
logger.Warnf("Unable to get IP address for container %s : failed to get extra configuration for container %s: %s", container.Name, res.Container.Name, err)
return ""
}
@@ -379,10 +382,10 @@ func (p *Provider) getIPAddress(ctx context.Context, container dockerData) strin
return ""
}
func (p *Provider) getPortBinding(container dockerData, serverPort string) (*nat.PortBinding, error) {
func (p *Provider) getPortBinding(container dockerData, serverPort string) (*networktypes.PortBinding, error) {
port := getPort(container, serverPort)
for netPort, portBindings := range container.NetworkSettings.Ports {
if strings.EqualFold(string(netPort), port+"/TCP") || strings.EqualFold(string(netPort), port+"/UDP") {
if netPort.Port() == port && (netPort.Proto() == networktypes.TCP || netPort.Proto() == networktypes.UDP) {
for _, p := range portBindings {
return &p, nil
}
@@ -396,22 +399,20 @@ func getPort(container dockerData, serverPort string) string {
if len(serverPort) > 0 {
return serverPort
}
if len(container.NetworkSettings.Ports) == 0 {
return ""
}
var ports []nat.Port
var ports []networktypes.Port
for port := range container.NetworkSettings.Ports {
ports = append(ports, port)
}
less := func(i, j nat.Port) bool {
return i.Int() < j.Int()
}
nat.Sort(ports, less)
slices.SortFunc(ports, func(a, b networktypes.Port) int {
return cmp.Compare(a.Num(), b.Num())
})
if len(ports) > 0 {
return ports[0].Port()
}
return ""
return ports[0].Port()
}
func getServiceName(container dockerData) string {
+180 -181
View File
@@ -1,14 +1,13 @@
package docker
import (
"net/netip"
"strconv"
"testing"
docker "github.com/docker/docker/api/types"
dockercontainertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
dockercontainertypes "github.com/moby/moby/api/types/container"
networktypes "github.com/moby/moby/api/types/network"
swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
@@ -31,8 +30,8 @@ func TestDefaultRule(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -90,8 +89,8 @@ func TestDefaultRule(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -151,8 +150,8 @@ func TestDefaultRule(t *testing.T) {
"traefik.domain": "foo.bar",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -210,8 +209,8 @@ func TestDefaultRule(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -263,8 +262,8 @@ func TestDefaultRule(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -316,8 +315,8 @@ func TestDefaultRule(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -413,8 +412,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.test": "",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -456,8 +455,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.services.test": "",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -499,8 +498,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.udp.services.test": "",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/udp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/udp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -540,8 +539,8 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -598,8 +597,8 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -614,8 +613,8 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test2",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -688,8 +687,8 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -705,8 +704,8 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -768,8 +767,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -830,8 +829,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.service": "Service1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -889,8 +888,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -949,8 +948,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1010,8 +1009,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service2.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1075,8 +1074,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.service": "Service1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1135,8 +1134,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1154,8 +1153,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "false",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1204,8 +1203,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "false",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1223,8 +1222,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1242,8 +1241,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1292,8 +1291,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1311,8 +1310,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1374,8 +1373,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1441,8 +1440,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1460,8 +1459,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1530,8 +1529,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1549,8 +1548,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "41",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1613,8 +1612,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1632,8 +1631,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "41",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1651,8 +1650,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "40",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1718,8 +1717,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1737,8 +1736,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1795,8 +1794,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1814,8 +1813,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1833,8 +1832,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foobar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1894,8 +1893,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1913,8 +1912,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1975,8 +1974,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -1993,8 +1992,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2057,8 +2056,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.wrong.label": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2118,8 +2117,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.LoadBalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2179,8 +2178,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service2.LoadBalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2241,7 +2240,7 @@ func Test_buildConfiguration(t *testing.T) {
Name: "Test",
Labels: map[string]string{},
NetworkSettings: networkSettings{
Ports: nat.PortMap{},
Ports: networktypes.PortMap{},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
@@ -2282,7 +2281,7 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.middlewares.Middleware1.inflightreq.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{},
Ports: networktypes.PortMap{},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
@@ -2323,8 +2322,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.enable": "false",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2362,7 +2361,7 @@ func Test_buildConfiguration(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
},
},
expected: &dynamic.Configuration{
@@ -2393,7 +2392,7 @@ func Test_buildConfiguration(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
},
},
expected: &dynamic.Configuration{
@@ -2435,7 +2434,7 @@ func Test_buildConfiguration(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
},
@@ -2469,7 +2468,7 @@ func Test_buildConfiguration(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
Labels: map[string]string{
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
},
@@ -2513,7 +2512,7 @@ func Test_buildConfiguration(t *testing.T) {
{
ServiceName: "Test",
Name: "Test",
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
Labels: map[string]string{
"traefik.udp.routers.foo": "true",
},
@@ -2550,7 +2549,7 @@ func Test_buildConfiguration(t *testing.T) {
Labels: map[string]string{
"traefik.udp.routers.foo": "true",
},
Health: docker.Unhealthy,
Health: string(dockercontainertypes.Unhealthy),
},
},
expected: &dynamic.Configuration{
@@ -2592,8 +2591,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tags": "foo",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2636,8 +2635,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tags": "foo",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2698,8 +2697,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.routers.Test.middlewares": "Middleware1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2770,8 +2769,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.routers.Test.middlewares": "Middleware1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2837,8 +2836,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.routers.foo.tls": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2897,8 +2896,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.udp.routers.foo.entrypoints": "mydns",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -2955,8 +2954,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.routers.foo.tls": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3011,8 +3010,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3074,8 +3073,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3134,8 +3133,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3155,8 +3154,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3236,8 +3235,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3290,8 +3289,8 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tcp.services.foo.loadbalancer.terminationdelay": "200",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
Ports: networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
@@ -3344,13 +3343,13 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.http.services.Test.loadbalancer.server.port": "80",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("79/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
Ports: networktypes.PortMap{
networktypes.MustParsePort("79/tcp"): []networktypes.PortBinding{{
HostIP: netip.MustParseAddr("192.168.0.1"),
HostPort: "8080",
}},
nat.Port("80/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{{
HostIP: netip.MustParseAddr("192.168.0.1"),
HostPort: "8081",
}},
},
@@ -3414,13 +3413,13 @@ func Test_buildConfiguration(t *testing.T) {
"traefik.tls.stores.default.defaultgeneratedcert.domain.sans": "foobar, fiibar",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("79/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
Ports: networktypes.PortMap{
networktypes.MustParsePort("79/tcp"): []networktypes.PortBinding{{
HostIP: netip.MustParseAddr("192.168.0.1"),
HostPort: "8080",
}},
nat.Port("80/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{{
HostIP: netip.MustParseAddr("192.168.0.1"),
HostPort: "8081",
}},
},
@@ -3527,8 +3526,8 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port not set, no binding, falling back on the container's IP/Port",
container: containerJSON(
ports(nat.PortMap{
"8080/tcp": {},
ports(networktypes.PortMap{
networktypes.MustParsePort("8080/tcp"): {},
}),
withNetwork("testnet", ipv4("10.11.12.13"))),
expected: expected{
@@ -3540,8 +3539,8 @@ func TestDockerGetIPPort(t *testing.T) {
desc: "label traefik.port not set, single binding with port only, falling back on the container's IP/Port",
container: containerJSON(
withNetwork("testnet", ipv4("10.11.12.13")),
ports(nat.PortMap{
"80/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{
{
HostPort: "8082",
},
@@ -3556,10 +3555,10 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port not set, binding with ip:port should create a route to the bound ip:port",
container: containerJSON(
ports(nat.PortMap{
"80/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{
{
HostIP: "1.2.3.4",
HostIP: netip.MustParseAddr("1.2.3.4"),
HostPort: "8081",
},
},
@@ -3582,10 +3581,10 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port set, single binding with ip:port for the label, creates the route",
container: containerJSON(
ports(nat.PortMap{
"443/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("443/tcp"): []networktypes.PortBinding{
{
HostIP: "5.6.7.8",
HostIP: netip.MustParseAddr("5.6.7.8"),
HostPort: "8082",
},
},
@@ -3600,10 +3599,10 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port set, no binding on the corresponding port, falling back on the container's IP/label.port",
container: containerJSON(
ports(nat.PortMap{
"443/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("443/tcp"): []networktypes.PortBinding{
{
HostIP: "5.6.7.8",
HostIP: netip.MustParseAddr("5.6.7.8"),
HostPort: "8082",
},
},
@@ -3618,16 +3617,16 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port set, multiple bindings on different ports, uses the label to select the correct (first) binding",
container: containerJSON(
ports(nat.PortMap{
"80/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{
{
HostIP: "1.2.3.4",
HostIP: netip.MustParseAddr("1.2.3.4"),
HostPort: "8081",
},
},
"443/tcp": []nat.PortBinding{
networktypes.MustParsePort("443/tcp"): []networktypes.PortBinding{
{
HostIP: "5.6.7.8",
HostIP: netip.MustParseAddr("5.6.7.8"),
HostPort: "8082",
},
},
@@ -3642,16 +3641,16 @@ func TestDockerGetIPPort(t *testing.T) {
{
desc: "label traefik.port set, multiple bindings on different ports, uses the label to select the correct (second) binding",
container: containerJSON(
ports(nat.PortMap{
"80/tcp": []nat.PortBinding{
ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): []networktypes.PortBinding{
{
HostIP: "1.2.3.4",
HostIP: netip.MustParseAddr("1.2.3.4"),
HostPort: "8081",
},
},
"443/tcp": []nat.PortBinding{
networktypes.MustParsePort("443/tcp"): []networktypes.PortBinding{
{
HostIP: "5.6.7.8",
HostIP: netip.MustParseAddr("5.6.7.8"),
HostPort: "8082",
},
},
@@ -3702,16 +3701,16 @@ func TestDockerGetPort(t *testing.T) {
},
{
desc: "binding, no server port label",
container: containerJSON(ports(nat.PortMap{
"80/tcp": {},
container: containerJSON(ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): {},
})),
expected: "80",
},
{
desc: "binding, multiple ports, no server port label",
container: containerJSON(ports(nat.PortMap{
"80/tcp": {},
"443/tcp": {},
container: containerJSON(ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): {},
networktypes.MustParsePort("443/tcp"): {},
})),
expected: "80",
},
@@ -3724,17 +3723,17 @@ func TestDockerGetPort(t *testing.T) {
{
desc: "binding, server port label",
container: containerJSON(
ports(nat.PortMap{
"80/tcp": {},
ports(networktypes.PortMap{
networktypes.MustParsePort("80/tcp"): {},
})),
serverPort: "8080",
expected: "8080",
},
{
desc: "binding, multiple ports, server port label",
container: containerJSON(ports(nat.PortMap{
"8080/tcp": {},
"80/tcp": {},
container: containerJSON(ports(networktypes.PortMap{
networktypes.MustParsePort("8080/tcp"): {},
networktypes.MustParsePort("80/tcp"): {},
})),
serverPort: "8080",
expected: "8080",
@@ -3886,7 +3885,7 @@ func TestSwarmGetIPAddress(t *testing.T) {
expected: "10.11.12.13",
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
Network: networktypes.Network{Name: "foo"},
},
},
},
@@ -3904,10 +3903,10 @@ func TestSwarmGetIPAddress(t *testing.T) {
expected: "10.11.12.99",
networks: map[string]*networktypes.Summary{
"1": {
Name: "foonet",
Network: networktypes.Network{Name: "foonet"},
},
"2": {
Name: "barnet",
Network: networktypes.Network{Name: "barnet"},
},
},
},
+61 -70
View File
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"net"
"net/http"
"strconv"
"strings"
@@ -14,15 +13,13 @@ import (
"github.com/cenkalti/backoff/v4"
"github.com/docker/cli/cli/connhelper"
dockercontainertypes "github.com/docker/docker/api/types/container"
eventtypes "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"github.com/docker/go-connections/sockets"
dockercontainertypes "github.com/moby/moby/api/types/container"
eventtypes "github.com/moby/moby/api/types/events"
networktypes "github.com/moby/moby/api/types/network"
swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/versions"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/job"
@@ -91,7 +88,7 @@ type dockerData struct {
// NetworkSettings holds the networks data to the provider.
type networkSettings struct {
NetworkMode dockercontainertypes.NetworkMode
Ports nat.PortMap
Ports networktypes.PortMap
Networks map[string]*networkData
}
@@ -124,7 +121,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
}
defer dockerClient.Close()
serverVersion, err := dockerClient.ServerVersion(ctx)
serverVersion, err := dockerClient.ServerVersion(ctx, client.ServerVersionOptions{})
if err != nil {
logger.Errorf("Failed to retrieve information of the docker client and server host: %s", err)
return err
@@ -191,12 +188,6 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
}
// channel closed
} else {
f := filters.NewArgs()
f.Add("type", "container")
options := eventtypes.ListOptions{
Filters: f,
}
startStopHandle := func(m eventtypes.Message) {
logger.Debugf("Provider event received %+v", m)
containers, err := p.listContainers(ctx, dockerClient)
@@ -219,16 +210,18 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
}
}
eventsc, errc := dockerClient.Events(ctx, options)
res := dockerClient.Events(ctx, client.EventsListOptions{
Filters: make(client.Filters).Add("type", string(eventtypes.ContainerEventType)),
})
for {
select {
case event := <-eventsc:
case event := <-res.Messages:
if event.Action == "start" ||
event.Action == "die" ||
strings.HasPrefix(string(event.Action), "health_status") {
startStopHandle(event)
}
case err := <-errc:
case err := <-res.Err:
if errors.Is(err, io.EOF) {
logger.Debug("Provider event stream closed")
}
@@ -265,10 +258,9 @@ func (p *Provider) createClient() (client.APIClient, error) {
}
opts = append(opts,
client.FromEnv,
client.WithAPIVersionNegotiation(),
client.WithHTTPHeaders(httpHeaders))
return client.NewClientWithOpts(opts...)
return client.New(opts...)
}
func (p *Provider) getClientOpts() ([]client.Opt, error) {
@@ -328,14 +320,14 @@ func (p *Provider) getClientOpts() ([]client.Opt, error) {
}
func (p *Provider) listContainers(ctx context.Context, dockerClient client.ContainerAPIClient) ([]dockerData, error) {
containerList, err := dockerClient.ContainerList(ctx, dockercontainertypes.ListOptions{})
containerList, err := dockerClient.ContainerList(ctx, client.ContainerListOptions{})
if err != nil {
return nil, err
}
var inspectedContainers []dockerData
// get inspect containers
for _, container := range containerList {
for _, container := range containerList.Items {
dData := inspectContainers(ctx, dockerClient, container.ID)
if len(dData.Name) == 0 {
continue
@@ -354,7 +346,7 @@ func (p *Provider) listContainers(ctx context.Context, dockerClient client.Conta
}
func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClient, containerID string) dockerData {
containerInspected, err := dockerClient.ContainerInspect(ctx, containerID)
res, err := dockerClient.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
if err != nil {
log.FromContext(ctx).Warnf("Failed to inspect container %s, error: %s", containerID, err)
return dockerData{}
@@ -362,8 +354,8 @@ func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClie
// This condition is here to avoid to have empty IP https://github.com/traefik/traefik/issues/2459
// We register only container which are running
if containerInspected.ContainerJSONBase != nil && containerInspected.ContainerJSONBase.State != nil && containerInspected.ContainerJSONBase.State.Running {
return parseContainer(containerInspected)
if res.Container.State != nil && res.Container.State.Running {
return parseContainer(res.Container)
}
return dockerData{}
@@ -371,21 +363,18 @@ func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClie
func parseContainer(container dockercontainertypes.InspectResponse) dockerData {
dData := dockerData{
ID: container.ID,
Name: container.Name,
ServiceName: container.Name, // Default ServiceName to be the container's Name.
NetworkSettings: networkSettings{},
}
if container.ContainerJSONBase != nil {
dData.ID = container.ContainerJSONBase.ID
dData.Name = container.ContainerJSONBase.Name
dData.ServiceName = dData.Name // Default ServiceName to be the container's Name.
if container.HostConfig != nil {
dData.NetworkSettings.NetworkMode = container.HostConfig.NetworkMode
}
if container.ContainerJSONBase.HostConfig != nil {
dData.NetworkSettings.NetworkMode = container.ContainerJSONBase.HostConfig.NetworkMode
}
if container.State != nil && container.State.Health != nil {
dData.Health = container.State.Health.Status
}
if container.State != nil && container.State.Health != nil {
dData.Health = string(container.State.Health.Status)
}
if container.Config != nil && container.Config.Labels != nil {
@@ -399,9 +388,11 @@ func parseContainer(container dockercontainertypes.InspectResponse) dockerData {
if container.NetworkSettings.Networks != nil {
dData.NetworkSettings.Networks = make(map[string]*networkData)
for name, containerNetwork := range container.NetworkSettings.Networks {
addr := containerNetwork.IPAddress
if addr == "" {
addr = containerNetwork.GlobalIPv6Address
var addr string
if containerNetwork.IPAddress.IsValid() {
addr = containerNetwork.IPAddress.String()
} else if containerNetwork.GlobalIPv6Address.IsValid() {
addr = containerNetwork.GlobalIPv6Address.String()
}
dData.NetworkSettings.Networks[name] = &networkData{
@@ -418,17 +409,17 @@ func parseContainer(container dockercontainertypes.InspectResponse) dockerData {
func (p *Provider) listServices(ctx context.Context, dockerClient client.APIClient) ([]dockerData, error) {
logger := log.FromContext(ctx)
serviceList, err := dockerClient.ServiceList(ctx, swarmtypes.ServiceListOptions{})
serviceList, err := dockerClient.ServiceList(ctx, client.ServiceListOptions{})
if err != nil {
return nil, err
}
serverVersion, err := dockerClient.ServerVersion(ctx)
serverVersion, err := dockerClient.ServerVersion(ctx, client.ServerVersionOptions{})
if err != nil {
return nil, err
}
networkListArgs := filters.NewArgs()
networkListArgs := client.Filters{}
// https://docs.docker.com/engine/api/v1.29/#tag/Network (Docker 17.06)
if versions.GreaterThanOrEqualTo(serverVersion.APIVersion, "1.29") {
networkListArgs.Add("scope", "swarm")
@@ -436,21 +427,21 @@ func (p *Provider) listServices(ctx context.Context, dockerClient client.APIClie
networkListArgs.Add("driver", "overlay")
}
networkList, err := dockerClient.NetworkList(ctx, networktypes.ListOptions{Filters: networkListArgs})
networkList, err := dockerClient.NetworkList(ctx, client.NetworkListOptions{Filters: networkListArgs})
if err != nil {
logger.Debugf("Failed to network inspect on client for docker, error: %s", err)
return nil, err
}
networkMap := make(map[string]*networktypes.Summary)
for _, network := range networkList {
for _, network := range networkList.Items {
networkMap[network.ID] = &network
}
var dockerDataList []dockerData
var dockerDataListTasks []dockerData
for _, service := range serviceList {
for _, service := range serviceList.Items {
dData, err := p.parseService(ctx, service, networkMap)
if err != nil {
logger.Errorf("Skip container %s: %v", getServiceName(dData), err)
@@ -501,21 +492,20 @@ func (p *Provider) parseService(ctx context.Context, service swarmtypes.Service,
dData.NetworkSettings.Networks = make(map[string]*networkData)
for _, virtualIP := range service.Endpoint.VirtualIPs {
networkService := networkMap[virtualIP.NetworkID]
if networkService != nil {
if len(virtualIP.Addr) > 0 {
ip, _, _ := net.ParseCIDR(virtualIP.Addr)
network := &networkData{
Name: networkService.Name,
ID: virtualIP.NetworkID,
Addr: ip.String(),
}
dData.NetworkSettings.Networks[network.Name] = network
} else {
logger.Debugf("No virtual IPs found in network %s", virtualIP.NetworkID)
}
} else {
if networkService == nil {
logger.Debugf("Network not found, id: %s", virtualIP.NetworkID)
continue
}
if !virtualIP.Addr.Addr().IsValid() {
logger.Debugf("No virtual IPs found in network %s", virtualIP.NetworkID)
continue
}
network := &networkData{
Name: networkService.Name,
ID: virtualIP.NetworkID,
Addr: virtualIP.Addr.Addr().String(),
}
dData.NetworkSettings.Networks[network.Name] = network
}
}
}
@@ -525,17 +515,15 @@ func (p *Provider) parseService(ctx context.Context, service swarmtypes.Service,
func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID string,
serviceDockerData dockerData, networkMap map[string]*networktypes.Summary, isGlobalSvc bool,
) ([]dockerData, error) {
serviceIDFilter := filters.NewArgs()
serviceIDFilter.Add("service", serviceID)
serviceIDFilter.Add("desired-state", "running")
taskList, err := dockerClient.TaskList(ctx, swarmtypes.TaskListOptions{Filters: serviceIDFilter})
taskList, err := dockerClient.TaskList(ctx, client.TaskListOptions{
Filters: make(client.Filters).Add("service", serviceID).Add("desired-state", "running"),
})
if err != nil {
return nil, err
}
var dockerDataList []dockerData
for _, task := range taskList {
for _, task := range taskList.Items {
if task.Status.State != swarmtypes.TaskStateRunning {
continue
}
@@ -570,11 +558,11 @@ func parseTasks(ctx context.Context, dockerClient client.APIClient, task swarmty
}
if task.NodeID != "" {
node, _, err := dockerClient.NodeInspectWithRaw(ctx, task.NodeID)
res, err := dockerClient.NodeInspect(ctx, task.NodeID, client.NodeInspectOptions{})
if err != nil {
return dockerData{}, fmt.Errorf("inspecting node %s: %w", task.NodeID, err)
}
dData.NodeIP = node.Status.Addr
dData.NodeIP = res.Node.Status.Addr
}
if task.NetworksAttachments != nil {
@@ -584,11 +572,14 @@ func parseTasks(ctx context.Context, dockerClient client.APIClient, task swarmty
if len(virtualIP.Addresses) > 0 {
// Not sure about this next loop - when would a task have multiple IP's for the same network?
for _, addr := range virtualIP.Addresses {
ip, _, _ := net.ParseCIDR(addr)
var ip string
if addr.IsValid() {
ip = addr.Addr().String()
}
network := &networkData{
ID: virtualIP.Network.ID,
Name: networkService.Name,
Addr: ip.String(),
Addr: ip,
}
dData.NetworkSettings.Networks[network.Name] = network
}
+60 -57
View File
@@ -6,29 +6,28 @@ import (
"testing"
"time"
dockertypes "github.com/docker/docker/api/types"
dockercontainertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
dockerclient "github.com/docker/docker/client"
dockercontainertypes "github.com/moby/moby/api/types/container"
networktypes "github.com/moby/moby/api/types/network"
swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type fakeTasksClient struct {
dockerclient.APIClient
client.APIClient
tasks []swarmtypes.Task
container dockercontainertypes.InspectResponse
err error
}
func (c *fakeTasksClient) TaskList(ctx context.Context, options swarmtypes.TaskListOptions) ([]swarmtypes.Task, error) {
return c.tasks, c.err
func (c *fakeTasksClient) TaskList(ctx context.Context, options client.TaskListOptions) (client.TaskListResult, error) {
return client.TaskListResult{Items: c.tasks}, c.err
}
func (c *fakeTasksClient) ContainerInspect(ctx context.Context, container string) (dockercontainertypes.InspectResponse, error) {
return c.container, c.err
func (c *fakeTasksClient) ContainerInspect(ctx context.Context, container string, options client.ContainerInspectOptions) (client.ContainerInspectResult, error) {
return client.ContainerInspectResult{Container: c.container}, c.err
}
func TestListTasks(t *testing.T) {
@@ -74,7 +73,7 @@ func TestListTasks(t *testing.T) {
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
Network: networktypes.Network{Name: "foo"},
},
},
},
@@ -105,7 +104,7 @@ func TestListTasks(t *testing.T) {
}
type fakeServicesClient struct {
dockerclient.APIClient
client.APIClient
dockerVersion string
networks []networktypes.Summary
@@ -115,29 +114,29 @@ type fakeServicesClient struct {
err error
}
func (c *fakeServicesClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarmtypes.Node, []byte, error) {
func (c *fakeServicesClient) NodeInspect(ctx context.Context, nodeID string, options client.NodeInspectOptions) (client.NodeInspectResult, error) {
for _, node := range c.nodes {
if node.ID == nodeID {
return node, nil, nil
return client.NodeInspectResult{Node: node}, nil
}
}
return swarmtypes.Node{}, nil, c.err
return client.NodeInspectResult{}, c.err
}
func (c *fakeServicesClient) ServiceList(ctx context.Context, options swarmtypes.ServiceListOptions) ([]swarmtypes.Service, error) {
return c.services, c.err
func (c *fakeServicesClient) ServiceList(ctx context.Context, options client.ServiceListOptions) (client.ServiceListResult, error) {
return client.ServiceListResult{Items: c.services}, c.err
}
func (c *fakeServicesClient) ServerVersion(ctx context.Context) (dockertypes.Version, error) {
return dockertypes.Version{APIVersion: c.dockerVersion}, c.err
func (c *fakeServicesClient) ServerVersion(ctx context.Context, options client.ServerVersionOptions) (client.ServerVersionResult, error) {
return client.ServerVersionResult{APIVersion: c.dockerVersion}, c.err
}
func (c *fakeServicesClient) NetworkList(ctx context.Context, options networktypes.ListOptions) ([]networktypes.Summary, error) {
return c.networks, c.err
func (c *fakeServicesClient) NetworkList(ctx context.Context, options client.NetworkListOptions) (client.NetworkListResult, error) {
return client.NetworkListResult{Items: c.networks}, c.err
}
func (c *fakeServicesClient) TaskList(ctx context.Context, options swarmtypes.TaskListOptions) ([]swarmtypes.Task, error) {
return c.tasks, c.err
func (c *fakeServicesClient) TaskList(ctx context.Context, options client.TaskListOptions) (client.TaskListResult, error) {
return client.TaskListResult{Items: c.tasks}, c.err
}
func TestListServices(t *testing.T) {
@@ -200,21 +199,23 @@ func TestListServices(t *testing.T) {
dockerVersion: "1.30",
networks: []networktypes.Summary{
{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
Network: networktypes.Network{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
},
},
},
@@ -255,21 +256,23 @@ func TestListServices(t *testing.T) {
dockerVersion: "1.30",
networks: []networktypes.Summary{
{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
Network: networktypes.Network{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
},
},
},
@@ -334,7 +337,7 @@ func TestSwarmTaskParsing(t *testing.T) {
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
Network: networktypes.Network{Name: "foo"},
},
},
},
@@ -359,7 +362,7 @@ func TestSwarmTaskParsing(t *testing.T) {
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
Network: networktypes.Network{Name: "foo"},
},
},
},
@@ -397,7 +400,7 @@ func TestSwarmTaskParsing(t *testing.T) {
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "vlan",
Network: networktypes.Network{Name: "vlan"},
},
},
},
@@ -425,7 +428,7 @@ func TestSwarmTaskParsing(t *testing.T) {
},
networks: map[string]*networktypes.Summary{
"1": {
Name: "foo",
Network: networktypes.Network{Name: "foo"},
},
},
},
+21 -13
View File
@@ -1,15 +1,18 @@
package ecs
import (
"cmp"
"context"
"errors"
"fmt"
"math"
"net"
"slices"
"strconv"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
ecstypes "github.com/aws/aws-sdk-go-v2/service/ecs/types"
"github.com/docker/go-connections/nat"
networktypes "github.com/moby/moby/api/types/network"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/config/label"
"github.com/traefik/traefik/v2/pkg/log"
@@ -302,26 +305,31 @@ func getPort(instance ecsInstance, serverPort string) string {
return serverPort
}
var ports []nat.Port
var ports []networktypes.Port
for _, port := range instance.machine.ports {
natPort, err := nat.NewPort(string(port.protocol), strconv.FormatInt(int64(port.hostPort), 10))
if err != nil {
if port.hostPort < 0 || port.hostPort > math.MaxUint16 {
// port out of range
continue
}
if port.protocol == "" {
port.protocol = ecstypes.TransportProtocolTcp
}
natPort, ok := networktypes.PortFrom(uint16(port.hostPort), networktypes.IPProtocol(port.protocol))
if !ok {
continue
}
ports = append(ports, natPort)
}
less := func(i, j nat.Port) bool {
return i.Int() < j.Int()
}
nat.Sort(ports, less)
if len(ports) > 0 {
return ports[0].Port()
if len(ports) == 0 {
return ""
}
return ""
slices.SortFunc(ports, func(a, b networktypes.Port) int {
return cmp.Compare(a.Num(), b.Num())
})
return ports[0].Port()
}
func getServiceName(instance ecsInstance) string {