summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Lee <aaron.lee@rackspace.com>2012-02-15 18:36:18 -0600
committerAaron Lee <aaron.lee@rackspace.com>2012-02-21 10:59:09 -0600
commit17654068a65d260f4c82841dd989cf12814c50a4 (patch)
tree03c0810def239bd07b86f1d784aaacf1719d0594
parentc28e4b526aed5c3dacee17729241c6a12859fc0b (diff)
Extract get_network in quantum manager
To aid understanding, testing and refactoring allocate_for_instance update: rebase update: rebase and trailingslashectomy Change-Id: I85364b925082ec598c1645c33f3db4a25f3242a8
-rw-r--r--nova/network/quantum/manager.py72
-rw-r--r--nova/tests/test_quantum.py35
2 files changed, 83 insertions, 24 deletions
diff --git a/nova/network/quantum/manager.py b/nova/network/quantum/manager.py
index f623bd549..ea6dae2c4 100644
--- a/nova/network/quantum/manager.py
+++ b/nova/network/quantum/manager.py
@@ -305,29 +305,14 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager):
net_proj_pairs.append((net_id, None))
# Create a port via quantum and attach the vif
- for (quantum_net_id, net_tenant_id) in net_proj_pairs:
- net_tenant_id = net_tenant_id or FLAGS.quantum_default_tenant_id
- # FIXME(danwent): We'd like to have the manager be
- # completely decoupled from the nova networks table.
- # However, other parts of nova sometimes go behind our
- # back and access network data directly from the DB. So
- # for now, the quantum manager knows that there is a nova
- # networks DB table and accesses it here. updating the
- # virtual_interfaces table to use UUIDs would be one
- # solution, but this would require significant work
- # elsewhere.
- admin_context = context.elevated()
-
- # We may not be able to get a network_ref here if this network
- # isn't in the database (i.e. it came from Quantum).
- network_ref = db.network_get_by_uuid(admin_context,
- quantum_net_id)
+ for proj_pair in net_proj_pairs:
+ network = self.get_network(context, proj_pair)
# TODO(tr3buchet): broken. Virtual interfaces require an integer
# network ID and it is not nullable
vif_rec = self.add_virtual_interface(context,
instance_id,
- network_ref['id'],
+ network['id'],
project_id)
# talk to Quantum API to create and attach port.
@@ -335,7 +320,8 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager):
nova_id = self._get_nova_id(instance)
# Tell the ipam library to allocate an IP
ips = self.ipam.allocate_fixed_ips(context, project_id,
- quantum_net_id, net_tenant_id, vif_rec)
+ network['quantum_net_id'], network['net_tenant_id'],
+ vif_rec)
pairs = []
# Set up port security if enabled
if FLAGS.quantum_use_port_security:
@@ -346,7 +332,8 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager):
pairs = [{'mac_address': vif_rec['address'],
'ip_address': ip} for ip in ips]
- self.q_conn.create_and_attach_port(net_tenant_id, quantum_net_id,
+ self.q_conn.create_and_attach_port(network['net_tenant_id'],
+ network['quantum_net_id'],
vif_rec['uuid'],
vm_id=instance['uuid'],
rxtx_factor=rxtx_factor,
@@ -354,13 +341,54 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager):
allowed_address_pairs=pairs)
# Set up/start the dhcp server for this network if necessary
if FLAGS.quantum_use_dhcp:
- self.enable_dhcp(context, quantum_net_id, network_ref,
- vif_rec, net_tenant_id)
+ self.enable_dhcp(context, network['quantum_net_id'], network,
+ vif_rec, network['net_tenant_id'])
return self.get_instance_nw_info(context, instance_id,
instance['uuid'],
rxtx_factor, host,
project_id=project_id)
+ def get_network(self, context, proj_pair):
+ (quantum_net_id, net_tenant_id) = proj_pair
+
+ net_tenant_id = net_tenant_id or FLAGS.quantum_default_tenant_id
+ # FIXME(danwent): We'd like to have the manager be
+ # completely decoupled from the nova networks table.
+ # However, other parts of nova sometimes go behind our
+ # back and access network data directly from the DB. So
+ # for now, the quantum manager knows that there is a nova
+ # networks DB table and accesses it here. updating the
+ # virtual_interfaces table to use UUIDs would be one
+ # solution, but this would require significant work
+ # elsewhere.
+ admin_context = context.elevated()
+
+ # We may not be able to get a network_ref here if this network
+ # isn't in the database (i.e. it came from Quantum).
+ network_ref = db.network_get_by_uuid(admin_context,
+ quantum_net_id)
+
+ if network_ref is None:
+ network_ref = {}
+ network_ref = {"uuid": quantum_net_id,
+ "project_id": net_tenant_id,
+ # NOTE(bgh): We need to document this somewhere but since
+ # we don't know the priority of any networks we get from
+ # quantum we just give them a priority of 0. If its
+ # necessary to specify the order of the vifs and what
+ # network they map to then the user will have to use the
+ # OSCreateServer extension and specify them explicitly.
+ #
+ # In the future users will be able to tag quantum networks
+ # with a priority .. and at that point we can update the
+ # code here to reflect that.
+ "priority": 0,
+ "id": 'NULL',
+ "label": "quantum-net-%s" % quantum_net_id}
+ network_ref['net_tenant_id'] = net_tenant_id
+ network_ref['quantum_net_id'] = quantum_net_id
+ return network_ref
+
@utils.synchronized('quantum-enable-dhcp')
def enable_dhcp(self, context, quantum_net_id, network_ref, vif_rec,
project_id):
diff --git a/nova/tests/test_quantum.py b/nova/tests/test_quantum.py
index 3fa32ef70..e13ad0357 100644
--- a/nova/tests/test_quantum.py
+++ b/nova/tests/test_quantum.py
@@ -220,10 +220,41 @@ class QuantumNovaTestCase(test.TestCase):
n['uuid'] = nwks[0]['uuid']
+class QuantumAllocationTestCase(QuantumNovaTestCase):
+ def test_get_network_in_db(self):
+ context = self.mox.CreateMockAnything()
+ context.elevated().AndReturn('elevated')
+ self.mox.StubOutWithMock(db, 'network_get_by_uuid')
+ self.net_man.context = context
+ db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(
+ {'uuid': 1})
+
+ self.mox.ReplayAll()
+
+ network = self.net_man.get_network(context, ('quantum_net_id',
+ 'net_tenant_id'))
+ self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
+ self.assertEquals(network['uuid'], 1)
+
+ def test_get_network_not_in_db(self):
+ context = self.mox.CreateMockAnything()
+ context.elevated().AndReturn('elevated')
+ self.mox.StubOutWithMock(db, 'network_get_by_uuid')
+ self.net_man.context = context
+ db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(None)
+
+ self.mox.ReplayAll()
+
+ network = self.net_man.get_network(context, ('quantum_net_id',
+ 'net_tenant_id'))
+ self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
+ self.assertEquals(network['uuid'], 'quantum_net_id')
+
+
class QuantumDeallocationTestCase(QuantumNovaTestCase):
def test_deallocate_port(self):
- quantum = self.mox.CreateMock(quantum_connection\
- .QuantumClientConnection)
+ quantum = self.mox.CreateMock(
+ quantum_connection.QuantumClientConnection)
quantum.get_port_by_attachment('q_tenant_id', 'net_id',
'interface_id').AndReturn('port_id')
quantum.detach_and_delete_port('q_tenant_id', 'net_id', 'port_id')