From: berlin Date: Wed, 19 Feb 2014 07:34:47 +0000 (+0800) Subject: Fix VPN agent does not handle multiple connections per vpn service X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=337b4076bf73d351d572d043a95edbeefa113315;p=openstack-build%2Fneutron-build.git 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 --- 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()