Skip to content

Commit 1cabcfb

Browse files
authored
Merge pull request #579 from nginx-proxy/350-redo
fix: empty adresses with docker internal networks
2 parents 3e80765 + bcbfa49 commit 1cabcfb

File tree

4 files changed

+170
-25
lines changed

4 files changed

+170
-25
lines changed

internal/context/address.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package context
2+
3+
import (
4+
docker "github.com/fsouza/go-dockerclient"
5+
)
6+
7+
type Address struct {
8+
IP string
9+
IP6LinkLocal string
10+
IP6Global string
11+
Port string
12+
HostPort string
13+
Proto string
14+
HostIP string
15+
}
16+
17+
func renderAddress(container *docker.Container, port docker.Port) Address {
18+
return Address{
19+
IP: container.NetworkSettings.IPAddress,
20+
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
21+
IP6Global: container.NetworkSettings.GlobalIPv6Address,
22+
Port: port.Port(),
23+
Proto: port.Proto(),
24+
}
25+
}
26+
27+
func GetContainerAddresses(container *docker.Container) []Address {
28+
addresses := []Address{}
29+
30+
for port, bindings := range container.NetworkSettings.Ports {
31+
address := renderAddress(container, port)
32+
33+
if len(bindings) > 0 {
34+
address.HostPort = bindings[0].HostPort
35+
address.HostIP = bindings[0].HostIP
36+
}
37+
38+
addresses = append(addresses, address)
39+
}
40+
41+
if len(addresses) == 0 {
42+
// internal docker network has empty 'container.NetworkSettings.Ports'
43+
for port := range container.Config.ExposedPorts {
44+
address := renderAddress(container, port)
45+
addresses = append(addresses, address)
46+
}
47+
}
48+
49+
return addresses
50+
}

internal/context/address_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package context
2+
3+
import (
4+
"testing"
5+
6+
docker "github.com/fsouza/go-dockerclient"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
type FakePortBinding struct{}
11+
12+
var httpPort = docker.Port("80/tcp")
13+
var httpPortBinding = docker.PortBinding{
14+
HostIP: "100.100.100.100",
15+
HostPort: "8080",
16+
}
17+
18+
var httpsPort = docker.Port("443/tcp")
19+
20+
var httpTestPort = docker.Port("8080/tcp")
21+
var httpsTestPort = docker.Port("8443/tcp")
22+
23+
func TestGenerateContainerAddresses(t *testing.T) {
24+
testContainer := &docker.Container{
25+
Config: &docker.Config{
26+
ExposedPorts: map[docker.Port]struct{}{},
27+
},
28+
NetworkSettings: &docker.NetworkSettings{
29+
IPAddress: "10.0.0.10",
30+
LinkLocalIPv6Address: "24",
31+
GlobalIPv6Address: "10.0.0.1",
32+
Ports: map[docker.Port][]docker.PortBinding{},
33+
},
34+
}
35+
testContainer.NetworkSettings.Ports[httpPort] = []docker.PortBinding{httpPortBinding}
36+
testContainer.NetworkSettings.Ports[httpsPort] = []docker.PortBinding{}
37+
38+
addresses := GetContainerAddresses(testContainer)
39+
assert.Len(t, addresses, len(testContainer.NetworkSettings.Ports))
40+
assert.Contains(t, addresses, Address{
41+
IP: "10.0.0.10",
42+
IP6LinkLocal: "24",
43+
IP6Global: "10.0.0.1",
44+
Port: "80",
45+
Proto: "tcp",
46+
HostIP: "100.100.100.100",
47+
HostPort: "8080",
48+
})
49+
assert.Contains(t, addresses, Address{
50+
IP: "10.0.0.10",
51+
IP6LinkLocal: "24",
52+
IP6Global: "10.0.0.1",
53+
Port: "443",
54+
Proto: "tcp",
55+
HostIP: "",
56+
HostPort: "",
57+
})
58+
}
59+
60+
func TestGenerateContainerAddressesWithExposedPorts(t *testing.T) {
61+
testContainer := &docker.Container{
62+
Config: &docker.Config{
63+
ExposedPorts: map[docker.Port]struct{}{},
64+
},
65+
NetworkSettings: &docker.NetworkSettings{
66+
IPAddress: "10.0.0.10",
67+
LinkLocalIPv6Address: "24",
68+
GlobalIPv6Address: "10.0.0.1",
69+
Ports: map[docker.Port][]docker.PortBinding{},
70+
},
71+
}
72+
testContainer.NetworkSettings.Ports[httpPort] = []docker.PortBinding{}
73+
testContainer.NetworkSettings.Ports[httpsPort] = []docker.PortBinding{}
74+
testContainer.Config.ExposedPorts[httpPort] = struct{}{}
75+
testContainer.Config.ExposedPorts[httpsPort] = struct{}{}
76+
testContainer.Config.ExposedPorts[httpTestPort] = struct{}{}
77+
78+
assert.Len(t, GetContainerAddresses(testContainer), 2)
79+
}
80+
81+
func TestGenerateContainerAddressesWithNoPorts(t *testing.T) {
82+
testContainer := &docker.Container{
83+
Config: &docker.Config{
84+
ExposedPorts: map[docker.Port]struct{}{},
85+
},
86+
NetworkSettings: &docker.NetworkSettings{
87+
IPAddress: "10.0.0.10",
88+
LinkLocalIPv6Address: "24",
89+
GlobalIPv6Address: "10.0.0.1",
90+
Ports: map[docker.Port][]docker.PortBinding{},
91+
},
92+
}
93+
testContainer.Config.ExposedPorts[httpTestPort] = FakePortBinding{}
94+
testContainer.Config.ExposedPorts[httpsTestPort] = FakePortBinding{}
95+
96+
addresses := GetContainerAddresses(testContainer)
97+
assert.Len(t, addresses, len(testContainer.Config.ExposedPorts))
98+
assert.Contains(t, addresses, Address{
99+
IP: "10.0.0.10",
100+
IP6LinkLocal: "24",
101+
IP6Global: "10.0.0.1",
102+
Port: "8080",
103+
Proto: "tcp",
104+
HostIP: "",
105+
HostPort: "",
106+
})
107+
assert.Contains(t, addresses, Address{
108+
IP: "10.0.0.10",
109+
IP6LinkLocal: "24",
110+
IP6Global: "10.0.0.1",
111+
Port: "8443",
112+
Proto: "tcp",
113+
HostIP: "",
114+
HostPort: "",
115+
})
116+
}

internal/context/context.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,6 @@ func SetDockerEnv(d *docker.Env) {
5252
dockerEnv = d
5353
}
5454

55-
type Address struct {
56-
IP string
57-
IP6LinkLocal string
58-
IP6Global string
59-
Port string
60-
HostPort string
61-
Proto string
62-
HostIP string
63-
}
64-
6555
type Network struct {
6656
IP string
6757
Name string

internal/generator/generator.go

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -420,22 +420,10 @@ func (g *generator) getContainers() ([]*context.RuntimeContainer, error) {
420420
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
421421
IP6Global: container.NetworkSettings.GlobalIPv6Address,
422422
}
423-
for k, v := range container.NetworkSettings.Ports {
424-
address := context.Address{
425-
IP: container.NetworkSettings.IPAddress,
426-
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
427-
IP6Global: container.NetworkSettings.GlobalIPv6Address,
428-
Port: k.Port(),
429-
Proto: k.Proto(),
430-
}
431-
if len(v) > 0 {
432-
address.HostPort = v[0].HostPort
433-
address.HostIP = v[0].HostIP
434-
}
435-
runtimeContainer.Addresses = append(runtimeContainer.Addresses,
436-
address)
437423

438-
}
424+
adresses := context.GetContainerAddresses(container)
425+
runtimeContainer.Addresses = append(runtimeContainer.Addresses, adresses...)
426+
439427
for k, v := range container.NetworkSettings.Networks {
440428
network := context.Network{
441429
IP: v.IPAddress,
@@ -453,6 +441,7 @@ func (g *generator) getContainers() ([]*context.RuntimeContainer, error) {
453441
runtimeContainer.Networks = append(runtimeContainer.Networks,
454442
network)
455443
}
444+
456445
for k, v := range container.Volumes {
457446
runtimeContainer.Volumes[k] = context.Volume{
458447
Path: k,

0 commit comments

Comments
 (0)