libnetwork: loosen container IPAM validation
Permit container network attachments to set any static IP address within
the network's IPAM master pool, including when a subpool is configured.
Users have come to depend on being able to statically assign container
IP addresses which are guaranteed not to collide with automatically-
assigned container addresses.
Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 058b30023f
)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
615dfdf672
commit
13964248f1
3 changed files with 45 additions and 5 deletions
|
@ -289,3 +289,40 @@ func TestMacAddressIsAppliedToMainNetworkWithShortID(t *testing.T) {
|
|||
c := container.Inspect(ctx, t, apiClient, cid)
|
||||
assert.Equal(t, c.NetworkSettings.Networks["testnet"].MacAddress, "02:42:08:26:a9:55")
|
||||
}
|
||||
|
||||
func TestStaticIPOutsideSubpool(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
|
||||
ctx := testutil.StartSpan(baseContext, t)
|
||||
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t)
|
||||
defer d.Stop(t)
|
||||
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.43"))
|
||||
assert.NilError(t, err)
|
||||
|
||||
const netname = "subnet-range"
|
||||
n := net.CreateNoError(ctx, t, apiClient, netname, net.WithIPAMRange("10.42.0.0/16", "10.42.128.0/24", "10.42.0.1"))
|
||||
defer net.RemoveNoError(ctx, t, apiClient, n)
|
||||
|
||||
cID := container.Run(ctx, t, apiClient,
|
||||
container.WithImage("busybox:latest"),
|
||||
container.WithCmd("sh", "-c", `ip -4 -oneline addr show eth0`),
|
||||
container.WithNetworkMode(netname),
|
||||
container.WithIPv4(netname, "10.42.1.3"),
|
||||
)
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, apiClient, cID), poll.WithDelay(100*time.Millisecond))
|
||||
|
||||
out, err := apiClient.ContainerLogs(ctx, cID, containertypes.LogsOptions{ShowStdout: true})
|
||||
assert.NilError(t, err)
|
||||
defer out.Close()
|
||||
|
||||
var b bytes.Buffer
|
||||
_, err = io.Copy(&b, out)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Check(t, is.Contains(b.String(), "inet 10.42.1.3/16"))
|
||||
}
|
||||
|
|
|
@ -73,6 +73,11 @@ func WithOption(key, value string) func(*types.NetworkCreate) {
|
|||
|
||||
// WithIPAM adds an IPAM with the specified Subnet and Gateway to the network
|
||||
func WithIPAM(subnet, gateway string) func(*types.NetworkCreate) {
|
||||
return WithIPAMRange(subnet, "", gateway)
|
||||
}
|
||||
|
||||
// WithIPAM adds an IPAM with the specified Subnet, IPRange and Gateway to the network
|
||||
func WithIPAMRange(subnet, iprange, gateway string) func(*types.NetworkCreate) {
|
||||
return func(n *types.NetworkCreate) {
|
||||
if n.IPAM == nil {
|
||||
n.IPAM = &network.IPAM{}
|
||||
|
@ -80,6 +85,7 @@ func WithIPAM(subnet, gateway string) func(*types.NetworkCreate) {
|
|||
|
||||
n.IPAM.Config = append(n.IPAM.Config, network.IPAMConfig{
|
||||
Subnet: subnet,
|
||||
IPRange: iprange,
|
||||
Gateway: gateway,
|
||||
AuxAddress: map[string]string{},
|
||||
})
|
||||
|
|
|
@ -83,7 +83,7 @@ type IpamConf struct {
|
|||
// PreferredPool is the master address pool for containers and network interfaces.
|
||||
PreferredPool string
|
||||
// SubPool is a subset of the master pool. If specified,
|
||||
// this becomes the container pool.
|
||||
// this becomes the container pool for automatic address allocations.
|
||||
SubPool string
|
||||
// Gateway is the preferred Network Gateway address (optional).
|
||||
Gateway string
|
||||
|
@ -100,7 +100,7 @@ func (c *IpamConf) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Contains checks whether the ipamSubnet contains [addr].
|
||||
// Contains checks whether the ipam master address pool contains [addr].
|
||||
func (c *IpamConf) Contains(addr net.IP) bool {
|
||||
if c == nil {
|
||||
return false
|
||||
|
@ -110,9 +110,6 @@ func (c *IpamConf) Contains(addr net.IP) bool {
|
|||
}
|
||||
|
||||
_, allowedRange, _ := net.ParseCIDR(c.PreferredPool)
|
||||
if c.SubPool != "" {
|
||||
_, allowedRange, _ = net.ParseCIDR(c.SubPool)
|
||||
}
|
||||
|
||||
return allowedRange.Contains(addr)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue