Add DHCP support to the QuantumManager and break apart dhcp/gateway
This introduces a new flag "quantum_use_dhcp=<boolean>" which indicates whether or not to enable dhcp for all of the networks. If it is set then we start dnsmasq (and provide it with the IP/MACs from Melange) similar to how this was done in linux_net before. Prior to this if you enabled dhcp then you would also get a gateway device.. some people may not want that so we now require that you specify the gateway when creating the network in order to end up with a device that will act as a gateway. If you're using Melange IPAM and you don't specify the gateway you still end up with one because it doesn't allow you to not have one. This lays the groundwork for the option of not having one in the future, at least :) Also, fix quantum/melange ipam interaction We now query for the subnets by net_id/vif_id instead of searching through all the blocks to find the right one. Both of the allocate and deallocate for instance calls are now using the vif_id -> network_id mapping instead of searching the quantum networks. get_port_by_attachment was also changed to take a net_id so that we don't have to search through all of the quantum networks to find the corresponding port. Change-Id: I6a84da35237b6c5f5cdee91ada92642103439a97
This commit is contained in:
parent
8c824fcc85
commit
9be8924403
@ -90,7 +90,8 @@ def init_leases(network_id):
|
||||
"""Get the list of hosts for a network."""
|
||||
ctxt = context.get_admin_context()
|
||||
network_ref = db.network_get(ctxt, network_id)
|
||||
return linux_net.get_dhcp_leases(ctxt, network_ref)
|
||||
network_manager = utils.import_object(FLAGS.network_manager)
|
||||
return network_manager.get_dhcp_leases(ctxt, network_ref)
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -727,6 +727,7 @@ class NetworkCommands(object):
|
||||
@args('--vpn', dest="vpn_start", help='vpn start')
|
||||
@args('--fixed_range_v6', dest="fixed_range_v6",
|
||||
help='IPv6 subnet (ex: fe80::/64')
|
||||
@args('--gateway', dest="gateway", help='gateway')
|
||||
@args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway')
|
||||
@args('--bridge', dest="bridge",
|
||||
metavar='<bridge>',
|
||||
@ -746,9 +747,10 @@ class NetworkCommands(object):
|
||||
help='Network interface priority')
|
||||
def create(self, label=None, fixed_range_v4=None, num_networks=None,
|
||||
network_size=None, multi_host=None, vlan_start=None,
|
||||
vpn_start=None, fixed_range_v6=None, gateway_v6=None,
|
||||
bridge=None, bridge_interface=None, dns1=None, dns2=None,
|
||||
project_id=None, priority=None, uuid=None):
|
||||
vpn_start=None, fixed_range_v6=None, gateway=None,
|
||||
gateway_v6=None, bridge=None, bridge_interface=None,
|
||||
dns1=None, dns2=None, project_id=None, priority=None,
|
||||
uuid=None):
|
||||
"""Creates fixed ips for host by range"""
|
||||
|
||||
# check for certain required inputs
|
||||
@ -811,6 +813,7 @@ class NetworkCommands(object):
|
||||
vlan_start=int(vlan_start),
|
||||
vpn_start=int(vpn_start),
|
||||
cidr_v6=fixed_range_v6,
|
||||
gateway=gateway,
|
||||
gateway_v6=gateway_v6,
|
||||
bridge=bridge,
|
||||
bridge_interface=bridge_interface,
|
||||
|
@ -63,6 +63,7 @@ def setup():
|
||||
num_networks=FLAGS.num_networks,
|
||||
network_size=FLAGS.network_size,
|
||||
cidr_v6=FLAGS.fixed_range_v6,
|
||||
gateway=FLAGS.gateway,
|
||||
gateway_v6=FLAGS.gateway_v6,
|
||||
bridge=FLAGS.flat_network_bridge,
|
||||
bridge_interface=bridge_interface,
|
||||
|
@ -206,7 +206,7 @@ class FlatNetworkTestCase(test.TestCase):
|
||||
is_admin=True)
|
||||
nets = self.network.create_networks(context_admin, 'fake',
|
||||
'192.168.0.0/24', False, 1,
|
||||
256, None, None, None, None)
|
||||
256, None, None, None, None, None)
|
||||
self.assertEqual(1, len(nets))
|
||||
network = nets[0]
|
||||
self.assertEqual(3, db.network_count_reserved_ips(context_admin,
|
||||
@ -697,7 +697,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
manager = fake_network.FakeNetworkManager()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.0.0/24',
|
||||
False, 1, 256, None, None, None,
|
||||
None)
|
||||
None, None)
|
||||
self.assertEqual(1, len(nets))
|
||||
cidrs = [str(net['cidr']) for net in nets]
|
||||
self.assertTrue('192.168.0.0/24' in cidrs)
|
||||
@ -706,7 +706,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
manager = fake_network.FakeNetworkManager()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.0.0/24',
|
||||
False, 2, 128, None, None, None,
|
||||
None)
|
||||
None, None)
|
||||
self.assertEqual(2, len(nets))
|
||||
cidrs = [str(net['cidr']) for net in nets]
|
||||
self.assertTrue('192.168.0.0/25' in cidrs)
|
||||
@ -721,7 +721,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
self.mox.ReplayAll()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.0.0/16',
|
||||
False, 4, 256, None, None, None,
|
||||
None)
|
||||
None, None)
|
||||
self.assertEqual(4, len(nets))
|
||||
cidrs = [str(net['cidr']) for net in nets]
|
||||
exp_cidrs = ['192.168.0.0/24', '192.168.1.0/24', '192.168.3.0/24',
|
||||
@ -740,7 +740,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
# ValueError: requested cidr (192.168.2.0/24) conflicts with
|
||||
# existing smaller cidr
|
||||
args = (None, 'fake', '192.168.2.0/24', False, 1, 256, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
|
||||
def test_validate_cidrs_split_smaller_cidr_in_use(self):
|
||||
@ -751,7 +751,8 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
'cidr': '192.168.2.0/25'}])
|
||||
self.mox.ReplayAll()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.0.0/16',
|
||||
False, 4, 256, None, None, None, None)
|
||||
False, 4, 256, None, None, None, None,
|
||||
None)
|
||||
self.assertEqual(4, len(nets))
|
||||
cidrs = [str(net['cidr']) for net in nets]
|
||||
exp_cidrs = ['192.168.0.0/24', '192.168.1.0/24', '192.168.3.0/24',
|
||||
@ -768,7 +769,8 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
'cidr': '192.168.2.9/29'}])
|
||||
self.mox.ReplayAll()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.2.0/24',
|
||||
False, 3, 32, None, None, None, None)
|
||||
False, 3, 32, None, None, None, None,
|
||||
None)
|
||||
self.assertEqual(3, len(nets))
|
||||
cidrs = [str(net['cidr']) for net in nets]
|
||||
exp_cidrs = ['192.168.2.32/27', '192.168.2.64/27', '192.168.2.96/27']
|
||||
@ -786,7 +788,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
manager.db.network_get_all(ctxt).AndReturn(in_use)
|
||||
self.mox.ReplayAll()
|
||||
args = (None, 'fake', '192.168.2.0/24', False, 3, 64, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
# ValueError: Not enough subnets avail to satisfy requested num_
|
||||
# networks - some subnets in requested range already
|
||||
# in use
|
||||
@ -795,7 +797,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
def test_validate_cidrs_one_in_use(self):
|
||||
manager = fake_network.FakeNetworkManager()
|
||||
args = (None, 'fake', '192.168.0.0/24', False, 2, 256, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
# ValueError: network_size * num_networks exceeds cidr size
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
|
||||
@ -808,13 +810,13 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
self.mox.ReplayAll()
|
||||
# ValueError: cidr already in use
|
||||
args = (None, 'fake', '192.168.0.0/24', False, 1, 256, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
|
||||
def test_validate_cidrs_too_many(self):
|
||||
manager = fake_network.FakeNetworkManager()
|
||||
args = (None, 'fake', '192.168.0.0/24', False, 200, 256, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
# ValueError: Not enough subnets avail to satisfy requested
|
||||
# num_networks
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
@ -822,7 +824,8 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
def test_validate_cidrs_split_partial(self):
|
||||
manager = fake_network.FakeNetworkManager()
|
||||
nets = manager.create_networks(None, 'fake', '192.168.0.0/16',
|
||||
False, 2, 256, None, None, None, None)
|
||||
False, 2, 256, None, None, None, None,
|
||||
None)
|
||||
returned_cidrs = [str(net['cidr']) for net in nets]
|
||||
self.assertTrue('192.168.0.0/24' in returned_cidrs)
|
||||
self.assertTrue('192.168.1.0/24' in returned_cidrs)
|
||||
@ -835,7 +838,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
manager.db.network_get_all(ctxt).AndReturn(fakecidr)
|
||||
self.mox.ReplayAll()
|
||||
args = (None, 'fake', '192.168.0.0/24', False, 1, 256, None, None,
|
||||
None, None)
|
||||
None, None, None)
|
||||
# ValueError: requested cidr (192.168.0.0/24) conflicts
|
||||
# with existing supernet
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
@ -846,7 +849,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
self.stubs.Set(manager, '_create_fixed_ips',
|
||||
self.fake_create_fixed_ips)
|
||||
args = [None, 'foo', cidr, None, 1, 256, 'fd00::/48', None, None,
|
||||
None]
|
||||
None, None, None]
|
||||
self.assertTrue(manager.create_networks(*args))
|
||||
|
||||
def test_create_networks_cidr_already_used(self):
|
||||
@ -857,7 +860,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
manager.db.network_get_all(ctxt).AndReturn(fakecidr)
|
||||
self.mox.ReplayAll()
|
||||
args = [None, 'foo', '192.168.0.0/24', None, 1, 256,
|
||||
'fd00::/48', None, None, None]
|
||||
'fd00::/48', None, None, None, None, None]
|
||||
self.assertRaises(ValueError, manager.create_networks, *args)
|
||||
|
||||
def test_create_networks_many(self):
|
||||
@ -866,7 +869,7 @@ class CommonNetworkTestCase(test.TestCase):
|
||||
self.stubs.Set(manager, '_create_fixed_ips',
|
||||
self.fake_create_fixed_ips)
|
||||
args = [None, 'foo', cidr, None, 10, 256, 'fd00::/48', None, None,
|
||||
None]
|
||||
None, None, None]
|
||||
self.assertTrue(manager.create_networks(*args))
|
||||
|
||||
def test_get_instance_uuids_by_ip_regex(self):
|
||||
|
@ -26,6 +26,8 @@ from nova.network.quantum import manager as quantum_manager
|
||||
from nova import test
|
||||
from nova import utils
|
||||
|
||||
import mox
|
||||
|
||||
LOG = logging.getLogger('nova.tests.quantum_network')
|
||||
|
||||
|
||||
@ -41,7 +43,7 @@ class FakeQuantumClientConnection(object):
|
||||
for net_id, n in self.nets.items():
|
||||
if n['tenant-id'] == tenant_id:
|
||||
net_ids.append(net_id)
|
||||
return net_ids
|
||||
return {'networks': net_ids}
|
||||
|
||||
def create_network(self, tenant_id, network_name):
|
||||
|
||||
@ -90,14 +92,22 @@ class FakeQuantumClientConnection(object):
|
||||
"for tenant %(tenant_id)s" % locals()))
|
||||
del self.nets[net_id]['ports'][port_id]
|
||||
|
||||
def get_port_by_attachment(self, tenant_id, attachment_id):
|
||||
for net_id, n in self.nets.items():
|
||||
if n['tenant-id'] == tenant_id:
|
||||
def get_port_by_attachment(self, tenant_id, net_id, attachment_id):
|
||||
for nid, n in self.nets.items():
|
||||
if nid == net_id and n['tenant-id'] == tenant_id:
|
||||
for port_id, p in n['ports'].items():
|
||||
if p['attachment-id'] == attachment_id:
|
||||
return (net_id, port_id)
|
||||
return port_id
|
||||
return None
|
||||
|
||||
def get_networks(self, tenant_id):
|
||||
nets = []
|
||||
for nid, n in self.nets.items():
|
||||
if n['tenant-id'] == tenant_id:
|
||||
x = {'id': nid}
|
||||
nets.append(x)
|
||||
return {'networks': nets}
|
||||
|
||||
return (None, None)
|
||||
|
||||
networks = [{'label': 'project1-net1',
|
||||
'injected': False,
|
||||
@ -184,14 +194,16 @@ class QuantumTestCaseBase(object):
|
||||
def _create_nets(self):
|
||||
for n in networks:
|
||||
ctx = context.RequestContext('user1', n['project_id'])
|
||||
self.net_man.create_networks(ctx,
|
||||
nwks = self.net_man.create_networks(ctx,
|
||||
label=n['label'], cidr=n['cidr'],
|
||||
multi_host=n['multi_host'],
|
||||
num_networks=1, network_size=256, cidr_v6=n['cidr_v6'],
|
||||
gateway=n['gateway'],
|
||||
gateway_v6=n['gateway_v6'], bridge=None,
|
||||
bridge_interface=None, dns1=n['dns1'],
|
||||
dns2=n['dns2'], project_id=n['project_id'],
|
||||
priority=n['priority'])
|
||||
n['uuid'] = nwks[0]['uuid']
|
||||
|
||||
def _delete_nets(self):
|
||||
for n in networks:
|
||||
@ -210,6 +222,16 @@ class QuantumTestCaseBase(object):
|
||||
|
||||
instance_ref = db.instance_create(ctx,
|
||||
{"project_id": project_id})
|
||||
|
||||
def func(arg1, arg2):
|
||||
pass
|
||||
|
||||
def func1(arg1):
|
||||
pass
|
||||
|
||||
self.net_man.driver.update_dhcp_hostfile_with_text = func
|
||||
self.net_man.driver.restart_dhcp = func
|
||||
self.net_man.driver.kill_dhcp = func1
|
||||
nw_info = self.net_man.allocate_for_instance(ctx,
|
||||
instance_id=instance_ref['id'], host="",
|
||||
instance_type_id=instance_ref['instance_type_id'],
|
||||
@ -249,12 +271,23 @@ class QuantumTestCaseBase(object):
|
||||
ctx = context.RequestContext('user1', project_id)
|
||||
|
||||
net_ids = self.net_man.q_conn.get_networks_for_tenant(project_id)
|
||||
requested_networks = [(net_id, None) for net_id in net_ids]
|
||||
requested_networks = [(net_id, None) for net_id in
|
||||
net_ids['networks']]
|
||||
|
||||
self.net_man.validate_networks(ctx, requested_networks)
|
||||
|
||||
instance_ref = db.instance_create(ctx,
|
||||
{"project_id": project_id})
|
||||
|
||||
def func(arg1, arg2):
|
||||
pass
|
||||
|
||||
def func1(arg1):
|
||||
pass
|
||||
|
||||
self.net_man.driver.update_dhcp_hostfile_with_text = func
|
||||
self.net_man.driver.restart_dhcp = func
|
||||
self.net_man.driver.kill_dhcp = func1
|
||||
nw_info = self.net_man.allocate_for_instance(ctx,
|
||||
instance_id=instance_ref['id'], host="",
|
||||
instance_type_id=instance_ref['instance_type_id'],
|
||||
|
Loading…
Reference in New Issue
Block a user