mirror of
https://github.com/traefik/traefik.git
synced 2026-06-17 19:09:29 +03:00
Migrate to github.com/moby/moby modules
This commit is contained in:
@@ -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,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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+29
-27
@@ -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()
|
||||
|
||||
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",
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@@ -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
|
||||
@@ -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{},
|
||||
},
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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,24 +399,22 @@ 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 ""
|
||||
}
|
||||
|
||||
func getServiceName(container dockerData) string {
|
||||
serviceName := container.ServiceName
|
||||
|
||||
|
||||
+180
-181
@@ -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"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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.ContainerJSONBase.HostConfig != nil {
|
||||
dData.NetworkSettings.NetworkMode = container.ContainerJSONBase.HostConfig.NetworkMode
|
||||
if container.HostConfig != nil {
|
||||
dData.NetworkSettings.NetworkMode = container.HostConfig.NetworkMode
|
||||
}
|
||||
|
||||
if container.State != nil && container.State.Health != nil {
|
||||
dData.Health = container.State.Health.Status
|
||||
}
|
||||
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)
|
||||
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: ip.String(),
|
||||
Addr: virtualIP.Addr.Addr().String(),
|
||||
}
|
||||
dData.NetworkSettings.Networks[network.Name] = network
|
||||
} else {
|
||||
logger.Debugf("No virtual IPs found in network %s", virtualIP.NetworkID)
|
||||
}
|
||||
} else {
|
||||
logger.Debugf("Network not found, id: %s", virtualIP.NetworkID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,6 +199,7 @@ func TestListServices(t *testing.T) {
|
||||
dockerVersion: "1.30",
|
||||
networks: []networktypes.Summary{
|
||||
{
|
||||
Network: networktypes.Network{
|
||||
Name: "network_name",
|
||||
ID: "yk6l57rfwizjzxxzftn4amaot",
|
||||
Created: time.Now(),
|
||||
@@ -218,6 +218,7 @@ func TestListServices(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedServices: []string{
|
||||
"service1",
|
||||
},
|
||||
@@ -255,6 +256,7 @@ func TestListServices(t *testing.T) {
|
||||
dockerVersion: "1.30",
|
||||
networks: []networktypes.Summary{
|
||||
{
|
||||
Network: networktypes.Network{
|
||||
Name: "network_name",
|
||||
ID: "yk6l57rfwizjzxxzftn4amaot",
|
||||
Created: time.Now(),
|
||||
@@ -273,6 +275,7 @@ func TestListServices(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedServices: []string{
|
||||
"service1.0",
|
||||
"service1.0",
|
||||
@@ -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"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+22
-14
@@ -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,28 +305,33 @@ 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 ""
|
||||
}
|
||||
|
||||
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 {
|
||||
return provider.Normalize(instance.Name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user