diff --git a/libnetwork/cmd/dnet/dnet.go b/libnetwork/cmd/dnet/dnet.go index 0fc2596f37..2f731f967c 100644 --- a/libnetwork/cmd/dnet/dnet.go +++ b/libnetwork/cmd/dnet/dnet.go @@ -435,7 +435,7 @@ func ipamOption(bridgeName string) libnetwork.NetworkOption { if hip.IsGlobalUnicast() { ipamV4Conf.Gateway = nw.IP.String() } - return libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil) + return libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil, nil) } return nil } diff --git a/libnetwork/docs/ipam.md b/libnetwork/docs/ipam.md index d66e5fc0f1..b5f8874e71 100644 --- a/libnetwork/docs/ipam.md +++ b/libnetwork/docs/ipam.md @@ -56,7 +56,7 @@ The following sections explain the each of the above API's semantics, when they A libnetwork user can provide IPAM related configuration when creating a network, via the `NetworkOptionIpam` setter function. ```go -func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf) NetworkOption +func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption ``` The caller has to provide the IPAM driver name and may provide the address space and a list of `IpamConf` structures for IPv4 and a list for IPv6. The IPAM driver name is the only mandatory field. If not provided, network creation will fail. diff --git a/libnetwork/libnetwork_internal_test.go b/libnetwork/libnetwork_internal_test.go index c504c4c478..e4761b6b4d 100644 --- a/libnetwork/libnetwork_internal_test.go +++ b/libnetwork/libnetwork_internal_test.go @@ -67,20 +67,19 @@ func TestNetworkMarshalling(t *testing.T) { networkType: "bridge", enableIPv6: true, persist: true, + ipamOptions: map[string]string{ + netlabel.MacAddress: "a:b:c:d:e:f", + }, ipamV4Config: []*IpamConf{ &IpamConf{ PreferredPool: "10.2.0.0/16", SubPool: "10.2.0.0/24", - Options: map[string]string{ - netlabel.MacAddress: "a:b:c:d:e:f", - }, - Gateway: "", - AuxAddresses: nil, + Gateway: "", + AuxAddresses: nil, }, &IpamConf{ PreferredPool: "10.2.0.0/16", SubPool: "10.2.1.0/24", - Options: nil, Gateway: "10.2.1.254", }, }, @@ -265,7 +264,6 @@ func compareIpamConfList(listA, listB []*IpamConf) bool { b = listB[i] if a.PreferredPool != b.PreferredPool || a.SubPool != b.SubPool || - !compareStringMaps(a.Options, b.Options) || a.Gateway != b.Gateway || !compareStringMaps(a.AuxAddresses, b.AuxAddresses) { return false } @@ -374,7 +372,7 @@ func TestIpamReleaseOnNetDriverFailures(t *testing.T) { // Test whether ipam state release is invoked on network create failure from net driver // by checking whether subsequent network creation requesting same gateway IP succeeds - ipamOpt := NetworkOptionIpam(ipamapi.DefaultIPAM, "", []*IpamConf{&IpamConf{PreferredPool: "10.34.0.0/16", Gateway: "10.34.255.254"}}, nil) + ipamOpt := NetworkOptionIpam(ipamapi.DefaultIPAM, "", []*IpamConf{&IpamConf{PreferredPool: "10.34.0.0/16", Gateway: "10.34.255.254"}}, nil, nil) if _, err := c.NewNetwork(badDriverName, "badnet1", ipamOpt); err == nil { t.Fatalf("bad network driver should have failed network creation") } @@ -398,7 +396,7 @@ func TestIpamReleaseOnNetDriverFailures(t *testing.T) { } // Now create good bridge network with different gateway - ipamOpt2 := NetworkOptionIpam(ipamapi.DefaultIPAM, "", []*IpamConf{&IpamConf{PreferredPool: "10.34.0.0/16", Gateway: "10.34.255.253"}}, nil) + ipamOpt2 := NetworkOptionIpam(ipamapi.DefaultIPAM, "", []*IpamConf{&IpamConf{PreferredPool: "10.34.0.0/16", Gateway: "10.34.255.253"}}, nil, nil) gnw, err = c.NewNetwork("bridge", "goodnet2", ipamOpt2) if err != nil { t.Fatal(err) diff --git a/libnetwork/libnetwork_test.go b/libnetwork/libnetwork_test.go index f290f001d2..a4e810c77f 100644 --- a/libnetwork/libnetwork_test.go +++ b/libnetwork/libnetwork_test.go @@ -87,7 +87,7 @@ func createController() error { func createTestNetwork(networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) { return controller.NewNetwork(networkType, networkName, libnetwork.NetworkOptionGeneric(netOption), - libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs)) + libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs, nil)) } func getEmptyGenericOption() map[string]interface{} { @@ -333,7 +333,7 @@ func TestBridgeIpv6FromMac(t *testing.T) { network, err := controller.NewNetwork(bridgeNetType, "testipv6mac", libnetwork.NetworkOptionGeneric(netOption), - libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4ConfList, ipamV6ConfList), + libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4ConfList, ipamV6ConfList, nil), libnetwork.NetworkOptionDeferIPv6Alloc(true)) if err != nil { t.Fatal(err) @@ -1016,7 +1016,7 @@ func TestEndpointJoin(t *testing.T) { ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/64", Gateway: "fe90::22"}} n1, err := controller.NewNetwork(bridgeNetType, "testnetwork1", libnetwork.NetworkOptionGeneric(netOption), - libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", nil, ipamV6ConfList), + libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", nil, ipamV6ConfList, nil), libnetwork.NetworkOptionDeferIPv6Alloc(true)) if err != nil { t.Fatal(err) diff --git a/libnetwork/network.go b/libnetwork/network.go index cf9f50dd75..45626df896 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -58,7 +58,7 @@ type Network interface { // NetworkInfo returns some configuration and operational information about the network type NetworkInfo interface { - IpamConfig() (string, []*IpamConf, []*IpamConf) + IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) IpamInfo() ([]*IpamInfo, []*IpamInfo) DriverOptions() map[string]string Scope() string @@ -81,8 +81,6 @@ type IpamConf struct { // A subset of the master pool. If specified, // this becomes the container pool SubPool string - // Input options for IPAM Driver (optional) - Options map[string]string // Preferred Network Gateway address (optional) Gateway string // Auxiliary addresses for network driver. Must be within the master pool. @@ -152,6 +150,7 @@ type network struct { networkType string id string ipamType string + ipamOptions map[string]string addrSpace string ipamV4Config []*IpamConf ipamV6Config []*IpamConf @@ -255,12 +254,6 @@ func (c *IpamConf) CopyTo(dstC *IpamConf) error { dstC.PreferredPool = c.PreferredPool dstC.SubPool = c.SubPool dstC.Gateway = c.Gateway - if c.Options != nil { - dstC.Options = make(map[string]string, len(c.Options)) - for k, v := range c.Options { - dstC.Options[k] = v - } - } if c.AuxAddresses != nil { dstC.AuxAddresses = make(map[string]string, len(c.AuxAddresses)) for k, v := range c.AuxAddresses { @@ -502,11 +495,12 @@ func NetworkOptionInternalNetwork() NetworkOption { } // NetworkOptionIpam function returns an option setter for the ipam configuration for this network -func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf) NetworkOption { +func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption { return func(n *network) { if ipamDriver != "" { n.ipamType = ipamDriver } + n.ipamOptions = opts n.addrSpace = addrSpace n.ipamV4Config = ipV4 n.ipamV6Config = ipV6 @@ -957,7 +951,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { d := &IpamInfo{} (*infoList)[i] = d - d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, cfg.Options, ipVer == 6) + d.PoolID, d.Pool, d.Meta, err = ipam.RequestPool(n.addrSpace, cfg.PreferredPool, cfg.SubPool, n.ipamOptions, ipVer == 6) if err != nil { return err } @@ -1136,7 +1130,7 @@ func (n *network) Scope() string { return n.driverScope() } -func (n *network) IpamConfig() (string, []*IpamConf, []*IpamConf) { +func (n *network) IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) { n.Lock() defer n.Unlock() @@ -1155,7 +1149,7 @@ func (n *network) IpamConfig() (string, []*IpamConf, []*IpamConf) { v6L[i] = cc } - return n.ipamType, v4L, v6L + return n.ipamType, n.ipamOptions, v4L, v6L } func (n *network) IpamInfo() ([]*IpamInfo, []*IpamInfo) {