From 337b4076bf73d351d572d043a95edbeefa113315 Mon Sep 17 00:00:00 2001 From: berlin Date: Wed, 19 Feb 2014 15:34:47 +0800 Subject: [PATCH] Fix VPN agent does not handle multiple connections per vpn service 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 | 11 +++++- .../services/vpn/device_drivers/test_ipsec.py | 39 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/neutron/services/vpn/device_drivers/ipsec.py b/neutron/services/vpn/device_drivers/ipsec.py index 1d2d602c6..cdf9c5871 100644 --- a/neutron/services/vpn/device_drivers/ipsec.py +++ b/neutron/services/vpn/device_drivers/ipsec.py @@ -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): diff --git a/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py b/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py index a06d6f9f9..d149e5024 100644 --- a/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py +++ b/neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py @@ -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() -- 2.45.2