]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Prevent update_port ip_address from matching address_pair
authorAaron Rosen <arosen@nicira.com>
Wed, 11 Sep 2013 03:32:28 +0000 (20:32 -0700)
committerAaron Rosen <arosen@nicira.com>
Wed, 11 Sep 2013 18:12:21 +0000 (11:12 -0700)
Previously one could update a port to match one of the address_pairs.
This patch prevents that.

Fixes bug: 1223646

Change-Id: Ic8cecfdb83b3fd9d2691bb41e0427cf578577fc8

neutron/db/allowedaddresspairs_db.py
neutron/plugins/ml2/plugin.py
neutron/plugins/nicira/NeutronPlugin.py
neutron/plugins/openvswitch/ovs_neutron_plugin.py
neutron/tests/unit/test_extension_allowedaddresspairs.py

index 1c9977dd227f67b94bd9ddc853be4a75069ee053..d1c35b221ab41f07baebeb935b31cf068125f796 100644 (file)
@@ -55,9 +55,6 @@ class AllowedAddressPairsMixin(object):
                     if ((fixed_ip['ip_address'] == address_pair['ip_address'])
                         and (port['mac_address'] ==
                              address_pair['mac_address'])):
-                        #TODO(arosen) - need to query for address pairs
-                        # to check for same condition if fixed_ips change to
-                        # be an address pair.
                         raise addr_pair.AddressPairMatchesPortFixedIPAndMac()
                 db_pair = AllowedAddressPair(
                     port_id=port['id'],
@@ -67,6 +64,14 @@ class AllowedAddressPairsMixin(object):
 
         return allowed_address_pairs
 
+    def _check_fixed_ips_and_address_pairs_no_overlap(self, context, port):
+        address_pairs = self.get_allowed_address_pairs(context, port['id'])
+        for fixed_ip in port['fixed_ips']:
+            for address_pair in address_pairs:
+                if (fixed_ip['ip_address'] == address_pair['ip_address']
+                    and port['mac_address'] == address_pair['mac_address']):
+                    raise addr_pair.AddressPairMatchesPortFixedIPAndMac()
+
     def get_allowed_address_pairs(self, context, port_id):
         pairs = (context.session.query(AllowedAddressPair).
                  filter_by(port_id=port_id))
index 25de47f33ff098fd302fc752538a6c54c61147fe..0e5dfc3b9f1e092209b5088c89d910c1aa553c42 100644 (file)
@@ -468,6 +468,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
         need_port_update_notify = False
 
         session = context.session
+        changed_fixed_ips = 'fixed_ips' in port['port']
         with session.begin(subtransactions=True):
             original_port = super(Ml2Plugin, self).get_port(context, id)
             updated_port = super(Ml2Plugin, self).update_port(context, id,
@@ -478,6 +479,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
                     context, updated_port,
                     port['port'][addr_pair.ADDRESS_PAIRS])
                 need_port_update_notify = True
+            elif changed_fixed_ips:
+                self._check_fixed_ips_and_address_pairs_no_overlap(
+                    context, updated_port)
             need_port_update_notify |= self.update_security_group_on_port(
                 context, id, port, original_port, updated_port)
             network = self.get_network(context, original_port['network_id'])
index 6854d8db3e7374c6bd1665baeabb3e723d73e83d..014dc8c4232f306c8f37e50b3472cd1f5e6ee850 100644 (file)
@@ -1205,6 +1205,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
         return port_data
 
     def update_port(self, context, id, port):
+        changed_fixed_ips = 'fixed_ips' in port['port']
         delete_security_groups = self._check_update_deletes_security_groups(
             port)
         has_security_groups = self._check_update_has_security_groups(port)
@@ -1246,6 +1247,9 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
                 self._delete_allowed_address_pairs(context, id)
                 self._process_create_allowed_address_pairs(
                     context, ret_port, ret_port[addr_pair.ADDRESS_PAIRS])
+            elif changed_fixed_ips:
+                self._check_fixed_ips_and_address_pairs_no_overlap(context,
+                                                                   ret_port)
             # checks if security groups were updated adding/modifying
             # security groups, port security is set and port has ip
             if not (has_ip and ret_port[psec.PORTSECURITY]):
index 1aafe6593f0499a7e70d4096453b78a6223b2e06..f7222660525d88a831eb01f371001c0033a38be7 100644 (file)
@@ -566,6 +566,7 @@ class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
     def update_port(self, context, id, port):
         session = context.session
         need_port_update_notify = False
+        changed_fixed_ips = 'fixed_ips' in port['port']
         with session.begin(subtransactions=True):
             original_port = super(OVSNeutronPluginV2, self).get_port(
                 context, id)
@@ -577,7 +578,9 @@ class OVSNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
                     context, updated_port,
                     port['port'][addr_pair.ADDRESS_PAIRS])
                 need_port_update_notify = True
-
+            elif changed_fixed_ips:
+                self._check_fixed_ips_and_address_pairs_no_overlap(
+                    context, updated_port)
             need_port_update_notify |= self.update_security_group_on_port(
                 context, id, port, original_port, updated_port)
             self._process_portbindings_create_and_update(context,
index ab380e9267482f1fb04d7c4d403b2124697711e3..dcfc2b99e50722c1656aef2b4576f2222f2df420 100644 (file)
@@ -64,6 +64,7 @@ class AllowedAddressPairTestPlugin(portsecurity_db.PortSecurityDbMixin,
         return port['port']
 
     def update_port(self, context, id, port):
+        changed_fixed_ips = 'fixed_ips' in port['port']
         delete_addr_pairs = self._check_update_deletes_allowed_address_pairs(
             port)
         has_addr_pairs = self._check_update_has_allowed_address_pairs(port)
@@ -81,6 +82,9 @@ class AllowedAddressPairTestPlugin(portsecurity_db.PortSecurityDbMixin,
                 self._process_create_allowed_address_pairs(
                     context, ret_port,
                     ret_port[addr_pair.ADDRESS_PAIRS])
+            elif changed_fixed_ips:
+                self._check_fixed_ips_and_address_pairs_no_overlap(context,
+                                                                   ret_port)
 
         return ret_port
 
@@ -196,6 +200,34 @@ class TestAllowedAddressPairs(AllowedAddressPairDBTestCase):
                              address_pairs)
             self._delete('ports', port['port']['id'])
 
+    def test_update_fixed_ip_to_address_pair_ip_fail(self):
+        with self.network() as net:
+            with self.subnet(network=net):
+                address_pairs = [{'ip_address': '10.0.0.65'}]
+                res = self._create_port(self.fmt, net['network']['id'],
+                                        arg_list=(addr_pair.ADDRESS_PAIRS,),
+                                        allowed_address_pairs=address_pairs)
+                port = self.deserialize(self.fmt, res)['port']
+                data = {'port': {'fixed_ips': [{'ip_address': '10.0.0.65'}]}}
+                req = self.new_update_request('ports', data, port['id'])
+                res = req.get_response(self.api)
+                self.assertEqual(res.status_int, 400)
+                self._delete('ports', port['id'])
+
+    def test_update_fixed_ip_to_address_pair_with_mac_fail(self):
+        with self.network() as net:
+            with self.subnet(network=net):
+                res = self._create_port(self.fmt, net['network']['id'])
+                port = self.deserialize(self.fmt, res)['port']
+                address_pairs = [
+                    {'mac_address': port['mac_address'],
+                     'ip_address': port['fixed_ips'][0]['ip_address']}]
+                data = {'port': {addr_pair.ADDRESS_PAIRS: address_pairs}}
+                req = self.new_update_request('ports', data, port['id'])
+                res = req.get_response(self.api)
+                self.assertEqual(res.status_int, 400)
+                self._delete('ports', port['id'])
+
     def test_create_address_gets_port_mac(self):
         with self.network() as net:
             address_pairs = [{'ip_address': '23.23.23.23'}]