Skip to content

Commit

Permalink
fix: use exact service name match searching container labels
Browse files Browse the repository at this point in the history
`findContainerByServiceName` incorrectly matched containers based on
service and router names when there were two services with similar
names, specifically when one service name was a prefix of the other.

Add a dot to the service and router needles and compare the labels with
HasPrefix() to ensure that only the exact matches get picked up.
  • Loading branch information
Damien Fleurisson committed Jul 7, 2024
1 parent 7f76a08 commit 7db2c37
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
6 changes: 3 additions & 3 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ func findContainerByServiceName(dc client.APIClient, svcType string, svcName str
return types.ContainerJSON{}, errors.Wrapf(err, "failed to inspect container %s", c.ID)
}
// check labels
svcNeedle := fmt.Sprintf("traefik.%s.services.%s", svcType, svcName)
routerNeedle := fmt.Sprintf("traefik.%s.routers.%s", svcType, routerName)
svcNeedle := fmt.Sprintf("traefik.%s.services.%s.", svcType, svcName)
routerNeedle := fmt.Sprintf("traefik.%s.routers.%s.", svcType, routerName)
for k := range container.Config.Labels {
if strings.Contains(k, svcNeedle) || (routerName != "" && strings.Contains(k, routerNeedle)) {
if strings.HasPrefix(k, svcNeedle) || (routerName != "" && strings.HasPrefix(k, routerNeedle)) {
logrus.Debugf("found container '%s' (%s) for service '%s'", container.Name, container.ID, svcName)
return container, nil
}
Expand Down
11 changes: 11 additions & 0 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,14 @@ func Test_helloWorldNoCert(t *testing.T) {

// assert.Fail(t, "TODO: check for no cert")
}

func Test_samePrefix(t *testing.T) {
store := doTest(t, "prefix.yml")

// Two services `hello` and `hello-test`.
// The former's name is a prefix of the latter. Ensure the matching does not mix them up.
assertServiceIPs(t, store, []svc{
{"hello", "http", "http://192.168.100.100:5555"},
{"hello-test", "http", "http://192.168.100.100:5566"},
})
}
29 changes: 29 additions & 0 deletions fixtures/prefix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

services:
hello:
image: helloworld
restart: unless-stopped
ports:
- 5555:5555
labels:
- "traefik.enable=true"
- "traefik.http.routers.hello.rule=Host(`hello.local`)"
- "traefik.http.routers.hello.service=hello"
- "traefik.http.routers.hello.tls=true"
- "traefik.http.routers.hello.tls.certresolver=default"
- "traefik.http.services.hello.loadbalancer.server.scheme=http"
- "traefik.http.services.hello.loadbalancer.server.port=5555"

hello-test:
image: helloworld
restart: unless-stopped
ports:
- 5566:5566
labels:
- "traefik.enable=true"
- "traefik.http.routers.hello-test.rule=Host(`hello-test.local`)"
- "traefik.http.routers.hello-test.service=hello-test"
- "traefik.http.routers.hello-test.tls=true"
- "traefik.http.routers.hello-test.tls.certresolver=default"
- "traefik.http.services.hello-test.loadbalancer.server.scheme=http"
- "traefik.http.services.hello-test.loadbalancer.server.port=5566"

0 comments on commit 7db2c37

Please sign in to comment.