diff options
| author | Brad Hall <brad@nicira.com> | 2011-12-19 19:02:47 -0800 |
|---|---|---|
| committer | Brad Hall <brad@nicira.com> | 2011-12-19 20:33:34 -0800 |
| commit | dc2c46430158496878255dd2e4d6416804d7c622 (patch) | |
| tree | ce47859ed14171f79e5c0d260d0d8f6299f1f86c /nova | |
| parent | c510592fe94e81ff0332ae9d209a893d8057ad4a (diff) | |
Add support for port security to QuantumManager
If enabled, QuantumManager will now pass in the allowed_address_pairs that
some quantum plugins understand in order to enforce port security on a
given port. Any plugins that don't understand the extra fields will just
ignore them.
Change-Id: I640658036789b319ecefbb5e7dcdcf6b4f4ab34e
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/network/quantum/manager.py | 17 | ||||
| -rw-r--r-- | nova/tests/test_quantum.py | 71 |
2 files changed, 84 insertions, 4 deletions
diff --git a/nova/network/quantum/manager.py b/nova/network/quantum/manager.py index 36559fa45..2183dd355 100644 --- a/nova/network/quantum/manager.py +++ b/nova/network/quantum/manager.py @@ -49,6 +49,9 @@ flags.DEFINE_bool('use_melange_mac_generation', False, flags.DEFINE_bool('quantum_use_dhcp', False, 'Whether or not to enable DHCP for networks') +flags.DEFINE_bool('quantum_use_port_security', False, + 'Whether or not to enable port security') + class QuantumManager(manager.FlatManager): """NetworkManager class that communicates with a Quantum service @@ -282,14 +285,20 @@ class QuantumManager(manager.FlatManager): rxtx_factor = instance_type['rxtx_factor'] nova_id = self._get_nova_id(context) q_tenant_id = project_id or FLAGS.quantum_default_tenant_id + # Tell the ipam library to allocate an IP + ip = self.ipam.allocate_fixed_ip(context, project_id, + quantum_net_id, vif_rec) + pairs = [] + # Set up port security if enabled + if FLAGS.quantum_use_port_security: + pairs = [{'mac_address': vif_rec['address'], + 'ip_address': ip}] self.q_conn.create_and_attach_port(q_tenant_id, quantum_net_id, vif_rec['uuid'], vm_id=instance['uuid'], rxtx_factor=rxtx_factor, - nova_id=nova_id) - # Tell melange to allocate an IP - ip = self.ipam.allocate_fixed_ip(context, project_id, - quantum_net_id, vif_rec) + nova_id=nova_id, + 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, diff --git a/nova/tests/test_quantum.py b/nova/tests/test_quantum.py index 8e8a8511c..6c19f00e5 100644 --- a/nova/tests/test_quantum.py +++ b/nova/tests/test_quantum.py @@ -429,3 +429,74 @@ class QuantumNovaMACGenerationTestCase(QuantumNovaTestCase): project_id=project_id, requested_networks=requested_networks) self.assertEqual(nw_info[0][1]['mac'], fake_mac) + + +class QuantumNovaPortSecurityTestCase(QuantumNovaTestCase): + def test_port_securty(self): + self.flags(use_melange_mac_generation=True) + self.flags(quantum_use_port_security=True) + fake_mac = "ab:cd:ef:ab:cd:ef" + self.stubs.Set(melange_connection.MelangeConnection, "create_vif", + lambda w, x, y, z: fake_mac) + project_id = "fake_project1" + ctx = context.RequestContext('user1', project_id) + self._create_network(networks[0]) + + net_ids = self.net_man.q_conn.get_networks_for_tenant(project_id) + requested_networks = [(net_id, None) for net_id in net_ids['networks']] + + instance_ref = db.api.instance_create(ctx, + {"project_id": project_id}) + oldfunc = self.net_man.q_conn.create_and_attach_port + + # Make sure we get the appropriate mac set in allowed_address_pairs + # if port security is enabled. + def _instrumented_create_and_attach_port(tenant_id, net_id, + interface_id, **kwargs): + self.assertTrue('allowed_address_pairs' in kwargs.keys()) + pairs = kwargs['allowed_address_pairs'] + self.assertTrue(pairs[0]['mac_address'] == fake_mac) + self.net_man.q_conn.create_and_attach_port = oldfunc + return oldfunc(tenant_id, net_id, interface_id, **kwargs) + self.net_man.q_conn.create_and_attach_port = \ + _instrumented_create_and_attach_port + nw_info = self.net_man.allocate_for_instance(ctx, + instance_id=instance_ref['id'], host="", + instance_type_id=instance_ref['instance_type_id'], + project_id=project_id, + requested_networks=requested_networks) + self.assertEqual(nw_info[0][1]['mac'], fake_mac) + + def test_port_securty_negative(self): + self.flags(use_melange_mac_generation=True) + self.flags(quantum_use_port_security=False) + fake_mac = "ab:cd:ef:ab:cd:ef" + self.stubs.Set(melange_connection.MelangeConnection, "create_vif", + lambda w, x, y, z: fake_mac) + project_id = "fake_project1" + ctx = context.RequestContext('user1', project_id) + self._create_network(networks[0]) + + net_ids = self.net_man.q_conn.get_networks_for_tenant(project_id) + requested_networks = [(net_id, None) for net_id in net_ids['networks']] + + instance_ref = db.api.instance_create(ctx, + {"project_id": project_id}) + oldfunc = self.net_man.q_conn.create_and_attach_port + + # Make sure no pairs are passed in if port security is turned off + def _instrumented_create_and_attach_port(tenant_id, net_id, + interface_id, **kwargs): + self.assertTrue('allowed_address_pairs' in kwargs.keys()) + pairs = kwargs['allowed_address_pairs'] + self.assertTrue(len(pairs) == 0) + self.net_man.q_conn.create_and_attach_port = oldfunc + return oldfunc(tenant_id, net_id, interface_id, **kwargs) + self.net_man.q_conn.create_and_attach_port = \ + _instrumented_create_and_attach_port + nw_info = self.net_man.allocate_for_instance(ctx, + instance_id=instance_ref['id'], host="", + instance_type_id=instance_ref['instance_type_id'], + project_id=project_id, + requested_networks=requested_networks) + self.assertEqual(nw_info[0][1]['mac'], fake_mac) |
