NSX-V3 Fix some VPNaaS configuration bugs

- Support the case of empty neutron names
- Fix NSX local endpoints tags
- Support connection/service admin-state configuration

Depends-on: Ieb9da32b6f3b908dda7b4c5b99cb4ca2b79c9286
Change-Id: If5509fdcf3c496ad446921a3fb57b48deb6179f4
This commit is contained in:
Adit Sarfaty 2018-03-18 11:28:18 +02:00
parent 8b06741ad7
commit a494a35444
1 changed files with 48 additions and 23 deletions

View File

@ -186,7 +186,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
ikepolicy = self.vpn_plugin.get_ikepolicy(context, ike_policy_id)
try:
profile = self._nsx_vpn.ike_profile.create(
ikepolicy['name'],
ikepolicy['name'] or ikepolicy['id'],
description=ikepolicy['description'],
encryption_algorithm=ipsec_utils.ENCRYPTION_ALGORITHM_MAP[
ikepolicy['encryption_algorithm']],
@ -217,7 +217,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
try:
profile = self._nsx_vpn.tunnel_profile.create(
ipsecpolicy['name'],
ipsecpolicy['name'] or ipsecpolicy['id'],
description=ipsecpolicy['description'],
encryption_algorithm=ipsec_utils.ENCRYPTION_ALGORITHM_MAP[
ipsecpolicy['encryption_algorithm']],
@ -235,11 +235,14 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
def _delete_ipsec_profile(self, ipsecprofile_id):
self._nsx_vpn.tunnel_profile.delete(ipsecprofile_id)
def _get_dpd_profile_name(self, connection):
return (connection['name'] or connection['id'])[:240] + '-dpd-profile'
def _create_dpd_profile(self, context, connection):
dpd_info = connection['dpd']
try:
profile = self._nsx_vpn.dpd_profile.create(
connection['name'][:240] + '-dpd-profile',
self._get_dpd_profile_name(connection),
description='neutron dpd profile',
timeout=dpd_info.get('timeout'),
enabled=True if dpd_info.get('action') == 'hold' else False,
@ -256,6 +259,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
def _update_dpd_profile(self, connection, dpdprofile_id):
dpd_info = connection['dpd']
self._nsx_vpn.dpd_profile.update(dpdprofile_id,
name=self._get_dpd_profile_name(connection),
timeout=dpd_info.get('timeout'),
enabled=True if dpd_info.get('action') == 'hold' else False)
@ -264,7 +268,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
default_auth = vpn_ipsec.AuthenticationModeTypes.AUTH_MODE_PSK
try:
peer_endpoint = self._nsx_vpn.peer_endpoint.create(
connection['name'],
connection['name'] or connection['id'],
connection['peer_address'],
connection['peer_id'],
description=connection['description'],
@ -285,7 +289,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
def _update_peer_endpoint(self, peer_ep_id, connection):
self._nsx_vpn.peer_endpoint.update(
peer_ep_id,
name=connection['name'],
name=connection['name'] or connection['id'],
peer_address=connection['peer_address'],
peer_id=connection['peer_id'],
description=connection['description'],
@ -304,7 +308,7 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
peer_ep['dpd_profile_id'])
def _create_local_endpoint(self, context, local_addr, nsx_service_id,
router_id):
router_id, project_id):
"""Creating an NSX local endpoint for a logical router
This endpoint can be reused by other connections, and will be deleted
@ -312,7 +316,8 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
"""
# Add the neutron router-id to the tags to help search later
tags = self._nsxlib.build_v3_tags_payload(
{'id': router_id}, resource_type='os-neutron-router-id',
{'id': router_id, 'project_id': project_id},
resource_type='os-neutron-router-id',
project_name=context.tenant_name)
try:
@ -353,7 +358,8 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
local_addr = vpnservice['external_v4_ip']
nsx_service_id = self._get_nsx_vpn_service(context, vpnservice)
local_ep_id = self._create_local_endpoint(
context, local_addr, nsx_service_id, router_id)
context, local_addr, nsx_service_id, router_id,
vpnservice['project_id'])
return local_ep_id
def _find_vpn_service_port(self, context, router_id):
@ -398,24 +404,28 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
return [rule]
def _create_session(self, context, connection, local_ep_id,
peer_ep_id, rules):
peer_ep_id, rules, enabled=True):
try:
session = self._nsx_vpn.session.create(
connection['name'], local_ep_id, peer_ep_id, rules,
connection['name'] or connection['id'],
local_ep_id, peer_ep_id, rules,
description=connection['description'],
tags=self._nsx_tags(context, connection))
tags=self._nsx_tags(context, connection),
enabled=enabled)
except nsx_lib_exc.ManagerError as e:
msg = _("Failed to create a session: %s") % e
raise nsx_exc.NsxPluginException(err_msg=msg)
return session['id']
def _update_session(self, session_id, connection, rules):
def _update_session(self, session_id, connection, rules=None,
enabled=True):
self._nsx_vpn.session.update(
session_id,
name=connection['name'],
name=connection['name'] or connection['id'],
description=connection['description'],
policy_rules=rules)
policy_rules=rules,
enabled=enabled)
def _delete_session(self, session_id):
self._nsx_vpn.session.delete(session_id)
@ -465,8 +475,11 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
# Finally: create the session with policy rules
rules = self._get_session_rules(
context, ipsec_site_conn, vpnservice)
connection_enabled = (vpnservice['admin_state_up'] and
ipsec_site_conn['admin_state_up'])
session_id = self._create_session(
context, ipsec_site_conn, local_ep_id, peer_ep_id, rules)
context, ipsec_site_conn, local_ep_id, peer_ep_id, rules,
enabled=connection_enabled)
# update the DB with the session id
db.add_nsx_vpn_connection_mapping(
@ -559,15 +572,12 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
self._update_status(context, vpnservice_id, ipsec_id, "ERROR")
raise nsx_exc.NsxIPsecVpnMappingNotFound(conn=ipsec_id)
update_all = (old_ipsec_conn['name'] != ipsec_site_conn['name'] or
old_ipsec_conn['description'] !=
ipsec_site_conn['description'])
# check if the dpd configuration changed
old_dpd = old_ipsec_conn['dpd']
new_dpd = ipsec_site_conn['dpd']
if (old_dpd['action'] != new_dpd['action'] or
old_dpd['timeout'] != new_dpd['timeout'] or
update_all):
old_ipsec_conn['name'] != ipsec_site_conn['name']):
self._update_dpd_profile(ipsec_site_conn,
mapping['dpd_profile_id'])
@ -576,9 +586,12 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
self._update_peer_endpoint(mapping['peer_ep_id'], ipsec_site_conn)
rules = self._get_session_rules(
context, ipsec_site_conn, vpnservice)
self._update_session(mapping['session_id'], ipsec_site_conn, rules)
connection_enabled = (vpnservice['admin_state_up'] and
ipsec_site_conn['admin_state_up'])
self._update_session(mapping['session_id'], ipsec_site_conn, rules,
enabled=connection_enabled)
if 'peer_cidrs' in ipsec_site_conn:
if ipsec_site_conn['peer_cidrs'] != old_ipsec_conn['peer_cidrs']:
# Update firewall
self._update_firewall_rules(context, vpnservice)
@ -684,8 +697,20 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
self._create_vpn_service_if_needed(context, vpnservice)
def update_vpnservice(self, context, old_vpnservice, vpnservice):
# No meaningful field can change here
pass
# Only handle the case of admin-state-up changes
if old_vpnservice['admin_state_up'] != vpnservice['admin_state_up']:
# update all relevant connections
filters = {'vpnservice_id': [vpnservice['id']]}
connections = self.vpn_plugin.get_ipsec_site_connections(
context, filters=filters)
for conn in connections:
mapping = db.get_nsx_vpn_connection_mapping(
context.session, conn['id'])
if mapping:
connection_enabled = (vpnservice['admin_state_up'] and
conn['admin_state_up'])
self._update_session(mapping['session_id'], conn,
enabled=connection_enabled)
def delete_vpnservice(self, context, vpnservice):
# Do not delete the NSX service or DB entry as those will be reused.