pulled in koelkers test changes
This commit is contained in:
4
doc/build/html/.buildinfo
vendored
4
doc/build/html/.buildinfo
vendored
@@ -1,4 +0,0 @@
|
||||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 2a2fe6198f4be4a4d6f289b09d16d74a
|
||||
tags: fbb0d17656682115ca4d033fb2f83ba1
|
||||
39
doc/source/devref/multinic.rst
Normal file
39
doc/source/devref/multinic.rst
Normal file
@@ -0,0 +1,39 @@
|
||||
MultiNic
|
||||
========
|
||||
|
||||
What is it
|
||||
----------
|
||||
|
||||
Multinic allows an instance to have more than one vif connected to it. Each vif is representative of a separate network with its own IP block.
|
||||
|
||||
Managers
|
||||
--------
|
||||
|
||||
Each of the network managers are designed to run independently of the compute manager. They expose a common API for the compute manager to call to determine and configure the network(s) for an instance. Direct calls to either the network api or especially the DB should be avoided by the virt layers.
|
||||
|
||||
On startup a manager looks in the networks table for networks it is assigned and configures itself to support that network. Using the periodic task, they will claim new networks that have no host set. Only one network per network-host will be claimed at a time. This allows for psuedo-loadbalancing if there are multiple network-hosts running.
|
||||
|
||||
Flat Manager
|
||||
------------
|
||||
|
||||
.. image:: /images/multinic_flat.png
|
||||
|
||||
The Flat manager is most similar to a traditional switched network environment. It assumes that the IP routing, DNS, DHCP (possibly) and bridge creation is handled by something else. That is it makes no attempt to configure any of this. It does keep track of a range of IPs for the instances that are connected to the network to be allocated.
|
||||
|
||||
Each instance will get a fixed IP from each network's pool. The guest operating system may be configured to gather this information through an agent or by the hypervisor injecting the files, or it may ignore it completely and come up with only a layer 2 connection.
|
||||
|
||||
Flat manager requires at least one nova-network process running that will listen to the API queue and respond to queries. It does not need to sit on any of the networks but it does keep track of the IPs it hands out to instances.
|
||||
|
||||
FlatDHCP Manager
|
||||
----------------
|
||||
|
||||
.. image:: /images/multinic_dhcp.png
|
||||
|
||||
FlatDHCP manager builds on the the Flat manager adding dnsmask (DNS and DHCP) and radvd (Router Advertisement) servers on the bridge for that network. The services run on the host that is assigned to that nework. The FlatDHCP manager will create its bridge as specified when the network was created on the network-host when the network host starts up or when a new network gets allocated to that host. Compute nodes will also create the bridges as necessary and connect instance VIFs to them.
|
||||
|
||||
VLAN Manager
|
||||
------------
|
||||
|
||||
.. image:: /images/multinic_vlan.png
|
||||
|
||||
The VLAN manager sets up forwarding to/from a cloudpipe instance in addition to providing dnsmask (DNS and DHCP) and radvd (Router Advertisement) services for each network. The manager will create its bridge as specified when the network was created on the network-host when the network host starts up or when a new network gets allocated to that host. Compute nodes will also create the bridges as necessary and conenct instance VIFs to them.
|
||||
BIN
doc/source/image_src/multinic_1.odg
Normal file
BIN
doc/source/image_src/multinic_1.odg
Normal file
Binary file not shown.
BIN
doc/source/image_src/multinic_2.odg
Normal file
BIN
doc/source/image_src/multinic_2.odg
Normal file
Binary file not shown.
BIN
doc/source/image_src/multinic_3.odg
Normal file
BIN
doc/source/image_src/multinic_3.odg
Normal file
Binary file not shown.
BIN
doc/source/images/multinic_dhcp.png
Normal file
BIN
doc/source/images/multinic_dhcp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
doc/source/images/multinic_flat.png
Normal file
BIN
doc/source/images/multinic_flat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
doc/source/images/multinic_vlan.png
Normal file
BIN
doc/source/images/multinic_vlan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
@@ -15,22 +15,226 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import db
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova.tests.network import base
|
||||
from nova import test
|
||||
from nova.network import manager as network_manager
|
||||
|
||||
|
||||
import mox
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
LOG = logging.getLogger('nova.tests.network')
|
||||
|
||||
|
||||
class FlatNetworkTestCase(base.NetworkTestCase, base.TestFuncs):
|
||||
network_manager = 'nova.network.manager.FlatManager'
|
||||
HOST = "testhost"
|
||||
|
||||
|
||||
class FlatDHCPNetworkTestCase(base.NetworkTestCase, base.TestFuncs):
|
||||
network_manager = 'nova.network.manager.FlatDHCPManager'
|
||||
class FakeModel(dict):
|
||||
"""Represent a model from the db"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.update(kwargs)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self[name]
|
||||
|
||||
|
||||
class VlanNetworkTestCase(base.NetworkTestCase, base.TestFuncs):
|
||||
network_manager = 'nova.network.manager.VlanManager'
|
||||
networks = [{'id': 0,
|
||||
'label': 'test0',
|
||||
'injected': False,
|
||||
'cidr': '192.168.0.0/24',
|
||||
'cidr_v6': '2001:db8::/64',
|
||||
'gateway_v6': '2001:db8::1',
|
||||
'netmask_v6': '64',
|
||||
'netmask': '255.255.255.0',
|
||||
'bridge': 'fa0',
|
||||
'bridge_interface': 'fake_fa0',
|
||||
'gateway': '192.168.0.1',
|
||||
'broadcast': '192.168.0.255',
|
||||
'dns': '192.168.0.1',
|
||||
'vlan': None,
|
||||
'host': None,
|
||||
'project_id': 'fake_project',
|
||||
'vpn_public_address': '192.168.0.2'},
|
||||
{'id': 1,
|
||||
'label': 'test1',
|
||||
'injected': False,
|
||||
'cidr': '192.168.1.0/24',
|
||||
'cidr_v6': '2001:db9::/64',
|
||||
'gateway_v6': '2001:db9::1',
|
||||
'netmask_v6': '64',
|
||||
'netmask': '255.255.255.0',
|
||||
'bridge': 'fa1',
|
||||
'bridge_interface': 'fake_fa1',
|
||||
'gateway': '192.168.1.1',
|
||||
'broadcast': '192.168.1.255',
|
||||
'dns': '192.168.0.1',
|
||||
'vlan': None,
|
||||
'host': None,
|
||||
'project_id': 'fake_project',
|
||||
'vpn_public_address': '192.168.1.2'}]
|
||||
|
||||
|
||||
fixed_ips = [{'id': 0,
|
||||
'network_id': 0,
|
||||
'address': '192.168.0.100',
|
||||
'instance_id': 0,
|
||||
'allocated': False,
|
||||
'virtual_interface_id': 0,
|
||||
'floating_ips': []},
|
||||
{'id': 0,
|
||||
'network_id': 1,
|
||||
'address': '192.168.1.100',
|
||||
'instance_id': 0,
|
||||
'allocated': False,
|
||||
'virtual_interface_id': 0,
|
||||
'floating_ips': []}]
|
||||
|
||||
|
||||
flavor = {'id': 0,
|
||||
'rxtx_cap': 3}
|
||||
|
||||
|
||||
floating_ip_fields = {'id': 0,
|
||||
'address': '192.168.10.100',
|
||||
'fixed_ip_id': 0,
|
||||
'project_id': None,
|
||||
'auto_assigned': False}
|
||||
|
||||
vifs = [{'id': 0,
|
||||
'address': 'DE:AD:BE:EF:00:00',
|
||||
'network_id': 0,
|
||||
'network': FakeModel(**networks[0]),
|
||||
'instance_id': 0},
|
||||
{'id': 1,
|
||||
'address': 'DE:AD:BE:EF:00:01',
|
||||
'network_id': 1,
|
||||
'network': FakeModel(**networks[1]),
|
||||
'instance_id': 0}]
|
||||
|
||||
|
||||
class FlatNetworkTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(FlatNetworkTestCase, self).setUp()
|
||||
self.network = network_manager.FlatManager(host=HOST)
|
||||
self.network.db = db
|
||||
|
||||
def test_set_network_hosts(self):
|
||||
self.mox.StubOutWithMock(db, 'network_get_all')
|
||||
self.mox.StubOutWithMock(db, 'network_set_host')
|
||||
self.mox.StubOutWithMock(db, 'network_update')
|
||||
|
||||
db.network_get_all(mox.IgnoreArg()).AndReturn([networks[0]])
|
||||
db.network_set_host(mox.IgnoreArg(),
|
||||
networks[0]['id'],
|
||||
mox.IgnoreArg()).AndReturn(HOST)
|
||||
db.network_update(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.network.set_network_hosts(None)
|
||||
|
||||
def test_get_instance_nw_info(self):
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_get_by_instance')
|
||||
self.mox.StubOutWithMock(db, 'virtual_interface_get_by_instance')
|
||||
self.mox.StubOutWithMock(db, 'instance_type_get_by_id')
|
||||
|
||||
db.fixed_ip_get_by_instance(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(fixed_ips)
|
||||
db.virtual_interface_get_by_instance(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(vifs)
|
||||
db.instance_type_get_by_id(mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn(flavor)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
nw_info = self.network.get_instance_nw_info(None, 0, 0)
|
||||
|
||||
self.assertTrue(nw_info)
|
||||
|
||||
for i, nw in enumerate(nw_info):
|
||||
i8 = i + 8
|
||||
check = {'bridge': 'fa%s' % i,
|
||||
'cidr': '192.168.%s.0/24' % i,
|
||||
'cidr_v6': '2001:db%s::/64' % i8,
|
||||
'id': i,
|
||||
'injected': 'DONTCARE'}
|
||||
|
||||
self.assertDictMatch(nw[0], check)
|
||||
|
||||
check = {'broadcast': '192.168.%s.255' % i,
|
||||
'dns': 'DONTCARE',
|
||||
'gateway': '192.168.%s.1' % i,
|
||||
'gateway6': '2001:db%s::1' % i8,
|
||||
'ip6s': 'DONTCARE',
|
||||
'ips': 'DONTCARE',
|
||||
'label': 'test%s' % i,
|
||||
'mac': 'DE:AD:BE:EF:00:0%s' % i,
|
||||
'rxtx_cap': 'DONTCARE'}
|
||||
self.assertDictMatch(nw[1], check)
|
||||
|
||||
check = [{'enabled': 'DONTCARE',
|
||||
'ip': '2001:db%s::dcad:beff:feef:%s' % (i8, i),
|
||||
'netmask': '64'}]
|
||||
self.assertDictListMatch(nw[1]['ip6s'], check)
|
||||
|
||||
check = [{'enabled': '1',
|
||||
'ip': '192.168.%s.100' % i,
|
||||
'netmask': '255.255.255.0'}]
|
||||
self.assertDictListMatch(nw[1]['ips'], check)
|
||||
|
||||
|
||||
class VlanNetworkTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(VlanNetworkTestCase, self).setUp()
|
||||
self.network = network_manager.VlanManager(host=HOST)
|
||||
self.network.db = db
|
||||
|
||||
def test_vpn_allocate_fixed_ip(self):
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_associate')
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_update')
|
||||
self.mox.StubOutWithMock(db,
|
||||
'virtual_interface_get_by_instance_and_network')
|
||||
|
||||
db.fixed_ip_associate(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn('192.168.0.1')
|
||||
db.fixed_ip_update(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
network = dict(networks[0])
|
||||
network['vpn_private_address'] = '192.168.0.2'
|
||||
self.network.allocate_fixed_ip(None, 0, network, vpn=True)
|
||||
|
||||
def test_allocate_fixed_ip(self):
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
|
||||
self.mox.StubOutWithMock(db, 'fixed_ip_update')
|
||||
self.mox.StubOutWithMock(db,
|
||||
'virtual_interface_get_by_instance_and_network')
|
||||
|
||||
db.fixed_ip_associate_pool(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg()).AndReturn('192.168.0.1')
|
||||
db.fixed_ip_update(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn({'id': 0})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
network = dict(networks[0])
|
||||
network['vpn_private_address'] = '192.168.0.2'
|
||||
self.network.allocate_fixed_ip(None, 0, network)
|
||||
|
||||
def test_create_networks_too_big(self):
|
||||
self.assertRaises(ValueError, self.network.create_networks, None,
|
||||
num_networks=4094, vlan_start=1)
|
||||
|
||||
def test_create_networks_too_many(self):
|
||||
self.assertRaises(ValueError, self.network.create_networks, None,
|
||||
num_networks=100, vlan_start=1,
|
||||
cidr='192.168.0.1/24', network_size=100)
|
||||
|
||||
Reference in New Issue
Block a user