mirror of
https://github.com/vxcontrol/coredns-docker-discovery.git
synced 2026-07-01 09:53:15 -04:00
316 lines
8.9 KiB
Go
316 lines
8.9 KiB
Go
package dockerdiscovery
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"testing"
|
|
|
|
"github.com/coredns/caddy"
|
|
dockerapi "github.com/fsouza/go-dockerclient"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type setupDockerDiscoveryTestCase struct {
|
|
configBlock string
|
|
expectedDockerEndpoint string
|
|
expectedDockerDomain string
|
|
}
|
|
|
|
func TestConfigDockerDiscovery(t *testing.T) {
|
|
testCases := []setupDockerDiscoveryTestCase{
|
|
{
|
|
"docker",
|
|
defaultDockerEndpoint,
|
|
defaultDockerDomain,
|
|
},
|
|
{
|
|
"docker unix:///var/run/docker.sock.backup",
|
|
"unix:///var/run/docker.sock.backup",
|
|
defaultDockerDomain,
|
|
},
|
|
{
|
|
`docker {
|
|
hostname_domain example.org.
|
|
}`,
|
|
defaultDockerEndpoint,
|
|
"example.org.",
|
|
},
|
|
{
|
|
`docker unix:///home/user/docker.sock {
|
|
hostname_domain home.example.org.
|
|
}`,
|
|
"unix:///home/user/docker.sock",
|
|
"home.example.org.",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
c := caddy.NewTestController("dns", tc.configBlock)
|
|
dd, err := createPlugin(c)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, dd.dockerEndpoint, tc.expectedDockerEndpoint)
|
|
}
|
|
}
|
|
|
|
func TestSetupDockerDiscovery(t *testing.T) {
|
|
networkName := "my_project_network_name"
|
|
c := caddy.NewTestController("dns", fmt.Sprintf(`docker unix:///home/user/docker.sock {
|
|
compose_domain compose.loc
|
|
hostname_domain home.example.org
|
|
domain docker.loc
|
|
network_aliases %s
|
|
filter_network %s
|
|
}`, networkName, networkName))
|
|
dd, err := createPlugin(c)
|
|
assert.Nil(t, err)
|
|
|
|
var address = net.ParseIP("192.11.0.1")
|
|
var containers = []*dockerapi.Container{
|
|
genContainerDefn("", networkName, address.String()),
|
|
genContainerDefn("", networkName, address.String()),
|
|
genContainerDefn(address.String(), networkName, address.String()),
|
|
}
|
|
|
|
for i := range containers {
|
|
container := containers[i]
|
|
e := dd.updateContainerInfo(container)
|
|
assert.Nil(t, e)
|
|
|
|
_ = ipOk(t, dd, "myproject.loc.", address)
|
|
ipNotOk(t, dd, "wrong.loc.")
|
|
_ = ipOk(t, dd, "nginx.home.example.org.", address)
|
|
ipNotOk(t, dd, "wrong.home.example.org.")
|
|
_ = ipOk(t, dd, "label-host.loc.", address)
|
|
_ = ipOk(t, dd, "cservice.cproject.compose.loc.", address)
|
|
|
|
containerInfo := ipOk(t, dd, fmt.Sprintf("%s.docker.loc.", container.Name), address)
|
|
assert.Equal(t, container.Name, containerInfo.container.Name)
|
|
}
|
|
}
|
|
|
|
func TestMultipleNetworksDockerDiscovery(t *testing.T) {
|
|
networkName := "my_project_network_name"
|
|
address := net.ParseIP("192.11.0.1")
|
|
expectedAddress := net.ParseIP("9.14.1.30")
|
|
expectedNet := "inquisition"
|
|
|
|
c := caddy.NewTestController("dns", fmt.Sprintf(`docker unix:///home/user/docker.sock {
|
|
compose_domain compose.loc
|
|
hostname_domain home.example.org
|
|
domain docker.loc
|
|
network_aliases %s
|
|
filter_network %s
|
|
}`, networkName, networkName))
|
|
dd, err := createPlugin(c)
|
|
assert.Nil(t, err)
|
|
|
|
// generate a configuration; tweak to add a second network
|
|
container := genContainerDefn("", networkName, address.String())
|
|
container.NetworkSettings.Networks[expectedNet] = dockerapi.ContainerNetwork{
|
|
Aliases: []string{"myproject.loc"},
|
|
IPAddress: expectedAddress.String(),
|
|
}
|
|
|
|
err = dd.updateContainerInfo(container)
|
|
assert.Nil(t, err)
|
|
|
|
// without label, we expect the "NetworkMode" address to prevail
|
|
_ = ipOk(t, dd, "label-host.loc.", address)
|
|
|
|
// now, update for the label and try this again
|
|
|
|
container.Config.Labels["coredns.dockerdiscovery.network"] = expectedNet
|
|
err = dd.updateContainerInfo(container)
|
|
assert.Nil(t, err)
|
|
|
|
_ = ipOk(t, dd, "label-host.loc.", expectedAddress)
|
|
}
|
|
|
|
// simple check
|
|
func ipOk(t *testing.T, dd *DockerDiscovery, domain string, address net.IP) *ContainerInfo {
|
|
|
|
containerInfo, e := dd.containerInfoByDomain(domain)
|
|
assert.Nil(t, e)
|
|
assert.NotNil(t, containerInfo)
|
|
|
|
// check as strings here, for us poor mortals
|
|
assert.Equal(t, address.String(), containerInfo.address.String())
|
|
|
|
return containerInfo
|
|
}
|
|
|
|
// simple check
|
|
func ipNotOk(t *testing.T, dd *DockerDiscovery, domain string) {
|
|
|
|
containerInfo, e := dd.containerInfoByDomain(domain)
|
|
assert.Nil(t, e)
|
|
assert.Nil(t, containerInfo)
|
|
}
|
|
|
|
// string, not net.IP, as 1) we're test, 2) the underling struct is a string,
|
|
// and 3) we may want something odd here
|
|
func genContainerDefn(nsAddress string, netMode string, netAddress string) *dockerapi.Container {
|
|
container := &dockerapi.Container{
|
|
ID: "fa155d6fd141e29256c286070d2d44b3f45f1e46822578f1e7d66c1e7981e6c7",
|
|
Name: "evil_ptolemy",
|
|
Config: &dockerapi.Config{
|
|
Hostname: "nginx",
|
|
Labels: map[string]string{
|
|
"coredns.dockerdiscovery.host": "label-host.loc",
|
|
"com.docker.compose.project": "cproject",
|
|
"com.docker.compose.service": "cservice",
|
|
},
|
|
},
|
|
HostConfig: &dockerapi.HostConfig{
|
|
NetworkMode: netMode,
|
|
},
|
|
NetworkSettings: &dockerapi.NetworkSettings{
|
|
IPAddress: nsAddress,
|
|
Networks: map[string]dockerapi.ContainerNetwork{
|
|
netMode: {
|
|
Aliases: []string{"myproject.loc"},
|
|
IPAddress: netAddress,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return container
|
|
}
|
|
|
|
func TestNetworkAliasesFilteringDockerDiscovery(t *testing.T) {
|
|
targetNetwork := "target_network"
|
|
otherNetwork := "other_network"
|
|
targetNetworkIP := net.ParseIP("10.10.10.10")
|
|
otherNetworkIP := net.ParseIP("20.20.20.20")
|
|
|
|
c := caddy.NewTestController("dns", fmt.Sprintf(`docker unix:///home/user/docker.sock {
|
|
domain docker.loc
|
|
network_aliases %s
|
|
filter_network %s
|
|
}`, targetNetwork, targetNetwork))
|
|
dd, err := createPlugin(c)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, targetNetwork, dd.filterNetwork)
|
|
|
|
// Test 1: Container is ONLY in target network - should be added
|
|
container1 := &dockerapi.Container{
|
|
ID: "111111111111111111111111111111111111111111111111111111111111111",
|
|
Name: "test_container_1",
|
|
Config: &dockerapi.Config{
|
|
Hostname: "test1",
|
|
Labels: map[string]string{},
|
|
},
|
|
HostConfig: &dockerapi.HostConfig{
|
|
NetworkMode: targetNetwork,
|
|
},
|
|
NetworkSettings: &dockerapi.NetworkSettings{
|
|
Networks: map[string]dockerapi.ContainerNetwork{
|
|
targetNetwork: {
|
|
Aliases: []string{"service1.loc"},
|
|
IPAddress: targetNetworkIP.String(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err = dd.updateContainerInfo(container1)
|
|
assert.Nil(t, err)
|
|
containerInfo := ipOk(t, dd, "service1.loc.", targetNetworkIP)
|
|
assert.NotNil(t, containerInfo)
|
|
t.Logf("Test 1 passed: Container in target network was added with correct IP")
|
|
|
|
// Test 2: Container in multiple networks including target - should use target network IP
|
|
container2 := &dockerapi.Container{
|
|
ID: "222222222222222222222222222222222222222222222222222222222222222",
|
|
Name: "test_container_2",
|
|
Config: &dockerapi.Config{
|
|
Hostname: "test2",
|
|
Labels: map[string]string{},
|
|
},
|
|
HostConfig: &dockerapi.HostConfig{
|
|
NetworkMode: otherNetwork, // NetworkMode is different from target
|
|
},
|
|
NetworkSettings: &dockerapi.NetworkSettings{
|
|
Networks: map[string]dockerapi.ContainerNetwork{
|
|
otherNetwork: {
|
|
Aliases: []string{"service2.loc"},
|
|
IPAddress: otherNetworkIP.String(),
|
|
},
|
|
targetNetwork: {
|
|
Aliases: []string{"service2.loc"},
|
|
IPAddress: targetNetworkIP.String(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err = dd.updateContainerInfo(container2)
|
|
assert.Nil(t, err)
|
|
containerInfo = ipOk(t, dd, "service2.loc.", targetNetworkIP)
|
|
assert.NotNil(t, containerInfo)
|
|
t.Logf("Test 2 passed: Container in multiple networks uses target network IP")
|
|
|
|
// Test 3: Container NOT in target network - should be skipped
|
|
container3 := &dockerapi.Container{
|
|
ID: "333333333333333333333333333333333333333333333333333333333333333",
|
|
Name: "test_container_3",
|
|
Config: &dockerapi.Config{
|
|
Hostname: "test3",
|
|
Labels: map[string]string{},
|
|
},
|
|
HostConfig: &dockerapi.HostConfig{
|
|
NetworkMode: otherNetwork,
|
|
},
|
|
NetworkSettings: &dockerapi.NetworkSettings{
|
|
Networks: map[string]dockerapi.ContainerNetwork{
|
|
otherNetwork: {
|
|
Aliases: []string{"service3.loc"},
|
|
IPAddress: otherNetworkIP.String(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err = dd.updateContainerInfo(container3)
|
|
assert.Nil(t, err)
|
|
ipNotOk(t, dd, "service3.loc.")
|
|
t.Logf("Test 3 passed: Container not in target network was skipped")
|
|
|
|
// Test 4: Container with 3+ networks including target - should still use target network IP
|
|
thirdNetworkIP := net.ParseIP("30.30.30.30")
|
|
container4 := &dockerapi.Container{
|
|
ID: "444444444444444444444444444444444444444444444444444444444444444",
|
|
Name: "test_container_4",
|
|
Config: &dockerapi.Config{
|
|
Hostname: "test4",
|
|
Labels: map[string]string{},
|
|
},
|
|
HostConfig: &dockerapi.HostConfig{
|
|
NetworkMode: "third_network",
|
|
},
|
|
NetworkSettings: &dockerapi.NetworkSettings{
|
|
Networks: map[string]dockerapi.ContainerNetwork{
|
|
"third_network": {
|
|
Aliases: []string{"service4.loc"},
|
|
IPAddress: thirdNetworkIP.String(),
|
|
},
|
|
otherNetwork: {
|
|
Aliases: []string{"service4.loc"},
|
|
IPAddress: otherNetworkIP.String(),
|
|
},
|
|
targetNetwork: {
|
|
Aliases: []string{"service4.loc"},
|
|
IPAddress: targetNetworkIP.String(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
err = dd.updateContainerInfo(container4)
|
|
assert.Nil(t, err)
|
|
containerInfo = ipOk(t, dd, "service4.loc.", targetNetworkIP)
|
|
assert.NotNil(t, containerInfo)
|
|
t.Logf("Test 4 passed: Container with 3+ networks uses target network IP")
|
|
}
|