]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix VPN agent does not handle multiple connections per vpn service
authorberlin <linb@vmware.com>
Wed, 19 Feb 2014 07:34:47 +0000 (15:34 +0800)
committerberlin <linb@vmware.com>
Fri, 21 Feb 2014 05:01:54 +0000 (13:01 +0800)
    Once the OpenSwan process is created, incoming updated vpnservice
data would not be updated into the process class which leads to config
files and openswan process always keep old configurations

Change-Id: Ia91ab08b1d03fbbe46bafd4967b57181fc4c6e71
Closes-Bug: 1263194

neutron/services/vpn/device_drivers/ipsec.py
neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py

index 1d2d602c69ec6aae2f0710b5ad949ae76520fe04..cdf9c58710bb3162c99212c5d3312560d9cf74a0 100644 (file)
@@ -131,14 +131,13 @@ class BaseSwanProcess():
         self.conf = conf
         self.id = process_id
         self.root_helper = root_helper
-        self.vpnservice = vpnservice
         self.updated_pending_status = False
         self.namespace = namespace
         self.connection_status = {}
         self.config_dir = os.path.join(
             cfg.CONF.ipsec.config_base_dir, self.id)
         self.etc_dir = os.path.join(self.config_dir, 'etc')
-        self.translate_dialect()
+        self.update_vpnservice(vpnservice)
 
     def translate_dialect(self):
         if not self.vpnservice:
@@ -152,6 +151,10 @@ class BaseSwanProcess():
                 self._dialect(ipsec_site_conn['ikepolicy'], key)
                 self._dialect(ipsec_site_conn['ipsecpolicy'], key)
 
+    def update_vpnservice(self, vpnservice):
+        self.vpnservice = vpnservice
+        self.translate_dialect()
+
     def _dialect(self, obj, key):
         obj[key] = self.DIALECT_MAP.get(obj[key], obj[key])
 
@@ -435,6 +438,8 @@ class OpenSwanProcess(BaseSwanProcess):
                        '--ctlbase', self.pid_path,
                        '--shutdown',
                        ])
+        #clean connection_status info
+        self.connection_status = {}
 
 
 class IPsecVpnDriverApi(proxy.RpcProxy):
@@ -555,6 +560,8 @@ class IPsecDriver(device_drivers.DeviceDriver):
                 vpnservice,
                 namespace)
             self.processes[process_id] = process
+        elif vpnservice:
+            process.update_vpnservice(vpnservice)
         return process
 
     def create_router(self, process_id):
index a06d6f9f9dd8d3cb1ab4cc31c2252026836e8b5e..d149e502456d1eb9e3274da55645563ee143e8b0 100644 (file)
@@ -14,6 +14,7 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+import copy
 import mock
 
 from neutron.openstack.common import uuidutils
@@ -134,6 +135,44 @@ class TestIPsecDeviceDriver(base.BaseTestCase):
              'updated_pending_status': True,
              'id': FAKE_VPN_SERVICE['id']}])
 
+    def fake_ensure_process(self, process_id, vpnservice=None):
+        process = self.driver.processes.get(process_id)
+        if not process:
+            process = mock.Mock()
+            process.vpnservice = FAKE_VPN_SERVICE
+            process.connection_status = {}
+            process.status = constants.ACTIVE
+            process.updated_pending_status = True
+            self.driver.processes[process_id] = process
+        elif vpnservice:
+            process.vpnservice = vpnservice
+            process.update_vpnservice(vpnservice)
+        return process
+
+    def test_sync_update_vpnservice(self):
+        with mock.patch.object(self.driver,
+                               'ensure_process') as ensure_process:
+            ensure_process.side_effect = self.fake_ensure_process
+            new_vpn_service = FAKE_VPN_SERVICE
+            updated_vpn_service = copy.deepcopy(new_vpn_service)
+            updated_vpn_service['ipsec_site_connections'].append(
+                {'peer_cidrs': ['60.0.0.0/24',
+                                '70.0.0.0/24']})
+            context = mock.Mock()
+            self.driver.process_status_cache = {}
+            self.driver.agent_rpc.get_vpn_services_on_host.return_value = [
+                new_vpn_service]
+            self.driver.sync(context, [])
+            process = self.driver.processes[FAKE_ROUTER_ID]
+            self.assertEqual(process.vpnservice, new_vpn_service)
+            self.driver.agent_rpc.get_vpn_services_on_host.return_value = [
+                updated_vpn_service]
+            self.driver.sync(context, [])
+            process = self.driver.processes[FAKE_ROUTER_ID]
+            process.update_vpnservice.assert_called_once_with(
+                updated_vpn_service)
+            self.assertEqual(process.vpnservice, updated_vpn_service)
+
     def test_sync_removed(self):
         self.driver.agent_rpc.get_vpn_services_on_host.return_value = []
         context = mock.Mock()