mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Added driver specific config support
- Added api enhancement to pass driver specific config - Refactored simple bridge driver code for driver specific config - Added an undocumented option to add non-default bridges without manual pre-provisioning to help libnetwork testing - Reenabled libnetwork test to do api testing - Updated README.md Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
parent
b4481f4d50
commit
e797f80ad4
28 changed files with 333 additions and 254 deletions
|
@ -22,10 +22,18 @@ There are many networking solutions available to suit a broad range of use-cases
|
||||||
```go
|
```go
|
||||||
// Create a new controller instance
|
// Create a new controller instance
|
||||||
controller := libnetwork.New()
|
controller := libnetwork.New()
|
||||||
|
|
||||||
options := options.Generic{}
|
// This option is only needed for in-tree drivers. Plugins(in future) will get
|
||||||
|
// their options through plugin infrastructure.
|
||||||
|
option := options.Generic{}
|
||||||
|
driver, err := controller.NewNetworkDriver("simplebridge", option)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
netOptions := options.Generic{}
|
||||||
// Create a network for containers to join.
|
// Create a network for containers to join.
|
||||||
network, err := controller.NewNetwork("simplebridge", "network1", options)
|
network, err := controller.NewNetwork(driver, "network1", netOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ func main() {
|
||||||
|
|
||||||
options := options.Generic{"AddressIPv4": net}
|
options := options.Generic{"AddressIPv4": net}
|
||||||
controller := libnetwork.New()
|
controller := libnetwork.New()
|
||||||
netw, err := controller.NewNetwork("simplebridge", "dummy", options)
|
driver, _ := controller.NewNetworkDriver("simplebridge", options)
|
||||||
|
netw, err := controller.NewNetwork(driver, "dummy", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,11 @@ type UUID string
|
||||||
|
|
||||||
// Driver is an interface that every plugin driver needs to implement.
|
// Driver is an interface that every plugin driver needs to implement.
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
|
// Push driver specific config to the driver
|
||||||
|
Config(config interface{}) error
|
||||||
|
|
||||||
// CreateNetwork invokes the driver method to create a network passing
|
// CreateNetwork invokes the driver method to create a network passing
|
||||||
// the network id and driver specific config. The config mechanism will
|
// the network id and network specific config. The config mechanism will
|
||||||
// eventually be replaced with labels which are yet to be introduced.
|
// eventually be replaced with labels which are yet to be introduced.
|
||||||
CreateNetwork(nid UUID, config interface{}) error
|
CreateNetwork(nid UUID, config interface{}) error
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ import (
|
||||||
type driverTable map[string]driverapi.Driver
|
type driverTable map[string]driverapi.Driver
|
||||||
|
|
||||||
func enumerateDrivers() driverTable {
|
func enumerateDrivers() driverTable {
|
||||||
var drivers driverTable
|
drivers := make(driverTable)
|
||||||
|
|
||||||
for _, fn := range [](func() (string, driverapi.Driver)){bridge.New} {
|
for _, fn := range [](func() (string, driverapi.Driver)){bridge.New} {
|
||||||
name, driver := fn()
|
name, driver := fn()
|
||||||
drivers[name] = driver
|
drivers[name] = driver
|
||||||
|
|
|
@ -36,15 +36,16 @@ func initPortMapper() {
|
||||||
|
|
||||||
// Configuration info for the "simplebridge" driver.
|
// Configuration info for the "simplebridge" driver.
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
BridgeName string
|
BridgeName string
|
||||||
AddressIPv4 *net.IPNet
|
AddressIPv4 *net.IPNet
|
||||||
FixedCIDR *net.IPNet
|
FixedCIDR *net.IPNet
|
||||||
FixedCIDRv6 *net.IPNet
|
FixedCIDRv6 *net.IPNet
|
||||||
EnableIPv6 bool
|
EnableIPv6 bool
|
||||||
EnableIPTables bool
|
EnableIPTables bool
|
||||||
EnableIPMasquerade bool
|
EnableIPMasquerade bool
|
||||||
EnableICC bool
|
EnableICC bool
|
||||||
EnableIPForwarding bool
|
EnableIPForwarding bool
|
||||||
|
AllowNonDefaultBridge bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type bridgeEndpoint struct {
|
type bridgeEndpoint struct {
|
||||||
|
@ -62,6 +63,7 @@ type bridgeNetwork struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type driver struct {
|
type driver struct {
|
||||||
|
config *Configuration
|
||||||
network *bridgeNetwork
|
network *bridgeNetwork
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
@ -76,15 +78,45 @@ func New() (string, driverapi.Driver) {
|
||||||
return networkType, &driver{}
|
return networkType, &driver{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *driver) Config(option interface{}) error {
|
||||||
|
var config *Configuration
|
||||||
|
|
||||||
|
d.Lock()
|
||||||
|
defer d.Unlock()
|
||||||
|
|
||||||
|
if d.config != nil {
|
||||||
|
return fmt.Errorf("configuration already exists, simplebridge configuration can be applied only once")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch opt := option.(type) {
|
||||||
|
case options.Generic:
|
||||||
|
opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to generate driver config: %v", err)
|
||||||
|
}
|
||||||
|
config = opaqueConfig.(*Configuration)
|
||||||
|
case *Configuration:
|
||||||
|
config = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
d.config = config
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new network using simplebridge plugin
|
// Create a new network using simplebridge plugin
|
||||||
func (d *driver) CreateNetwork(id driverapi.UUID, option interface{}) error {
|
func (d *driver) CreateNetwork(id driverapi.UUID, option interface{}) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
config *Configuration
|
err error
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
|
if d.config == nil {
|
||||||
|
d.Unlock()
|
||||||
|
return fmt.Errorf("trying to create a network on a driver without valid config")
|
||||||
|
}
|
||||||
|
config := d.config
|
||||||
|
|
||||||
if d.network != nil {
|
if d.network != nil {
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
return fmt.Errorf("network already exists, simplebridge can only have one network")
|
return fmt.Errorf("network already exists, simplebridge can only have one network")
|
||||||
|
@ -100,19 +132,8 @@ func (d *driver) CreateNetwork(id driverapi.UUID, option interface{}) error {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
switch opt := option.(type) {
|
|
||||||
case options.Generic:
|
|
||||||
opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to generate driver config: %v", err)
|
|
||||||
}
|
|
||||||
config = opaqueConfig.(*Configuration)
|
|
||||||
case *Configuration:
|
|
||||||
config = opt
|
|
||||||
}
|
|
||||||
|
|
||||||
bridgeIface := newInterface(config)
|
bridgeIface := newInterface(config)
|
||||||
bridgeSetup := newBridgeSetup(bridgeIface)
|
bridgeSetup := newBridgeSetup(config, bridgeIface)
|
||||||
|
|
||||||
// If the bridge interface doesn't exist, we need to start the setup steps
|
// If the bridge interface doesn't exist, we need to start the setup steps
|
||||||
// by creating a new device and assigning it an IPv4 address.
|
// by creating a new device and assigning it an IPv4 address.
|
||||||
|
@ -199,7 +220,7 @@ func (d *driver) DeleteNetwork(nid driverapi.UUID) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, config interface{}) (*driverapi.SandboxInfo, error) {
|
func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, epOption interface{}) (*driverapi.SandboxInfo, error) {
|
||||||
var (
|
var (
|
||||||
ipv6Addr net.IPNet
|
ipv6Addr net.IPNet
|
||||||
err error
|
err error
|
||||||
|
@ -207,6 +228,7 @@ func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, config
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
n := d.network
|
n := d.network
|
||||||
|
config := d.config
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return nil, driverapi.ErrNoNetwork
|
return nil, driverapi.ErrNoNetwork
|
||||||
|
@ -271,7 +293,7 @@ func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, config
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = netlink.LinkSetMaster(host,
|
if err = netlink.LinkSetMaster(host,
|
||||||
&netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: n.bridge.Config.BridgeName}}); err != nil {
|
&netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: config.BridgeName}}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +303,7 @@ func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, config
|
||||||
}
|
}
|
||||||
ipv4Addr := net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
|
ipv4Addr := net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
|
||||||
|
|
||||||
if n.bridge.Config.EnableIPv6 {
|
if config.EnableIPv6 {
|
||||||
ip6, err := ipAllocator.RequestIP(n.bridge.bridgeIPv6, nil)
|
ip6, err := ipAllocator.RequestIP(n.bridge.bridgeIPv6, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -297,7 +319,7 @@ func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, config
|
||||||
intf.DstName = containerVeth
|
intf.DstName = containerVeth
|
||||||
intf.Address = ipv4Addr
|
intf.Address = ipv4Addr
|
||||||
sinfo.Gateway = n.bridge.bridgeIPv4.IP
|
sinfo.Gateway = n.bridge.bridgeIPv4.IP
|
||||||
if n.bridge.Config.EnableIPv6 {
|
if config.EnableIPv6 {
|
||||||
intf.AddressIPv6 = ipv6Addr
|
intf.AddressIPv6 = ipv6Addr
|
||||||
sinfo.GatewayIPv6 = n.bridge.bridgeIPv6.IP
|
sinfo.GatewayIPv6 = n.bridge.bridgeIPv6.IP
|
||||||
}
|
}
|
||||||
|
@ -314,6 +336,7 @@ func (d *driver) DeleteEndpoint(nid, eid driverapi.UUID) error {
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
n := d.network
|
n := d.network
|
||||||
|
config := d.config
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return driverapi.ErrNoNetwork
|
return driverapi.ErrNoNetwork
|
||||||
|
@ -356,8 +379,8 @@ func (d *driver) DeleteEndpoint(nid, eid driverapi.UUID) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.bridge.Config.EnableIPv6 {
|
if config.EnableIPv6 {
|
||||||
err := ipAllocator.ReleaseIP(n.bridge.bridgeIPv6, n.endpoint.addressIPv6)
|
err := ipAllocator.ReleaseIP(n.bridge.bridgeIPv6, ep.addressIPv6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,11 @@ func TestCreate(t *testing.T) {
|
||||||
_, d := New()
|
_, d := New()
|
||||||
|
|
||||||
config := &Configuration{BridgeName: DefaultBridgeName}
|
config := &Configuration{BridgeName: DefaultBridgeName}
|
||||||
err := d.CreateNetwork("dummy", config)
|
if err := d.Config(config); err != nil {
|
||||||
if err != nil {
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.CreateNetwork("dummy", ""); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +26,11 @@ func TestCreateFail(t *testing.T) {
|
||||||
_, d := New()
|
_, d := New()
|
||||||
|
|
||||||
config := &Configuration{BridgeName: "dummy0"}
|
config := &Configuration{BridgeName: "dummy0"}
|
||||||
if err := d.CreateNetwork("dummy", config); err == nil {
|
if err := d.Config(config); err != nil {
|
||||||
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.CreateNetwork("dummy", ""); err == nil {
|
||||||
t.Fatal("Bridge creation was expected to fail")
|
t.Fatal("Bridge creation was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +47,11 @@ func TestCreateFullOptions(t *testing.T) {
|
||||||
EnableIPForwarding: true,
|
EnableIPForwarding: true,
|
||||||
}
|
}
|
||||||
_, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
|
_, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
|
||||||
|
if err := d.Config(config); err != nil {
|
||||||
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", config)
|
err := d.CreateNetwork("dummy", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ const (
|
||||||
|
|
||||||
// Interface models the bridge network device.
|
// Interface models the bridge network device.
|
||||||
type bridgeInterface struct {
|
type bridgeInterface struct {
|
||||||
Config *Configuration
|
|
||||||
Link netlink.Link
|
Link netlink.Link
|
||||||
bridgeIPv4 *net.IPNet
|
bridgeIPv4 *net.IPNet
|
||||||
bridgeIPv6 *net.IPNet
|
bridgeIPv6 *net.IPNet
|
||||||
|
@ -25,17 +24,15 @@ type bridgeInterface struct {
|
||||||
// or the default bridge name when unspecified), but doesn't attempt to create
|
// or the default bridge name when unspecified), but doesn't attempt to create
|
||||||
// on when missing
|
// on when missing
|
||||||
func newInterface(config *Configuration) *bridgeInterface {
|
func newInterface(config *Configuration) *bridgeInterface {
|
||||||
i := &bridgeInterface{
|
i := &bridgeInterface{}
|
||||||
Config: config,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the bridge name to the default if unspecified.
|
// Initialize the bridge name to the default if unspecified.
|
||||||
if i.Config.BridgeName == "" {
|
if config.BridgeName == "" {
|
||||||
i.Config.BridgeName = DefaultBridgeName
|
config.BridgeName = DefaultBridgeName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to find an existing bridge named with the specified name.
|
// Attempt to find an existing bridge named with the specified name.
|
||||||
i.Link, _ = netlink.LinkByName(i.Config.BridgeName)
|
i.Link, _ = netlink.LinkByName(config.BridgeName)
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,9 @@ import (
|
||||||
func TestInterfaceDefaultName(t *testing.T) {
|
func TestInterfaceDefaultName(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
if inf := newInterface(&Configuration{}); inf.Config.BridgeName != DefaultBridgeName {
|
config := &Configuration{}
|
||||||
t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, inf.Config.BridgeName)
|
if _ = newInterface(config); config.BridgeName != DefaultBridgeName {
|
||||||
|
t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, config.BridgeName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,11 @@ func TestLinkCreate(t *testing.T) {
|
||||||
config := &Configuration{
|
config := &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
EnableIPv6: true}
|
EnableIPv6: true}
|
||||||
err := d.CreateNetwork("dummy", config)
|
if err := d.Config(config); err != nil {
|
||||||
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := d.CreateNetwork("dummy", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -69,7 +73,11 @@ func TestLinkCreateTwo(t *testing.T) {
|
||||||
config := &Configuration{
|
config := &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
EnableIPv6: true}
|
EnableIPv6: true}
|
||||||
err := d.CreateNetwork("dummy", config)
|
if err := d.Config(config); err != nil {
|
||||||
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := d.CreateNetwork("dummy", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -95,7 +103,11 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
||||||
|
|
||||||
config := &Configuration{
|
config := &Configuration{
|
||||||
BridgeName: DefaultBridgeName}
|
BridgeName: DefaultBridgeName}
|
||||||
err := d.CreateNetwork("dummy", config)
|
if err := d.Config(config); err != nil {
|
||||||
|
t.Fatalf("Failed to setup driver config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := d.CreateNetwork("dummy", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
type setupStep func(*bridgeInterface) error
|
type setupStep func(*Configuration, *bridgeInterface) error
|
||||||
|
|
||||||
type bridgeSetup struct {
|
type bridgeSetup struct {
|
||||||
|
config *Configuration
|
||||||
bridge *bridgeInterface
|
bridge *bridgeInterface
|
||||||
steps []setupStep
|
steps []setupStep
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBridgeSetup(i *bridgeInterface) *bridgeSetup {
|
func newBridgeSetup(c *Configuration, i *bridgeInterface) *bridgeSetup {
|
||||||
return &bridgeSetup{bridge: i}
|
return &bridgeSetup{config: c, bridge: i}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bridgeSetup) apply() error {
|
func (b *bridgeSetup) apply() error {
|
||||||
for _, fn := range b.steps {
|
for _, fn := range b.steps {
|
||||||
if err := fn(b.bridge); err != nil {
|
if err := fn(b.config, b.bridge); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetupDevice create a new bridge interface/
|
// SetupDevice create a new bridge interface/
|
||||||
func setupDevice(i *bridgeInterface) error {
|
func setupDevice(config *Configuration, i *bridgeInterface) error {
|
||||||
// We only attempt to create the bridge when the requested device name is
|
// We only attempt to create the bridge when the requested device name is
|
||||||
// the default one.
|
// the default one.
|
||||||
if i.Config.BridgeName != DefaultBridgeName {
|
if config.BridgeName != DefaultBridgeName && !config.AllowNonDefaultBridge {
|
||||||
return fmt.Errorf("bridge device with non default name %q must be created manually", i.Config.BridgeName)
|
return fmt.Errorf("bridge device with non default name %q must be created manually", config.BridgeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the bridgeInterface netlink.Bridge.
|
// Set the bridgeInterface netlink.Bridge.
|
||||||
i.Link = &netlink.Bridge{
|
i.Link = &netlink.Bridge{
|
||||||
LinkAttrs: netlink.LinkAttrs{
|
LinkAttrs: netlink.LinkAttrs{
|
||||||
Name: i.Config.BridgeName,
|
Name: config.BridgeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ func setupDevice(i *bridgeInterface) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupDeviceUp ups the given bridge interface.
|
// SetupDeviceUp ups the given bridge interface.
|
||||||
func setupDeviceUp(i *bridgeInterface) error {
|
func setupDeviceUp(config *Configuration, i *bridgeInterface) error {
|
||||||
err := netlink.LinkSetUp(i.Link)
|
err := netlink.LinkSetUp(i.Link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -45,7 +45,7 @@ func setupDeviceUp(i *bridgeInterface) error {
|
||||||
|
|
||||||
// Attempt to update the bridge interface to refresh the flags status,
|
// Attempt to update the bridge interface to refresh the flags status,
|
||||||
// ignoring any failure to do so.
|
// ignoring any failure to do so.
|
||||||
if lnk, err := netlink.LinkByName(i.Config.BridgeName); err == nil {
|
if lnk, err := netlink.LinkByName(config.BridgeName); err == nil {
|
||||||
i.Link = lnk
|
i.Link = lnk
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -13,12 +13,10 @@ import (
|
||||||
func TestSetupNewBridge(t *testing.T) {
|
func TestSetupNewBridge(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &bridgeInterface{
|
config := &Configuration{BridgeName: DefaultBridgeName}
|
||||||
Config: &Configuration{
|
br := &bridgeInterface{}
|
||||||
BridgeName: DefaultBridgeName,
|
|
||||||
},
|
if err := setupDevice(config, br); err != nil {
|
||||||
}
|
|
||||||
if err := setupDevice(br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if br.Link == nil {
|
if br.Link == nil {
|
||||||
|
@ -35,12 +33,10 @@ func TestSetupNewBridge(t *testing.T) {
|
||||||
func TestSetupNewNonDefaultBridge(t *testing.T) {
|
func TestSetupNewNonDefaultBridge(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &bridgeInterface{
|
config := &Configuration{BridgeName: "test0"}
|
||||||
Config: &Configuration{
|
br := &bridgeInterface{}
|
||||||
BridgeName: "test0",
|
|
||||||
},
|
if err := setupDevice(config, br); err == nil || !strings.Contains(err.Error(), "non default name") {
|
||||||
}
|
|
||||||
if err := setupDevice(br); err == nil || !strings.Contains(err.Error(), "non default name") {
|
|
||||||
t.Fatalf("Expected bridge creation failure with \"non default name\", got: %v", err)
|
t.Fatalf("Expected bridge creation failure with \"non default name\", got: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,15 +44,13 @@ func TestSetupNewNonDefaultBridge(t *testing.T) {
|
||||||
func TestSetupDeviceUp(t *testing.T) {
|
func TestSetupDeviceUp(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &bridgeInterface{
|
config := &Configuration{BridgeName: DefaultBridgeName}
|
||||||
Config: &Configuration{
|
br := &bridgeInterface{}
|
||||||
BridgeName: DefaultBridgeName,
|
|
||||||
},
|
if err := setupDevice(config, br); err != nil {
|
||||||
}
|
|
||||||
if err := setupDevice(br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := setupDeviceUp(br); err != nil {
|
if err := setupDeviceUp(config, br); err != nil {
|
||||||
t.Fatalf("Failed to up bridge device: %v", err)
|
t.Fatalf("Failed to up bridge device: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@ import (
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupFixedCIDRv4(i *bridgeInterface) error {
|
func setupFixedCIDRv4(config *Configuration, i *bridgeInterface) error {
|
||||||
addrv4, _, err := i.addresses()
|
addrv4, _, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Using IPv4 subnet: %v", i.Config.FixedCIDR)
|
log.Debugf("Using IPv4 subnet: %v", config.FixedCIDR)
|
||||||
if err := ipAllocator.RegisterSubnet(addrv4.IPNet, i.Config.FixedCIDR); err != nil {
|
if err := ipAllocator.RegisterSubnet(addrv4.IPNet, config.FixedCIDR); err != nil {
|
||||||
return fmt.Errorf("Setup FixedCIDRv4 failed for subnet %s in %s: %v", i.Config.FixedCIDR, addrv4.IPNet, err)
|
return fmt.Errorf("Setup FixedCIDRv4 failed for subnet %s in %s: %v", config.FixedCIDR, addrv4.IPNet, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -10,25 +10,24 @@ import (
|
||||||
func TestSetupFixedCIDRv4(t *testing.T) {
|
func TestSetupFixedCIDRv4(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName,
|
||||||
BridgeName: DefaultBridgeName,
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)}}
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
br := &bridgeInterface{}
|
||||||
},
|
|
||||||
}
|
if err := setupDevice(config, br); err != nil {
|
||||||
if err := setupDevice(br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupFixedCIDRv4(br); err != nil {
|
if err := setupFixedCIDRv4(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ip, err := ipAllocator.RequestIP(br.Config.FixedCIDR, nil); err != nil {
|
if ip, err := ipAllocator.RequestIP(config.FixedCIDR, nil); err != nil {
|
||||||
t.Fatalf("Failed to request IP to allocator: %v", err)
|
t.Fatalf("Failed to request IP to allocator: %v", err)
|
||||||
} else if expected := "192.168.2.1"; ip.String() != expected {
|
} else if expected := "192.168.2.1"; ip.String() != expected {
|
||||||
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
||||||
|
@ -38,21 +37,20 @@ func TestSetupFixedCIDRv4(t *testing.T) {
|
||||||
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName,
|
||||||
BridgeName: DefaultBridgeName,
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)}}
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
br := &bridgeInterface{}
|
||||||
},
|
|
||||||
}
|
if err := setupDevice(config, br); err != nil {
|
||||||
if err := setupDevice(br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupFixedCIDRv4(br); err == nil {
|
if err := setupFixedCIDRv4(config, br); err == nil {
|
||||||
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupFixedCIDRv6(i *bridgeInterface) error {
|
func setupFixedCIDRv6(config *Configuration, i *bridgeInterface) error {
|
||||||
log.Debugf("Using IPv6 subnet: %v", i.Config.FixedCIDRv6)
|
log.Debugf("Using IPv6 subnet: %v", config.FixedCIDRv6)
|
||||||
if err := ipAllocator.RegisterSubnet(i.Config.FixedCIDRv6, i.Config.FixedCIDRv6); err != nil {
|
if err := ipAllocator.RegisterSubnet(config.FixedCIDRv6, config.FixedCIDRv6); err != nil {
|
||||||
return fmt.Errorf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", i.Config.FixedCIDRv6, i.Config.FixedCIDRv6, err)
|
return fmt.Errorf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", config.FixedCIDRv6, config.FixedCIDRv6, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -10,25 +10,26 @@ import (
|
||||||
func TestSetupFixedCIDRv6(t *testing.T) {
|
func TestSetupFixedCIDRv6(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := newInterface(&Configuration{})
|
config := &Configuration{}
|
||||||
|
br := newInterface(config)
|
||||||
|
|
||||||
_, br.Config.FixedCIDRv6, _ = net.ParseCIDR("2002:db8::/48")
|
_, config.FixedCIDRv6, _ = net.ParseCIDR("2002:db8::/48")
|
||||||
if err := setupDevice(br); err != nil {
|
if err := setupDevice(config, br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupBridgeIPv6(br); err != nil {
|
if err := setupBridgeIPv6(config, br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupFixedCIDRv6(br); err != nil {
|
if err := setupFixedCIDRv6(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv6: %v", err)
|
t.Fatalf("Failed to setup bridge FixedCIDRv6: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ip, err := ipAllocator.RequestIP(br.Config.FixedCIDRv6, nil); err != nil {
|
if ip, err := ipAllocator.RequestIP(config.FixedCIDRv6, nil); err != nil {
|
||||||
t.Fatalf("Failed to request IP to allocator: %v", err)
|
t.Fatalf("Failed to request IP to allocator: %v", err)
|
||||||
} else if expected := "2002:db8::1"; ip.String() != expected {
|
} else if expected := "2002:db8::1"; ip.String() != expected {
|
||||||
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
||||||
|
|
|
@ -10,9 +10,9 @@ const (
|
||||||
ipv4ForwardConfPerm = 0644
|
ipv4ForwardConfPerm = 0644
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupIPForwarding(i *bridgeInterface) error {
|
func setupIPForwarding(config *Configuration, i *bridgeInterface) error {
|
||||||
// Sanity Check
|
// Sanity Check
|
||||||
if i.Config.EnableIPForwarding == false {
|
if config.EnableIPForwarding == false {
|
||||||
return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i)
|
return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,15 +18,13 @@ func TestSetupIPForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create test interface with ip forwarding setting enabled
|
// Create test interface with ip forwarding setting enabled
|
||||||
br := &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName,
|
||||||
BridgeName: DefaultBridgeName,
|
EnableIPForwarding: true}
|
||||||
EnableIPForwarding: true,
|
br := &bridgeInterface{}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set IP Forwarding
|
// Set IP Forwarding
|
||||||
if err := setupIPForwarding(br); err != nil {
|
if err := setupIPForwarding(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup IP forwarding: %v", err)
|
t.Fatalf("Failed to setup IP forwarding: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +41,13 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
|
||||||
defer reconcileIPForwardingSetting(t, procSetting)
|
defer reconcileIPForwardingSetting(t, procSetting)
|
||||||
|
|
||||||
// Create test interface without ip forwarding setting enabled
|
// Create test interface without ip forwarding setting enabled
|
||||||
br := &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName,
|
||||||
BridgeName: DefaultBridgeName,
|
EnableIPForwarding: false}
|
||||||
EnableIPForwarding: false,
|
br := &bridgeInterface{}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt Set IP Forwarding
|
// Attempt Set IP Forwarding
|
||||||
if err := setupIPForwarding(br); err == nil {
|
if err := setupIPForwarding(config, br); err == nil {
|
||||||
t.Fatal("Setup IP forwarding was expected to fail")
|
t.Fatal("Setup IP forwarding was expected to fail")
|
||||||
} else if !strings.Contains(err.Error(), "Unexpected request") {
|
} else if !strings.Contains(err.Error(), "Unexpected request") {
|
||||||
t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
|
t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
|
||||||
|
|
|
@ -13,26 +13,26 @@ const (
|
||||||
DockerChain = "DOCKER"
|
DockerChain = "DOCKER"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupIPTables(i *bridgeInterface) error {
|
func setupIPTables(config *Configuration, i *bridgeInterface) error {
|
||||||
// Sanity check.
|
// Sanity check.
|
||||||
if i.Config.EnableIPTables == false {
|
if config.EnableIPTables == false {
|
||||||
return fmt.Errorf("Unexpected request to set IP tables for interface: %s", i.Config.BridgeName)
|
return fmt.Errorf("Unexpected request to set IP tables for interface: %s", config.BridgeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
addrv4, _, err := netutils.GetIfaceAddr(i.Config.BridgeName)
|
addrv4, _, err := netutils.GetIfaceAddr(config.BridgeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to setup IP tables, cannot acquire Interface address: %s", err.Error())
|
return fmt.Errorf("Failed to setup IP tables, cannot acquire Interface address: %s", err.Error())
|
||||||
}
|
}
|
||||||
if err = setupIPTablesInternal(i.Config.BridgeName, addrv4, i.Config.EnableICC, i.Config.EnableIPMasquerade, true); err != nil {
|
if err = setupIPTablesInternal(config.BridgeName, addrv4, config.EnableICC, config.EnableIPMasquerade, true); err != nil {
|
||||||
return fmt.Errorf("Failed to Setup IP tables: %s", err.Error())
|
return fmt.Errorf("Failed to Setup IP tables: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = iptables.NewChain(DockerChain, i.Config.BridgeName, iptables.Nat)
|
_, err = iptables.NewChain(DockerChain, config.BridgeName, iptables.Nat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create NAT chain: %s", err.Error())
|
return fmt.Errorf("Failed to create NAT chain: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, err := iptables.NewChain(DockerChain, i.Config.BridgeName, iptables.Filter)
|
chain, err := iptables.NewChain(DockerChain, config.BridgeName, iptables.Filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create FILTER chain: %s", err.Error())
|
return fmt.Errorf("Failed to create FILTER chain: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ const (
|
||||||
func TestProgramIPTable(t *testing.T) {
|
func TestProgramIPTable(t *testing.T) {
|
||||||
// Create a test bridge with a basic bridge configuration (name + IPv4).
|
// Create a test bridge with a basic bridge configuration (name + IPv4).
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
createTestBridge(getBasicTestConfig(), t)
|
createTestBridge(getBasicTestConfig(), &bridgeInterface{}, t)
|
||||||
|
|
||||||
// Store various iptables chain rules we care for.
|
// Store various iptables chain rules we care for.
|
||||||
rules := []struct {
|
rules := []struct {
|
||||||
|
@ -39,37 +39,37 @@ func TestProgramIPTable(t *testing.T) {
|
||||||
func TestSetupIPTables(t *testing.T) {
|
func TestSetupIPTables(t *testing.T) {
|
||||||
// Create a test bridge with a basic bridge configuration (name + IPv4).
|
// Create a test bridge with a basic bridge configuration (name + IPv4).
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
br := getBasicTestConfig()
|
config := getBasicTestConfig()
|
||||||
createTestBridge(br, t)
|
br := &bridgeInterface{}
|
||||||
|
|
||||||
|
createTestBridge(config, br, t)
|
||||||
|
|
||||||
// Modify iptables params in base configuration and apply them.
|
// Modify iptables params in base configuration and apply them.
|
||||||
br.Config.EnableIPTables = true
|
config.EnableIPTables = true
|
||||||
assertBridgeConfig(br, t)
|
assertBridgeConfig(config, br, t)
|
||||||
|
|
||||||
br.Config.EnableIPMasquerade = true
|
config.EnableIPMasquerade = true
|
||||||
assertBridgeConfig(br, t)
|
assertBridgeConfig(config, br, t)
|
||||||
|
|
||||||
br.Config.EnableICC = true
|
config.EnableICC = true
|
||||||
assertBridgeConfig(br, t)
|
assertBridgeConfig(config, br, t)
|
||||||
|
|
||||||
br.Config.EnableIPMasquerade = false
|
config.EnableIPMasquerade = false
|
||||||
assertBridgeConfig(br, t)
|
assertBridgeConfig(config, br, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBasicTestConfig() *bridgeInterface {
|
func getBasicTestConfig() *Configuration {
|
||||||
return &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName,
|
||||||
BridgeName: DefaultBridgeName,
|
AddressIPv4: &net.IPNet{IP: net.ParseIP(iptablesTestBridgeIP), Mask: net.CIDRMask(16, 32)}}
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP(iptablesTestBridgeIP), Mask: net.CIDRMask(16, 32)},
|
return config
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestBridge(br *bridgeInterface, t *testing.T) {
|
func createTestBridge(config *Configuration, br *bridgeInterface, t *testing.T) {
|
||||||
if err := setupDevice(br); err != nil {
|
if err := setupDevice(config, br); err != nil {
|
||||||
t.Fatalf("Failed to create the testing Bridge: %s", err.Error())
|
t.Fatalf("Failed to create the testing Bridge: %s", err.Error())
|
||||||
}
|
}
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Failed to bring up the testing Bridge: %s", err.Error())
|
t.Fatalf("Failed to bring up the testing Bridge: %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,9 +94,9 @@ func assertIPTableChainProgramming(rule iptRule, descr string, t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert function which pushes chains based on bridge config parameters.
|
// Assert function which pushes chains based on bridge config parameters.
|
||||||
func assertBridgeConfig(br *bridgeInterface, t *testing.T) {
|
func assertBridgeConfig(config *Configuration, br *bridgeInterface, t *testing.T) {
|
||||||
// Attempt programming of ip tables.
|
// Attempt programming of ip tables.
|
||||||
err := setupIPTables(br)
|
err := setupIPTables(config, br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%v", err)
|
t.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,13 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBridgeIPv4(i *bridgeInterface) error {
|
func setupBridgeIPv4(config *Configuration, i *bridgeInterface) error {
|
||||||
bridgeIPv4, err := electBridgeIPv4(i.Config)
|
bridgeIPv4, err := electBridgeIPv4(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Creating bridge interface %q with network %s", i.Config.BridgeName, bridgeIPv4)
|
log.Debugf("Creating bridge interface %q with network %s", config.BridgeName, bridgeIPv4)
|
||||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
||||||
return fmt.Errorf("Failed to add IPv4 address %s to bridge: %v", bridgeIPv4, err)
|
return fmt.Errorf("Failed to add IPv4 address %s to bridge: %v", bridgeIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,15 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupTestInterface(t *testing.T) *bridgeInterface {
|
func setupTestInterface(t *testing.T) (*Configuration, *bridgeInterface) {
|
||||||
br := &bridgeInterface{
|
config := &Configuration{
|
||||||
Config: &Configuration{
|
BridgeName: DefaultBridgeName}
|
||||||
BridgeName: DefaultBridgeName,
|
br := &bridgeInterface{}
|
||||||
},
|
|
||||||
}
|
if err := setupDevice(config, br); err != nil {
|
||||||
if err := setupDevice(br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
return br
|
return config, br
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
||||||
|
@ -28,9 +27,9 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
||||||
t.Fatalf("Failed to parse bridge IPv4: %v", err)
|
t.Fatalf("Failed to parse bridge IPv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
config, br := setupTestInterface(t)
|
||||||
br.Config.AddressIPv4 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
config.AddressIPv4 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,22 +40,22 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
for _, addr := range addrsv4 {
|
for _, addr := range addrsv4 {
|
||||||
if br.Config.AddressIPv4.String() == addr.IPNet.String() {
|
if config.AddressIPv4.String() == addr.IPNet.String() {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
t.Fatalf("Bridge device does not have requested IPv4 address %v", br.Config.AddressIPv4)
|
t.Fatalf("Bridge device does not have requested IPv4 address %v", config.AddressIPv4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetupBridgeIPv4Auto(t *testing.T) {
|
func TestSetupBridgeIPv4Auto(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
config, br := setupTestInterface(t)
|
||||||
if err := setupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,9 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBridgeIPv6(i *bridgeInterface) error {
|
func setupBridgeIPv6(config *Configuration, i *bridgeInterface) error {
|
||||||
// Enable IPv6 on the bridge
|
// Enable IPv6 on the bridge
|
||||||
procFile := "/proc/sys/net/ipv6/conf/" + i.Config.BridgeName + "/disable_ipv6"
|
procFile := "/proc/sys/net/ipv6/conf/" + config.BridgeName + "/disable_ipv6"
|
||||||
if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
|
if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
|
||||||
return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
|
return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,12 @@ import (
|
||||||
func TestSetupIPv6(t *testing.T) {
|
func TestSetupIPv6(t *testing.T) {
|
||||||
defer netutils.SetupTestNetNS(t)()
|
defer netutils.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
config, br := setupTestInterface(t)
|
||||||
if err := setupBridgeIPv6(br); err != nil {
|
if err := setupBridgeIPv6(config, br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv6: %v", err)
|
t.Fatalf("Failed to setup bridge IPv6: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
procSetting, err := ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", br.Config.BridgeName))
|
procSetting, err := ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", config.BridgeName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to read disable_ipv6 kernel setting: %v", err)
|
t.Fatalf("Failed to read disable_ipv6 kernel setting: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupVerifyConfiguredAddresses(i *bridgeInterface) error {
|
func setupVerifyConfiguredAddresses(config *Configuration, i *bridgeInterface) error {
|
||||||
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
||||||
addrv4, addrsv6, err := i.addresses()
|
addrv4, addrsv6, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,13 +19,13 @@ func setupVerifyConfiguredAddresses(i *bridgeInterface) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the bridge IPv4 address matches the requested configuration.
|
// Verify that the bridge IPv4 address matches the requested configuration.
|
||||||
if i.Config.AddressIPv4 != nil && !addrv4.IP.Equal(i.Config.AddressIPv4.IP) {
|
if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
|
||||||
return fmt.Errorf("Bridge IPv4 (%s) does not match requested configuration %s", addrv4.IP, i.Config.AddressIPv4.IP)
|
return fmt.Errorf("Bridge IPv4 (%s) does not match requested configuration %s", addrv4.IP, config.AddressIPv4.IP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that one of the bridge IPv6 addresses matches the requested
|
// Verify that one of the bridge IPv6 addresses matches the requested
|
||||||
// configuration.
|
// configuration.
|
||||||
if i.Config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
|
if config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
|
||||||
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", bridgeIPv6)
|
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", bridgeIPv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupVerifyTest(t *testing.T) *bridgeInterface {
|
func setupVerifyTest(t *testing.T) *bridgeInterface {
|
||||||
inf := &bridgeInterface{Config: &Configuration{}}
|
inf := &bridgeInterface{}
|
||||||
|
|
||||||
br := netlink.Bridge{}
|
br := netlink.Bridge{}
|
||||||
br.LinkAttrs.Name = "default0"
|
br.LinkAttrs.Name = "default0"
|
||||||
|
@ -27,13 +27,14 @@ func TestSetupVerify(t *testing.T) {
|
||||||
|
|
||||||
addrv4 := net.IPv4(192, 168, 1, 1)
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
config := &Configuration{}
|
||||||
|
config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupVerifyConfiguredAddresses(inf); err != nil {
|
if err := setupVerifyConfiguredAddresses(config, inf); err != nil {
|
||||||
t.Fatalf("Address verification failed: %v", err)
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,14 +44,15 @@ func TestSetupVerifyBad(t *testing.T) {
|
||||||
|
|
||||||
addrv4 := net.IPv4(192, 168, 1, 1)
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
config := &Configuration{}
|
||||||
|
config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
ipnet := &net.IPNet{IP: net.IPv4(192, 168, 1, 2), Mask: addrv4.DefaultMask()}
|
ipnet := &net.IPNet{IP: net.IPv4(192, 168, 1, 2), Mask: addrv4.DefaultMask()}
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: ipnet}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: ipnet}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", ipnet, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", ipnet, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(config, inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,9 +62,10 @@ func TestSetupVerifyMissing(t *testing.T) {
|
||||||
|
|
||||||
addrv4 := net.IPv4(192, 168, 1, 1)
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
config := &Configuration{}
|
||||||
|
config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(config, inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,17 +75,18 @@ func TestSetupVerifyIPv6(t *testing.T) {
|
||||||
|
|
||||||
addrv4 := net.IPv4(192, 168, 1, 1)
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
config := &Configuration{}
|
||||||
inf.Config.EnableIPv6 = true
|
config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
config.EnableIPv6 = true
|
||||||
|
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv6 %s to interface: %v", bridgeIPv6, err)
|
t.Fatalf("Failed to assign IPv6 %s to interface: %v", bridgeIPv6, err)
|
||||||
}
|
}
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupVerifyConfiguredAddresses(inf); err != nil {
|
if err := setupVerifyConfiguredAddresses(config, inf); err != nil {
|
||||||
t.Fatalf("Address verification failed: %v", err)
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,14 +96,15 @@ func TestSetupVerifyIPv6Missing(t *testing.T) {
|
||||||
|
|
||||||
addrv4 := net.IPv4(192, 168, 1, 1)
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
config := &Configuration{}
|
||||||
inf.Config.EnableIPv6 = true
|
config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
config.EnableIPv6 = true
|
||||||
|
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(config, inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package libnetwork_test
|
package libnetwork_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -12,14 +11,9 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bridgeName = "docker0"
|
var bridgeName = "dockertest0"
|
||||||
var enableBridgeTest = flag.Bool("enable-bridge-test", false, "")
|
|
||||||
|
|
||||||
func TestSimplebridge(t *testing.T) {
|
func TestSimplebridge(t *testing.T) {
|
||||||
if *enableBridgeTest == false {
|
|
||||||
t.Skip()
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}
|
bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}
|
||||||
netlink.LinkDel(bridge)
|
netlink.LinkDel(bridge)
|
||||||
|
|
||||||
|
@ -43,23 +37,38 @@ func TestSimplebridge(t *testing.T) {
|
||||||
|
|
||||||
log.Debug("Adding a simple bridge")
|
log.Debug("Adding a simple bridge")
|
||||||
options := options.Generic{
|
options := options.Generic{
|
||||||
"BridgeName": bridgeName,
|
"BridgeName": bridgeName,
|
||||||
"AddressIPv4": subnet,
|
"AddressIPv4": subnet,
|
||||||
"FixedCIDR": cidr,
|
"FixedCIDR": cidr,
|
||||||
"FixedCIDRv6": cidrv6,
|
"FixedCIDRv6": cidrv6,
|
||||||
"EnableIPv6": true,
|
"EnableIPv6": true,
|
||||||
"EnableIPTables": true,
|
"EnableIPTables": true,
|
||||||
"EnableIPMasquerade": true,
|
"EnableIPMasquerade": true,
|
||||||
"EnableICC": true,
|
"EnableICC": true,
|
||||||
"EnableIPForwarding": true}
|
"EnableIPForwarding": true,
|
||||||
|
"AllowNonDefaultBridge": true}
|
||||||
|
|
||||||
controller := libnetwork.New()
|
controller := libnetwork.New()
|
||||||
|
|
||||||
network, err := controller.NewNetwork("simplebridge", "dummy", options)
|
driver, err := controller.NewNetworkDriver("simplebridge", options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network, err := controller.NewNetwork(driver, "testnetwork", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ep, _, err := network.CreateEndpoint("testep", "", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ep.Delete(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := network.Delete(); err != nil {
|
if err := network.Delete(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,17 @@ create network namespaces and allocate interfaces for containers to use.
|
||||||
// Create a new controller instance
|
// Create a new controller instance
|
||||||
controller := libnetwork.New()
|
controller := libnetwork.New()
|
||||||
|
|
||||||
options := options.Generic{}
|
// This option is only needed for in-tree drivers. Plugins(in future) will get
|
||||||
|
// their options through plugin infrastructure.
|
||||||
|
option := options.Generic{}
|
||||||
|
driver, err := controller.NewNetworkDriver("simplebridge", option)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
netOptions := options.Generic{}
|
||||||
// Create a network for containers to join.
|
// Create a network for containers to join.
|
||||||
network, err := controller.NewNetwork("simplebridge", "network1", options)
|
network, err := controller.NewNetwork(driver, "network1", netOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -53,13 +61,14 @@ import (
|
||||||
// NetworkController provides the interface for controller instance which manages
|
// NetworkController provides the interface for controller instance which manages
|
||||||
// networks.
|
// networks.
|
||||||
type NetworkController interface {
|
type NetworkController interface {
|
||||||
|
NewNetworkDriver(networkType string, options interface{}) (*NetworkDriver, error)
|
||||||
// Create a new network. The options parameter carry driver specific options.
|
// Create a new network. The options parameter carry driver specific options.
|
||||||
// Labels support will be added in the near future.
|
// Labels support will be added in the near future.
|
||||||
NewNetwork(networkType, name string, options interface{}) (Network, error)
|
NewNetwork(d *NetworkDriver, name string, options interface{}) (Network, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Network represents a logical connectivity zone that containers may
|
// A Network represents a logical connectivity zone that containers may
|
||||||
// ulteriorly join using the Link method. A Network is managed by a specific
|
// ulteriorly join using the CreateEndpoint method. A Network is managed by a specific
|
||||||
// driver.
|
// driver.
|
||||||
type Network interface {
|
type Network interface {
|
||||||
// A user chosen name for this network.
|
// A user chosen name for this network.
|
||||||
|
@ -86,6 +95,11 @@ type Endpoint interface {
|
||||||
Delete() error
|
Delete() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetworkDriver provides a reference to driver and way to push driver specific config
|
||||||
|
type NetworkDriver struct {
|
||||||
|
internalDriver driverapi.Driver
|
||||||
|
}
|
||||||
|
|
||||||
type endpoint struct {
|
type endpoint struct {
|
||||||
name string
|
name string
|
||||||
id driverapi.UUID
|
id driverapi.UUID
|
||||||
|
@ -98,11 +112,13 @@ type network struct {
|
||||||
name string
|
name string
|
||||||
networkType string
|
networkType string
|
||||||
id driverapi.UUID
|
id driverapi.UUID
|
||||||
endpoints map[driverapi.UUID]*endpoint
|
driver *NetworkDriver
|
||||||
|
endpoints endpointTable
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type networkTable map[driverapi.UUID]*network
|
type networkTable map[driverapi.UUID]*network
|
||||||
|
type endpointTable map[driverapi.UUID]*endpoint
|
||||||
|
|
||||||
type controller struct {
|
type controller struct {
|
||||||
networks networkTable
|
networks networkTable
|
||||||
|
@ -115,18 +131,34 @@ func New() NetworkController {
|
||||||
return &controller{networkTable{}, enumerateDrivers(), sync.Mutex{}}
|
return &controller{networkTable{}, enumerateDrivers(), sync.Mutex{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNetwork creates a new network of the specified networkType. The options
|
func (c *controller) NewNetworkDriver(networkType string, options interface{}) (*NetworkDriver, error) {
|
||||||
// are driver specific and modeled in a generic way.
|
|
||||||
func (c *controller) NewNetwork(networkType, name string, options interface{}) (Network, error) {
|
|
||||||
network := &network{name: name, networkType: networkType}
|
|
||||||
network.id = driverapi.UUID(common.GenerateRandomID())
|
|
||||||
network.ctrlr = c
|
|
||||||
|
|
||||||
d, ok := c.drivers[networkType]
|
d, ok := c.drivers[networkType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unknown driver %q", networkType)
|
return nil, fmt.Errorf("unknown driver %q", networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := d.Config(options); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NetworkDriver{internalDriver: d}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetwork creates a new network of the specified networkType. The options
|
||||||
|
// are driver specific and modeled in a generic way.
|
||||||
|
func (c *controller) NewNetwork(nd *NetworkDriver, name string, options interface{}) (Network, error) {
|
||||||
|
network := &network{
|
||||||
|
name: name,
|
||||||
|
id: driverapi.UUID(common.GenerateRandomID()),
|
||||||
|
ctrlr: c,
|
||||||
|
driver: nd}
|
||||||
|
network.endpoints = make(endpointTable)
|
||||||
|
|
||||||
|
d := network.driver.internalDriver
|
||||||
|
if d == nil {
|
||||||
|
return nil, fmt.Errorf("invalid driver bound to network")
|
||||||
|
}
|
||||||
|
|
||||||
if err := d.CreateNetwork(network.id, options); err != nil {
|
if err := d.CreateNetwork(network.id, options); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -153,13 +185,8 @@ func (n *network) Type() string {
|
||||||
func (n *network) Delete() error {
|
func (n *network) Delete() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
d, ok := n.ctrlr.drivers[n.networkType]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("unknown driver %q", n.networkType)
|
|
||||||
}
|
|
||||||
|
|
||||||
n.ctrlr.Lock()
|
n.ctrlr.Lock()
|
||||||
_, ok = n.ctrlr.networks[n.id]
|
_, ok := n.ctrlr.networks[n.id]
|
||||||
if !ok {
|
if !ok {
|
||||||
n.ctrlr.Unlock()
|
n.ctrlr.Unlock()
|
||||||
return fmt.Errorf("unknown network %s id %s", n.name, n.id)
|
return fmt.Errorf("unknown network %s id %s", n.name, n.id)
|
||||||
|
@ -183,6 +210,7 @@ func (n *network) Delete() error {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
d := n.driver.internalDriver
|
||||||
err = d.DeleteNetwork(n.id)
|
err = d.DeleteNetwork(n.id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -192,11 +220,7 @@ func (n *network) CreateEndpoint(name string, sboxKey string, options interface{
|
||||||
ep.id = driverapi.UUID(common.GenerateRandomID())
|
ep.id = driverapi.UUID(common.GenerateRandomID())
|
||||||
ep.network = n
|
ep.network = n
|
||||||
|
|
||||||
d, ok := n.ctrlr.drivers[n.networkType]
|
d := n.driver.internalDriver
|
||||||
if !ok {
|
|
||||||
return nil, nil, fmt.Errorf("unknown driver %q", n.networkType)
|
|
||||||
}
|
|
||||||
|
|
||||||
sinfo, err := d.CreateEndpoint(n.id, ep.id, sboxKey, options)
|
sinfo, err := d.CreateEndpoint(n.id, ep.id, sboxKey, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -212,14 +236,9 @@ func (n *network) CreateEndpoint(name string, sboxKey string, options interface{
|
||||||
func (ep *endpoint) Delete() error {
|
func (ep *endpoint) Delete() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
d, ok := ep.network.ctrlr.drivers[ep.network.networkType]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("unknown driver %q", ep.network.networkType)
|
|
||||||
}
|
|
||||||
|
|
||||||
n := ep.network
|
n := ep.network
|
||||||
n.Lock()
|
n.Lock()
|
||||||
_, ok = n.endpoints[ep.id]
|
_, ok := n.endpoints[ep.id]
|
||||||
if !ok {
|
if !ok {
|
||||||
n.Unlock()
|
n.Unlock()
|
||||||
return fmt.Errorf("unknown endpoint %s id %s", ep.name, ep.id)
|
return fmt.Errorf("unknown endpoint %s id %s", ep.name, ep.id)
|
||||||
|
@ -235,6 +254,7 @@ func (ep *endpoint) Delete() error {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
d := n.driver.internalDriver
|
||||||
err = d.DeleteEndpoint(n.id, ep.id)
|
err = d.DeleteEndpoint(n.id, ep.id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue