apply IPAM configuration to network and services

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2021-06-22 09:56:32 +02:00
parent 7f18b47a9a
commit 2fdc2e1dfb
4 changed files with 80 additions and 5 deletions

View File

@ -0,0 +1,12 @@
services:
foo:
image: alpine
entrypoint: ["sleep", "600"]
networks:
default:
ipv4_address: 10.1.0.100 # <-- Fixed IP address
networks:
default:
ipam:
config:
- subnet: 10.1.0.0/16

View File

@ -94,3 +94,26 @@ func TestNetworkAliassesAndLinks(t *testing.T) {
_ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
})
}
func TestIPAMConfig(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
const projectName = "ipam_e2e"
t.Run("ensure we do not reuse previous networks", func(t *testing.T) {
c.RunDockerOrExitError("network", "rm", projectName+"_default")
})
t.Run("up", func(t *testing.T) {
c.RunDockerCmd("compose", "-f", "./fixtures/ipam/compose.yaml", "--project-name", projectName, "up", "-d")
})
t.Run("ensure service get fixed IP assigned", func(t *testing.T) {
res := c.RunDockerCmd("inspect", projectName+"_foo_1", "-f", "{{ .NetworkSettings.Networks."+projectName+"_default.IPAddress }}")
res.Assert(t, icmd.Expected{Out: "10.1.0.100"})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerCmd("compose", "--project-name", projectName, "down")
})
}

View File

@ -370,18 +370,24 @@ func shortIDAliasExists(containerID string, aliases ...string) bool {
func (s *composeService) connectContainerToNetwork(ctx context.Context, id string, netwrk string, cfg *types.ServiceNetworkConfig, links []string, aliases ...string) error {
var (
ipv4ddress string
ipv4Address string
ipv6Address string
ipam *network.EndpointIPAMConfig
)
if cfg != nil {
ipv4ddress = cfg.Ipv4Address
ipv4Address = cfg.Ipv4Address
ipv6Address = cfg.Ipv6Address
ipam = &network.EndpointIPAMConfig{
IPv4Address: ipv4Address,
IPv6Address: ipv6Address,
}
}
err := s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{
Aliases: aliases,
IPAddress: ipv4ddress,
IPAddress: ipv4Address,
GlobalIPv6Address: ipv6Address,
Links: links,
IPAMConfig: ipam,
})
if err != nil {
return err

View File

@ -284,17 +284,34 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project,
}
var networkConfig *network.NetworkingConfig
for _, id := range service.NetworksByPriority() {
net := p.Networks[id]
config := service.Networks[id]
var ipam *network.EndpointIPAMConfig
var (
ipv4Address string
ipv6Address string
)
if config != nil {
ipv4Address = config.Ipv4Address
ipv6Address = config.Ipv6Address
ipam = &network.EndpointIPAMConfig{
IPv4Address: ipv4Address,
IPv6Address: ipv6Address,
}
}
networkConfig = &network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
net.Name: {
Aliases: getAliases(service, config),
Aliases: getAliases(service, config),
IPAddress: ipv4Address,
IPv6Gateway: ipv6Address,
IPAMConfig: ipam,
},
},
}
break
break //nolint:staticcheck
}
ipcmode, err := getMode(ctx, service.Name, service.Ipc)
@ -915,6 +932,22 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi
if n.External.External {
return fmt.Errorf("network %s declared as external, but could not be found", n.Name)
}
var ipam *network.IPAM
if n.Ipam.Config != nil {
var config []network.IPAMConfig
for _, pool := range n.Ipam.Config {
config = append(config, network.IPAMConfig{
Subnet: pool.Subnet,
IPRange: pool.IPRange,
Gateway: pool.Gateway,
AuxAddress: pool.AuxiliaryAddresses,
})
}
ipam = &network.IPAM{
Driver: n.Ipam.Driver,
Config: config,
}
}
createOpts := moby.NetworkCreate{
// TODO NameSpace Labels
Labels: n.Labels,
@ -922,6 +955,7 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi
Options: n.DriverOpts,
Internal: n.Internal,
Attachable: n.Attachable,
IPAM: ipam,
}
if n.Ipam.Driver != "" || len(n.Ipam.Config) > 0 {