Browse Source

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
tags/2014.1.b3
berlin 6 years ago
parent
commit
6206d7e377
2 changed files with 48 additions and 2 deletions
  1. +9
    -2
      neutron/services/vpn/device_drivers/ipsec.py
  2. +39
    -0
      neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py

+ 9
- 2
neutron/services/vpn/device_drivers/ipsec.py View 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):


+ 39
- 0
neutron/tests/unit/services/vpn/device_drivers/test_ipsec.py View 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()


Loading…
Cancel
Save