Skip to content

Commit ce9a9e5

Browse files
committed
fix: kop.bind.ip ignored when using label prefix (resolves #82)
1 parent ae722d1 commit ce9a9e5

File tree

6 files changed

+75
-1
lines changed

6 files changed

+75
-1
lines changed

docker_helpers_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@ func assertServiceIPs(t *testing.T, store TraefikStore, svcs []svc) {
397397
assert.Equal(t,
398398
svc.ip,
399399
val,
400-
"service has wrong IP at key: %s",
400+
"service %s has wrong IP at key: %s",
401+
svc,
401402
key,
402403
)
403404
}

docker_proxy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ func (s *DockerProxyServer) start() (*fiber.App, string) {
160160
app.Use(logger.New())
161161
}
162162

163+
app.All("/_ping", func(ctx *fiber.Ctx) error { return ctx.SendStatus(fiber.StatusNoContent) })
163164
app.Get("/v*/version", s.handleVersion)
164165
app.Get("/v*/containers/json", s.handleContainersList)
165166
app.Get("/v*/containers/:id/json", s.handleContainerInspect)

docker_proxy_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,34 @@ func Test_dockerProxyServerPrefix(t *testing.T) {
6363
assert.Empty(t, g(store, fmt.Sprintf("traefik/http/routers/%s/service", "hello-detect2")))
6464
assert.NotEmpty(t, g(store, fmt.Sprintf("traefik/http/routers/%s/service", "prefixed")))
6565
}
66+
67+
// test that services with kop.bind.ip or foo.kop.bind.ip labels are handled correctly
68+
func Test_dockerProxyServerPrefixWithKopBindIP(t *testing.T) {
69+
mockDockerEndpoint := dockerEndpoint
70+
mockDockerClient := dc
71+
72+
// now create our proxy pointing to the mock
73+
proxyServer := createProxy(mockDockerClient, "foo")
74+
_, proxyDockerEndpoint := proxyServer.start()
75+
76+
var err error
77+
dockerEndpoint = proxyDockerEndpoint
78+
dc, err = createDockerClient(proxyDockerEndpoint)
79+
assert.NoError(t, err, "should create docker client")
80+
defer func() {
81+
dockerEndpoint = mockDockerEndpoint
82+
dc = mockDockerClient
83+
}()
84+
85+
// both services get mapped to the same port (error case)
86+
store := processFile(t, "hellodetect.yml")
87+
processFileWithConfig(t, store, nil, "prefix-bindip.yml")
88+
89+
assertServiceIPs(t, store, []svc{
90+
{"prefixed", "http", "http://foo.bar.baz:5588"},
91+
{"unprefixed", "http", "http://example.local:5599"},
92+
})
93+
94+
assert.Empty(t, g(store, fmt.Sprintf("traefik/http/routers/%s/service", "hello-detect2")))
95+
assert.NotEmpty(t, g(store, fmt.Sprintf("traefik/http/routers/%s/service", "prefixed")))
96+
}

docker_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var dc client.APIClient
1717
var dockerAPI = &DockerAPIStub{}
1818

1919
func setup() {
20+
os.Unsetenv("DOCKER_HOST") // make sure this doesn't interfere with our client setup
2021
app, dockerEndpoint = createHTTPServer()
2122
var err error
2223
dc, err = createDockerClient(dockerEndpoint)

fixtures/prefix-bindip.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
services:
2+
# test labels with a prefix, i.e., DOCKER_PREFIX=foo.
3+
dockerprefix:
4+
image: nginx
5+
restart: "no"
6+
ports:
7+
- 5588:80
8+
labels:
9+
- "foo.traefik.enable=true"
10+
- "foo.traefik.http.routers.prefixed.rule=Host(`hello-prefix.local`)"
11+
- "foo.traefik.http.routers.prefixed.service=prefixed"
12+
- "foo.traefik.http.routers.prefixed.tls=true"
13+
- "foo.traefik.http.routers.prefixed.tls.certresolver=default"
14+
- "foo.traefik.http.services.prefixed.loadbalancer.server.scheme=http"
15+
- "foo.kop.bind.ip=foo.bar.baz"
16+
dockerprefix2:
17+
image: nginx
18+
restart: "no"
19+
ports:
20+
- 5599:80
21+
labels:
22+
- "foo.traefik.enable=true"
23+
- "foo.traefik.http.routers.unprefixed.rule=Host(`hello-prefix2.local`)"
24+
- "foo.traefik.http.routers.unprefixed.service=prefixed"
25+
- "foo.traefik.http.routers.unprefixed.tls=true"
26+
- "foo.traefik.http.routers.unprefixed.tls.certresolver=default"
27+
- "foo.traefik.http.services.unprefixed.loadbalancer.server.scheme=http"
28+
- "kop.bind.ip=example.local"

traefik_kop.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,21 @@ func Start(config Config) {
9393

9494
if config.DockerPrefix != "" {
9595
// use proxy to filter by label prefix
96+
//
97+
// Docker client is used in two places:
98+
// - Docker Provider which is used by traefik
99+
// - dockerCache used by traefik-kop to lookup container info
100+
//
101+
// The real docker client is only used by the proxy.
102+
// All other usage goes via docker client connecting to the proxy.
103+
96104
dockerProxy := createProxy(dockerClient, config.DockerPrefix)
97105
_, dockerProxyAddr := dockerProxy.start()
98106
config.DockerHost = dockerProxyAddr
107+
dockerClient, err = createDockerClient(dockerProxyAddr)
108+
if err != nil {
109+
log.Fatal().Msgf("failed to create docker client for proxy: %s", err)
110+
}
99111
}
100112

101113
dp := newDockerProvider(config)

0 commit comments

Comments
 (0)