func TestIPDataMarshalling(t *testing.T) {
	i := &IPAMData{
		AddressSpace: "giallo",
		Pool:         &net.IPNet{IP: net.IP{10, 10, 10, 8}, Mask: net.IPMask{255, 255, 255, 0}},
		Gateway:      &net.IPNet{IP: net.IP{10, 10, 10, 254}, Mask: net.IPMask{255, 255, 255, 0}},
		AuxAddresses: map[string]*net.IPNet{
			"ip1": &net.IPNet{IP: net.IP{10, 10, 10, 1}, Mask: net.IPMask{255, 255, 255, 0}},
			"ip2": &net.IPNet{IP: net.IP{10, 10, 10, 2}, Mask: net.IPMask{255, 255, 255, 0}},
		},
	}

	b, err := json.Marshal(i)
	if err != nil {
		t.Fatal(err)
	}

	ii := &IPAMData{}
	err = json.Unmarshal(b, &ii)
	if err != nil {
		t.Fatal(err)
	}

	if i.AddressSpace != ii.AddressSpace || !types.CompareIPNet(i.Pool, ii.Pool) ||
		!types.CompareIPNet(i.Gateway, ii.Gateway) ||
		!compareAddresses(i.AuxAddresses, ii.AuxAddresses) {
		t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%s\nDecoded:\n%s", i, ii)
	}
}
示例#2
0
// Install/Removes the iptables rules needed to isolate this network
// from each of the other networks
func (n *bridgeNetwork) isolateNetwork(others []*bridgeNetwork, enable bool) error {
	n.Lock()
	thisV4 := n.bridge.bridgeIPv4
	thisV6 := getV6Network(n.config, n.bridge)
	n.Unlock()

	// Install the rules to isolate this networks against each of the other networks
	for _, o := range others {
		o.Lock()
		otherV4 := o.bridge.bridgeIPv4
		otherV6 := getV6Network(o.config, o.bridge)
		o.Unlock()

		if !types.CompareIPNet(thisV4, otherV4) {
			// It's ok to pass a.b.c.d/x, iptables will ignore the host subnet bits
			if err := setINC(thisV4.String(), otherV4.String(), enable); err != nil {
				return err
			}
		}

		if thisV6 != nil && otherV6 != nil && !types.CompareIPNet(thisV6, otherV6) {
			if err := setINC(thisV6.String(), otherV6.String(), enable); err != nil {
				return err
			}
		}
	}

	return nil
}
func compareEndpointInterface(a, b *endpointInterface) bool {
	if a == b {
		return true
	}
	if a == nil || b == nil {
		return false
	}
	return a.srcName == b.srcName && a.dstPrefix == b.dstPrefix && a.v4PoolID == b.v4PoolID && a.v6PoolID == b.v6PoolID &&
		types.CompareIPNet(a.addr, b.addr) && types.CompareIPNet(a.addrv6, b.addrv6)
}
示例#4
0
func TestNetworkRequest(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	nw, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}

	var found bool
	for _, exp := range ipamutils.PredefinedBroadNetworks {
		if types.CompareIPNet(exp, nw) {
			found = true
			break
		}
	}

	if !found {
		t.Fatalf("Found unexpected broad network %s", nw)
	}

	nw, err = FindAvailableNetwork(ipamutils.PredefinedGranularNetworks)
	if err != nil {
		t.Fatal(err)
	}

	found = false
	for _, exp := range ipamutils.PredefinedGranularNetworks {
		if types.CompareIPNet(exp, nw) {
			found = true
			break
		}
	}

	if !found {
		t.Fatalf("Found unexpected granular network %s", nw)
	}

	// Add iface and ssert returned address on request
	createInterface(t, "test", "172.17.42.1/16")

	_, exp, err := net.ParseCIDR("172.18.0.0/16")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}
}
示例#5
0
func TestPredefinedPool(t *testing.T) {
	a, err := getAllocator()
	if err != nil {
		t.Fatal(err)
	}

	if _, err := a.getPredefinedPool("blue", false); err == nil {
		t.Fatalf("Expected failure for non default addr space")
	}

	exp, err := ipamutils.FindAvailableNetwork(a.predefined[localAddressSpace])
	if err != nil {
		t.Fatal(err)
	}

	nw, err := a.getPredefinedPool(localAddressSpace, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(nw, exp) {
		t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
	}

	pid, nw, _, err := a.RequestPool(localAddressSpace, exp.String(), "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(nw, exp) {
		t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
	}

	nw2, err := a.getPredefinedPool(localAddressSpace, false)
	if err != nil {
		t.Fatal(err)
	}
	if types.CompareIPNet(nw, nw2) {
		t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
	}

	if err := a.ReleasePool(pid); err != nil {
		t.Fatal(err)
	}

	nw, err = a.getPredefinedPool(localAddressSpace, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(nw, exp) {
		t.Fatalf("Unexpected default network returned: %s. Expected %s", nw, exp)
	}
}
示例#6
0
func TestPoolDataMarshal(t *testing.T) {
	_, nw, err := net.ParseCIDR("172.28.30.1/24")
	if err != nil {
		t.Fatal(err)
	}

	p := &PoolData{
		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
		Pool:      nw,
		Range:     &AddressRange{Sub: &net.IPNet{IP: net.IP{172, 28, 20, 0}, Mask: net.IPMask{255, 255, 255, 0}}, Start: 0, End: 255},
		RefCount:  4,
	}

	ba, err := json.Marshal(p)
	if err != nil {
		t.Fatal(err)
	}
	var q PoolData
	err = json.Unmarshal(ba, &q)
	if err != nil {
		t.Fatal(err)
	}

	if p.ParentKey != q.ParentKey || !types.CompareIPNet(p.Range.Sub, q.Range.Sub) ||
		p.Range.Start != q.Range.Start || p.Range.End != q.Range.End || p.RefCount != q.RefCount ||
		!types.CompareIPNet(p.Pool, q.Pool) {
		t.Fatalf("\n%#v\n%#v", p, &q)
	}

	p = &PoolData{
		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
		Pool:      nw,
		RefCount:  4,
	}

	ba, err = json.Marshal(p)
	if err != nil {
		t.Fatal(err)
	}
	err = json.Unmarshal(ba, &q)
	if err != nil {
		t.Fatal(err)
	}

	if q.Range != nil {
		t.Fatalf("Unexpected Range")
	}
}
示例#7
0
func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) error {
	// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
	addrv4, addrsv6, err := i.addresses()
	if err != nil {
		return fmt.Errorf("Failed to verify ip addresses: %v", err)
	}

	// Verify that the bridge does have an IPv4 address.
	if addrv4.IPNet == nil {
		return &ErrNoIPAddr{}
	}

	// Verify that the bridge IPv4 address matches the requested configuration.
	if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
		return &IPv4AddrNoMatchError{IP: addrv4.IP, CfgIP: config.AddressIPv4.IP}
	}

	// Verify that one of the bridge IPv6 addresses matches the requested
	// configuration.
	if config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
		return (*IPv6AddrNoMatchError)(bridgeIPv6)
	}

	// Release any residual IPv6 address that might be there because of older daemon instances
	for _, addrv6 := range addrsv6 {
		if addrv6.IP.IsGlobalUnicast() && !types.CompareIPNet(addrv6.IPNet, i.bridgeIPv6) {
			if err := i.nlh.AddrDel(i.Link, &addrv6); err != nil {
				log.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
			}
		}
	}

	return nil
}
示例#8
0
func TestPoolRequest(t *testing.T) {
	a := allocator{}

	pid, pool, _, err := a.RequestPool(defaultAS, "", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(defaultPool, pool) {
		t.Fatalf("Unexpected pool returned. Expected %v. Got: %v", defaultPool, pool)
	}
	if pid != defaultPoolID {
		t.Fatalf("Unexpected pool id returned. Expected: %s. Got: %s", defaultPoolID, pid)
	}

	_, _, _, err = a.RequestPool("default", "", "", nil, false)
	if err == nil {
		t.Fatalf("Unexpected success")
	}

	_, _, _, err = a.RequestPool(defaultAS, "192.168.0.0/16", "", nil, false)
	if err == nil {
		t.Fatalf("Unexpected success")
	}

	_, _, _, err = a.RequestPool(defaultAS, "", "192.168.0.0/24", nil, false)
	if err == nil {
		t.Fatalf("Unexpected success")
	}

	_, _, _, err = a.RequestPool(defaultAS, "", "", nil, true)
	if err == nil {
		t.Fatalf("Unexpected success")
	}
}
示例#9
0
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
	addrv4List, _, err := i.addresses()
	if err != nil {
		return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
	}

	addrv4, _ := selectIPv4Address(addrv4List, config.AddressIPv4)

	if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
		if addrv4.IPNet != nil {
			if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil {
				return fmt.Errorf("failed to remove current ip address from bridge: %v", err)
			}
		}
		log.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
		if err := i.nlh.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
			return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err}
		}
	}

	// Store bridge network and default gateway
	i.bridgeIPv4 = config.AddressIPv4
	i.gatewayIPv4 = config.AddressIPv4.IP

	return nil
}
示例#10
0
func TestPredefinedPool(t *testing.T) {
	a, err := getAllocator()
	if err != nil {
		t.Fatal(err)
	}

	if _, err := a.getPredefinedPool("blue", false); err == nil {
		t.Fatalf("Expected failure for non default addr space")
	}

	pid, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}

	nw2, err := a.getPredefinedPool(localAddressSpace, false)
	if err != nil {
		t.Fatal(err)
	}
	if types.CompareIPNet(nw, nw2) {
		t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
	}

	if err := a.ReleasePool(pid); err != nil {
		t.Fatal(err)
	}
}
func TestIpamReleaseOnNetDriverFailures(t *testing.T) {
	if !testutils.IsRunningInContainer() {
		defer testutils.SetupTestOSContext(t)()
	}

	cfgOptions, err := OptionBoltdbWithRandomDBFile()
	c, err := New(cfgOptions...)
	if err != nil {
		t.Fatal(err)
	}
	defer c.Stop()

	cc := c.(*controller)
	bd := badDriver{failNetworkCreation: true}
	cc.drivers[badDriverName] = &driverData{driver: &bd, capability: driverapi.Capability{DataScope: datastore.LocalScope}}

	// 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)
	if _, err := c.NewNetwork(badDriverName, "badnet1", ipamOpt); err == nil {
		t.Fatalf("bad network driver should have failed network creation")
	}

	gnw, err := c.NewNetwork("bridge", "goodnet1", ipamOpt)
	if err != nil {
		t.Fatal(err)
	}
	gnw.Delete()

	// Now check whether ipam release works on endpoint creation failure
	bd.failNetworkCreation = false
	bnw, err := c.NewNetwork(badDriverName, "badnet2", ipamOpt)
	if err != nil {
		t.Fatal(err)
	}
	defer bnw.Delete()

	if _, err := bnw.CreateEndpoint("ep0"); err == nil {
		t.Fatalf("bad network driver should have failed endpoint creation")
	}

	// 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)
	gnw, err = c.NewNetwork("bridge", "goodnet2", ipamOpt2)
	if err != nil {
		t.Fatal(err)
	}
	defer gnw.Delete()

	ep, err := gnw.CreateEndpoint("ep1")
	if err != nil {
		t.Fatal(err)
	}
	defer ep.Delete()

	expectedIP, _ := types.ParseCIDR("10.34.0.1/16")
	if !types.CompareIPNet(ep.Info().Iface().Address(), expectedIP) {
		t.Fatalf("Ipam release must have failed, endpoint has unexpected address: %v", ep.Info().Iface().Address())
	}
}
示例#12
0
func TestSubnetsMarshal(t *testing.T) {
	a, err := getAllocator()
	if err != nil {
		t.Fatal(err)
	}
	pid0, _, _, err := a.RequestPool(localAddressSpace, "192.168.0.0/16", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	pid1, _, _, err := a.RequestPool(localAddressSpace, "192.169.0.0/16", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	_, _, err = a.RequestAddress(pid0, nil, nil)
	if err != nil {
		t.Fatal(err)
	}

	cfg, err := a.getAddrSpace(localAddressSpace)
	if err != nil {
		t.Fatal(err)
	}

	ba := cfg.Value()
	if err := cfg.SetValue(ba); err != nil {
		t.Fatal(err)
	}

	expIP := &net.IPNet{IP: net.IP{192, 168, 0, 2}, Mask: net.IPMask{255, 255, 0, 0}}
	ip, _, err := a.RequestAddress(pid0, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expIP, ip) {
		t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
	}

	expIP = &net.IPNet{IP: net.IP{192, 169, 0, 1}, Mask: net.IPMask{255, 255, 0, 0}}
	ip, _, err = a.RequestAddress(pid1, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expIP, ip) {
		t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
	}
}
示例#13
0
func compareIPNets(t *testing.T, kind string, shouldBe string, supplied net.IPNet) {
	_, net, _ := net.ParseCIDR(shouldBe)
	if net == nil {
		t.Fatalf(`Invalid IP network to test against: "%s"`, shouldBe)
	}
	if !types.CompareIPNet(net, &supplied) {
		t.Fatalf(`%s IP networks are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
	}
}
func compareIpamInfoList(listA, listB []*IpamInfo) bool {
	var a, b *IpamInfo
	if len(listA) != len(listB) {
		return false
	}
	for i := 0; i < len(listA); i++ {
		a = listA[i]
		b = listB[i]
		if a.PoolID != b.PoolID || !compareStringMaps(a.Meta, b.Meta) ||
			!types.CompareIPNet(a.Gateway, b.Gateway) ||
			a.AddressSpace != b.AddressSpace ||
			!types.CompareIPNet(a.Pool, b.Pool) ||
			!compareAddresses(a.AuxAddresses, b.AuxAddresses) {
			return false
		}
	}
	return true
}
示例#15
0
func TestNetworkRequest(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	ipamutils.InitNetworks()

	_, exp, err := net.ParseCIDR("172.17.0.0/16")
	if err != nil {
		t.Fatal(err)
	}

	nw, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}

	_, exp, err = net.ParseCIDR("10.0.0.0/24")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedGranularNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}

	// Add iface and ssert returned address on request
	createInterface(t, "test", "172.17.42.1/16")

	_, exp, err = net.ParseCIDR("172.18.0.0/16")
	if err != nil {
		t.Fatal(err)
	}
	nw, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(exp, nw) {
		t.Fatalf("exected %s. got %s", exp, nw)
	}
}
func compareNwLists(a, b []*net.IPNet) bool {
	if len(a) != len(b) {
		return false
	}
	for k := range a {
		if !types.CompareIPNet(a[k], b[k]) {
			return false
		}
	}
	return true
}
func compareAddresses(a, b map[string]*net.IPNet) bool {
	if len(a) != len(b) {
		return false
	}
	if len(a) > 0 {
		for k := range a {
			if !types.CompareIPNet(a[k], b[k]) {
				return false
			}
		}
	}
	return true
}
// Testing IPV6 from MAC address
func TestBridgeIpv6FromMac(t *testing.T) {
	if !testutils.IsRunningInContainer() {
		defer testutils.SetupTestOSContext(t)()
	}

	netOption := options.Generic{
		netlabel.GenericData: options.Generic{
			"BridgeName":         "testipv6mac",
			"EnableICC":          true,
			"EnableIPMasquerade": true,
		},
	}
	ipamV4ConfList := []*libnetwork.IpamConf{{PreferredPool: "192.168.100.0/24", Gateway: "192.168.100.1"}}
	ipamV6ConfList := []*libnetwork.IpamConf{{PreferredPool: "fe90::/64", Gateway: "fe90::22"}}

	network, err := controller.NewNetwork(bridgeNetType, "testipv6mac", "",
		libnetwork.NetworkOptionGeneric(netOption),
		libnetwork.NetworkOptionEnableIPv6(true),
		libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4ConfList, ipamV6ConfList, nil),
		libnetwork.NetworkOptionDeferIPv6Alloc(true))
	if err != nil {
		t.Fatal(err)
	}

	mac := net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
	epOption := options.Generic{netlabel.MacAddress: mac}

	ep, err := network.CreateEndpoint("testep", libnetwork.EndpointOptionGeneric(epOption))
	if err != nil {
		t.Fatal(err)
	}

	iface := ep.Info().Iface()
	if !bytes.Equal(iface.MacAddress(), mac) {
		t.Fatalf("Unexpected mac address: %v", iface.MacAddress())
	}

	ip, expIP, _ := net.ParseCIDR("fe90::aabb:ccdd:eeff/64")
	expIP.IP = ip
	if !types.CompareIPNet(expIP, iface.AddressIPv6()) {
		t.Fatalf("Expected %v. Got: %v", expIP, iface.AddressIPv6())
	}

	if err := ep.Delete(false); err != nil {
		t.Fatal(err)
	}

	if err := network.Delete(); err != nil {
		t.Fatal(err)
	}
}
示例#19
0
// Equal checks if this instance of Interface is equal to the passed one
func (i *Interface) Equal(o *Interface) bool {
	if i == o {
		return true
	}

	if o == nil {
		return false
	}

	if i.SrcName != o.SrcName || i.DstName != o.DstName {
		return false
	}

	if !types.CompareIPNet(i.Address, o.Address) {
		return false
	}

	if !types.CompareIPNet(i.AddressIPv6, o.AddressIPv6) {
		return false
	}

	return true
}
示例#20
0
func TestRequestReleaseAddressFromSubPool(t *testing.T) {
	a, err := getAllocator()
	if err != nil {
		t.Fatal(err)
	}
	a.addrSpace2Configs["rosso"] = a.addrSpace2Configs[localAddressSpace]

	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
	if err != nil {
		t.Fatal(err)
	}

	var ip *net.IPNet
	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
	for err == nil {
		var c *net.IPNet
		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
			ip = c
		}
	}
	if err != ipamapi.ErrNoAvailableIPs {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expected, ip) {
		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
	}
	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
		t.Fatal(err)
	}
	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(rp, ip) {
		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
	}

	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
	for err == nil {
		var c *net.IPNet
		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
			ip = c
		}
	}
	if err != ipamapi.ErrNoAvailableIPs {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expected, ip) {
		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
	}
	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
		t.Fatal(err)
	}
	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(rp, ip) {
		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
	}
}
示例#21
0
func TestRemoteDriver(t *testing.T) {
	var plugin = "test-net-driver"

	ep := &testEndpoint{
		t:              t,
		src:            "vethsrc",
		dst:            "vethdst",
		address:        "192.168.5.7/16",
		addressIPv6:    "2001:DB8::5:7/48",
		macAddress:     "ab:cd:ef:ee:ee:ee",
		gateway:        "192.168.0.1",
		gatewayIPv6:    "2001:DB8::1",
		hostsPath:      "/here/comes/the/host/path",
		resolvConfPath: "/there/goes/the/resolv/conf",
		destination:    "10.0.0.0/8",
		nextHop:        "10.0.0.1",
		routeType:      1,
	}

	mux := http.NewServeMux()
	defer setupPlugin(t, plugin, mux)()

	var networkID string

	handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
		return map[string]interface{}{
			"Scope": "global",
		}
	})
	handle(t, mux, "CreateNetwork", func(msg map[string]interface{}) interface{} {
		nid := msg["NetworkID"]
		var ok bool
		if networkID, ok = nid.(string); !ok {
			t.Fatal("RPC did not include network ID string")
		}
		return map[string]interface{}{}
	})
	handle(t, mux, "DeleteNetwork", func(msg map[string]interface{}) interface{} {
		if nid, ok := msg["NetworkID"]; !ok || nid != networkID {
			t.Fatal("Network ID missing or does not match that created")
		}
		return map[string]interface{}{}
	})
	handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
		iface := map[string]interface{}{
			"MacAddress":  ep.macAddress,
			"Address":     ep.address,
			"AddressIPv6": ep.addressIPv6,
		}
		return map[string]interface{}{
			"Interface": iface,
		}
	})
	handle(t, mux, "Join", func(msg map[string]interface{}) interface{} {
		options := msg["Options"].(map[string]interface{})
		foo, ok := options["foo"].(string)
		if !ok || foo != "fooValue" {
			t.Fatalf("Did not receive expected foo string in request options: %+v", msg)
		}
		return map[string]interface{}{
			"Gateway":        ep.gateway,
			"GatewayIPv6":    ep.gatewayIPv6,
			"HostsPath":      ep.hostsPath,
			"ResolvConfPath": ep.resolvConfPath,
			"InterfaceName": map[string]interface{}{
				"SrcName":   ep.src,
				"DstPrefix": ep.dst,
			},
			"StaticRoutes": []map[string]interface{}{
				{
					"Destination": ep.destination,
					"RouteType":   ep.routeType,
					"NextHop":     ep.nextHop,
				},
			},
		}
	})
	handle(t, mux, "Leave", func(msg map[string]interface{}) interface{} {
		return map[string]string{}
	})
	handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
		return map[string]interface{}{}
	})
	handle(t, mux, "EndpointOperInfo", func(msg map[string]interface{}) interface{} {
		return map[string]interface{}{
			"Value": map[string]string{
				"Arbitrary": "key",
				"Value":     "pairs?",
			},
		}
	})
	handle(t, mux, "DiscoverNew", func(msg map[string]interface{}) interface{} {
		return map[string]string{}
	})
	handle(t, mux, "DiscoverDelete", func(msg map[string]interface{}) interface{} {
		return map[string]interface{}{}
	})

	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
	if err != nil {
		t.Fatal(err)
	}

	d := newDriver(plugin, p.Client)
	if d.Type() != plugin {
		t.Fatal("Driver type does not match that given")
	}

	c, err := d.(*driver).getCapabilities()
	if err != nil {
		t.Fatal(err)
	} else if c.DataScope != datastore.GlobalScope {
		t.Fatalf("get capability '%s', expecting 'global'", c.DataScope)
	}

	netID := "dummy-network"
	err = d.CreateNetwork(netID, map[string]interface{}{}, nil, nil, nil)
	if err != nil {
		t.Fatal(err)
	}

	endID := "dummy-endpoint"
	ifInfo := &testEndpoint{}
	err = d.CreateEndpoint(netID, endID, ifInfo, map[string]interface{}{})
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(ep.MacAddress(), ifInfo.MacAddress()) || !types.CompareIPNet(ep.Address(), ifInfo.Address()) ||
		!types.CompareIPNet(ep.AddressIPv6(), ifInfo.AddressIPv6()) {
		t.Fatalf("Unexpected InterfaceInfo data. Expected (%s, %s, %s). Got (%v, %v, %v)",
			ep.MacAddress(), ep.Address(), ep.AddressIPv6(),
			ifInfo.MacAddress(), ifInfo.Address(), ifInfo.AddressIPv6())
	}

	joinOpts := map[string]interface{}{"foo": "fooValue"}
	err = d.Join(netID, endID, "sandbox-key", ep, joinOpts)
	if err != nil {
		t.Fatal(err)
	}
	if _, err = d.EndpointOperInfo(netID, endID); err != nil {
		t.Fatal(err)
	}
	if err = d.Leave(netID, endID); err != nil {
		t.Fatal(err)
	}
	if err = d.DeleteEndpoint(netID, endID); err != nil {
		t.Fatal(err)
	}
	if err = d.DeleteNetwork(netID); err != nil {
		t.Fatal(err)
	}

	data := discoverapi.NodeDiscoveryData{
		Address: "192.168.1.1",
	}
	if err = d.DiscoverNew(discoverapi.NodeDiscovery, data); err != nil {
		t.Fatal(err)
	}
	if err = d.DiscoverDelete(discoverapi.NodeDiscovery, data); err != nil {
		t.Fatal(err)
	}
}
func TestWindowsIPAM(t *testing.T) {
	a := &allocator{}
	requestPool, _ := types.ParseCIDR("192.168.0.0/16")
	requestAddress := net.ParseIP("192.168.1.1")

	pid, pool, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(defaultPool, pool) ||
		pid != pool.String() {
		t.Fatalf("Unexpected data returned. Expected %v : %s. Got: %v : %s", defaultPool, pid, pool, pool.String())
	}

	pid, pool, _, err = a.RequestPool(localAddressSpace, requestPool.String(), "", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(requestPool, pool) ||
		pid != requestPool.String() {
		t.Fatalf("Unexpected data returned. Expected %v : %s. Got: %v : %s", requestPool, requestPool.String(), pool, pool.String())
	}

	_, _, _, err = a.RequestPool(localAddressSpace, requestPool.String(), requestPool.String(), nil, false)
	if err == nil {
		t.Fatal("Unexpected success for subpool request")
	}

	_, _, _, err = a.RequestPool(localAddressSpace, requestPool.String(), "", nil, true)
	if err == nil {
		t.Fatal("Unexpected success for v6 request")
	}

	err = a.ReleasePool(requestPool.String())
	if err != nil {
		t.Fatal(err)
	}

	ip, _, err := a.RequestAddress(requestPool.String(), nil, map[string]string{})
	if err != nil {
		t.Fatal(err)
	}

	if !types.CompareIPNet(ip, requestPool) {
		t.Fatalf("Unexpected data returned. Expected %v . Got: %v ", requestPool, ip)
	}

	ip, _, err = a.RequestAddress(requestPool.String(), requestAddress, map[string]string{})
	if err != nil {
		t.Fatal(err)
	}

	if !ip.IP.Equal(requestAddress) {
		t.Fatalf("Unexpected data returned. Expected %v . Got: %v ", requestAddress, ip.IP)
	}

	err = a.ReleaseAddress(requestPool.String(), requestAddress)
	if err != nil {
		t.Fatal(err)
	}
}
示例#23
0
func runParallelTests(t *testing.T, instance int) {
	var err error

	t.Parallel()

	pTest := flag.Lookup("test.parallel")
	if pTest == nil {
		t.Skip("Skipped because test.parallel flag not set;")
	}
	numParallel, err := strconv.Atoi(pTest.Value.String())
	if err != nil {
		t.Fatal(err)
	}
	if numParallel < numInstances {
		t.Skip("Skipped because t.parallel was less than ", numInstances)
	}

	// The first instance creates the allocator, gives the start
	// and finally checks the pools each instance was assigned
	if instance == first {
		allocator, err = getAllocator()
		if err != nil {
			t.Fatal(err)
		}
		close(start)
	}

	if instance != first {
		select {
		case <-start:
		}

		instDone := make(chan struct{})
		done <- instDone
		defer close(instDone)

		if instance == last {
			defer close(done)
		}
	}

	_, pools[instance], _, err = allocator.RequestPool(localAddressSpace, "", "", nil, false)
	if err != nil {
		t.Fatal(err)
	}

	if instance == first {
		for instDone := range done {
			select {
			case <-instDone:
			}
		}
		// Now check each instance got a different pool
		for i := 0; i < numInstances; i++ {
			for j := i + 1; j < numInstances; j++ {
				if types.CompareIPNet(pools[i], pools[j]) {
					t.Fatalf("Instance %d and %d were given the same predefined pool: %v", i, j, pools)
				}
			}
		}
	}
}
示例#24
0
func TestCreateFullOptionsLabels(t *testing.T) {
	defer testutils.SetupTestOSContext(t)()
	d := newDriver()

	config := &configuration{
		EnableIPForwarding: true,
	}
	genericOption := make(map[string]interface{})
	genericOption[netlabel.GenericData] = config

	if err := d.configure(genericOption); err != nil {
		t.Fatalf("Failed to setup driver config: %v", err)
	}

	bndIPs := "127.0.0.1"
	nwV6s := "2100:2400:2600:2700:2800::/80"
	gwV6s := "2100:2400:2600:2700:2800::25/80"
	nwV6, _ := types.ParseCIDR(nwV6s)
	gwV6, _ := types.ParseCIDR(gwV6s)

	labels := map[string]string{
		BridgeName:          DefaultBridgeName,
		DefaultBridge:       "true",
		netlabel.EnableIPv6: "true",
		EnableICC:           "true",
		EnableIPMasquerade:  "true",
		DefaultBindingIP:    bndIPs,
	}

	netOption := make(map[string]interface{})
	netOption[netlabel.GenericData] = labels

	ipdList := getIPv4Data(t)
	ipd6List := []driverapi.IPAMData{
		driverapi.IPAMData{
			Pool: nwV6,
			AuxAddresses: map[string]*net.IPNet{
				DefaultGatewayV6AuxKey: gwV6,
			},
		},
	}

	err := d.CreateNetwork("dummy", netOption, ipdList, ipd6List)
	if err != nil {
		t.Fatalf("Failed to create bridge: %v", err)
	}

	nw, ok := d.networks["dummy"]
	if !ok {
		t.Fatalf("Cannot find dummy network in bridge driver")
	}

	if nw.config.BridgeName != DefaultBridgeName {
		t.Fatalf("incongruent name in bridge network")
	}

	if !nw.config.EnableIPv6 {
		t.Fatalf("incongruent EnableIPv6 in bridge network")
	}

	if !nw.config.EnableICC {
		t.Fatalf("incongruent EnableICC in bridge network")
	}

	if !nw.config.EnableIPMasquerade {
		t.Fatalf("incongruent EnableIPMasquerade in bridge network")
	}

	bndIP := net.ParseIP(bndIPs)
	if !bndIP.Equal(nw.config.DefaultBindingIP) {
		t.Fatalf("Unexpected: %v", nw.config.DefaultBindingIP)
	}

	if !types.CompareIPNet(nw.config.AddressIPv6, nwV6) {
		t.Fatalf("Unexpected: %v", nw.config.AddressIPv6)
	}

	if !gwV6.IP.Equal(nw.config.DefaultGatewayIPv6) {
		t.Fatalf("Unexpected: %v", nw.config.DefaultGatewayIPv6)
	}

	// In short here we are testing --fixed-cidr-v6 daemon option
	// plus --mac-address run option
	mac, _ := net.ParseMAC("aa:bb:cc:dd:ee:ff")
	epOptions := map[string]interface{}{netlabel.MacAddress: mac}
	te := newTestEndpoint(ipdList[0].Pool, 20)
	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
	if err != nil {
		t.Fatal(err)
	}

	if !nwV6.Contains(te.Interface().AddressIPv6().IP) {
		t.Fatalf("endpoint got assigned address outside of container network(%s): %s", nwV6.String(), te.Interface().AddressIPv6())
	}
	if te.Interface().AddressIPv6().IP.String() != "2100:2400:2600:2700:2800:aabb:ccdd:eeff" {
		t.Fatalf("Unexpected endpoint IPv6 address: %v", te.Interface().AddressIPv6().IP)
	}
}
示例#25
0
func TestRequestReleaseAddressFromSubPool(t *testing.T) {
	a, err := getAllocator()
	if err != nil {
		t.Fatal(err)
	}
	a.addrSpaces["rosso"] = &addrSpace{
		id:      dsConfigKey + "/" + "rosso",
		ds:      a.addrSpaces[localAddressSpace].ds,
		alloc:   a.addrSpaces[localAddressSpace].alloc,
		scope:   a.addrSpaces[localAddressSpace].scope,
		subnets: map[SubnetKey]*PoolData{},
	}

	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
	if err != nil {
		t.Fatal(err)
	}

	var ip *net.IPNet
	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
	for err == nil {
		var c *net.IPNet
		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
			ip = c
		}
	}
	if err != ipamapi.ErrNoAvailableIPs {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expected, ip) {
		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
	}
	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
		t.Fatal(err)
	}
	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(rp, ip) {
		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
	}

	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
	if err != nil {
		t.Fatal(err)
	}
	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
	for err == nil {
		var c *net.IPNet
		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
			ip = c
		}
	}
	if err != ipamapi.ErrNoAvailableIPs {
		t.Fatal(err)
	}
	if !types.CompareIPNet(expected, ip) {
		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
	}
	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
		t.Fatal(err)
	}
	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(rp, ip) {
		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
	}

	// Request any addresses from subpool after explicit address request
	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
	treExp, _ := types.ParseCIDR("10.2.2.1/16")
	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
		t.Fatal(err)
	}
	tre, _, err := a.RequestAddress(poolID, treExp.IP, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(tre, treExp) {
		t.Fatalf("Unexpected address: %v", tre)
	}

	uno, _, err := a.RequestAddress(poolID, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(uno, unoExp) {
		t.Fatalf("Unexpected address: %v", uno)
	}

	due, _, err := a.RequestAddress(poolID, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(due, dueExp) {
		t.Fatalf("Unexpected address: %v", due)
	}

	if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
		t.Fatal(err)
	}
	uno, _, err = a.RequestAddress(poolID, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(uno, unoExp) {
		t.Fatalf("Unexpected address: %v", uno)
	}

	if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
		t.Fatal(err)
	}
	tre, _, err = a.RequestAddress(poolID, nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if !types.CompareIPNet(tre, treExp) {
		t.Fatalf("Unexpected address: %v", tre)
	}
}
示例#26
0
func TestEndpointMarshalling(t *testing.T) {
	ip1, _ := types.ParseCIDR("172.22.0.9/16")
	ip2, _ := types.ParseCIDR("2001:db8::9")
	mac, _ := net.ParseMAC("ac:bd:24:57:66:77")
	e := &bridgeEndpoint{
		id:         "d2c015a1fe5930650cbcd50493efba0500bcebd8ee1f4401a16319f8a567de33",
		nid:        "ee33fbb43c323f1920b6b35a0101552ac22ede960d0e5245e9738bccc68b2415",
		addr:       ip1,
		addrv6:     ip2,
		macAddress: mac,
		srcName:    "veth123456",
		config:     &endpointConfiguration{MacAddress: mac},
		containerConfig: &containerConfiguration{
			ParentEndpoints: []string{"one", "due", "three"},
			ChildEndpoints:  []string{"four", "five", "six"},
		},
		extConnConfig: &connectivityConfiguration{
			ExposedPorts: []types.TransportPort{
				{
					Proto: 6,
					Port:  uint16(18),
				},
			},
			PortBindings: []types.PortBinding{
				{
					Proto:       6,
					IP:          net.ParseIP("17210.33.9.56"),
					Port:        uint16(18),
					HostPort:    uint16(3000),
					HostPortEnd: uint16(14000),
				},
			},
		},
		portMapping: []types.PortBinding{
			{
				Proto:       17,
				IP:          net.ParseIP("172.33.9.56"),
				Port:        uint16(99),
				HostIP:      net.ParseIP("10.10.100.2"),
				HostPort:    uint16(9900),
				HostPortEnd: uint16(10000),
			},
			{
				Proto:       6,
				IP:          net.ParseIP("171.33.9.56"),
				Port:        uint16(55),
				HostIP:      net.ParseIP("10.11.100.2"),
				HostPort:    uint16(5500),
				HostPortEnd: uint16(55000),
			},
		},
	}

	b, err := json.Marshal(e)
	if err != nil {
		t.Fatal(err)
	}

	ee := &bridgeEndpoint{}
	err = json.Unmarshal(b, ee)
	if err != nil {
		t.Fatal(err)
	}

	if e.id != ee.id || e.nid != ee.nid || e.srcName != ee.srcName || !bytes.Equal(e.macAddress, ee.macAddress) ||
		!types.CompareIPNet(e.addr, ee.addr) || !types.CompareIPNet(e.addrv6, ee.addrv6) ||
		!compareEpConfig(e.config, ee.config) ||
		!compareContainerConfig(e.containerConfig, ee.containerConfig) ||
		!compareConnConfig(e.extConnConfig, ee.extConnConfig) ||
		!compareBindings(e.portMapping, ee.portMapping) {
		t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%#v\nDecoded:\n%#v", e, ee)
	}
}