Merge "NSX-v3: VPNaaS supports only No-SNAT routers"
This commit is contained in:
commit
da500f1e84
@ -3445,6 +3445,14 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context.elevated(), router_id,
|
||||
gw_info['network_id'], fip['subnet_id'])
|
||||
|
||||
# VPNaaS need to be notified on router GW changes (there is currently
|
||||
# no matching upstream registration for this)
|
||||
if validators.is_attr_set(gw_info):
|
||||
vpn_plugin = directory.get_plugin(plugin_const.VPN)
|
||||
if vpn_plugin:
|
||||
vpn_driver = vpn_plugin.drivers[vpn_plugin.default_provider]
|
||||
vpn_driver.validate_router_gw_info(context, router_id, gw_info)
|
||||
|
||||
nsx_router_id = None
|
||||
routes_added = []
|
||||
routes_removed = []
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
|
||||
@ -21,6 +22,7 @@ from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
from neutron_lib.callbacks import resources
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as nexception
|
||||
from neutron_lib.plugins import directory
|
||||
from neutron_vpnaas.services.vpn import service_drivers
|
||||
|
||||
@ -37,6 +39,11 @@ LOG = logging.getLogger(__name__)
|
||||
IPSEC = 'ipsec'
|
||||
|
||||
|
||||
class RouterWithSNAT(nexception.BadRequest):
|
||||
message = _("Router %(router_id)s has a VPN service and cannot enable "
|
||||
"SNAT")
|
||||
|
||||
|
||||
class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
|
||||
|
||||
def __init__(self, service_plugin):
|
||||
@ -354,6 +361,19 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
|
||||
if local_ep_id:
|
||||
self._nsx_vpn.local_endpoint.delete(local_ep_id)
|
||||
|
||||
def validate_router_gw_info(self, context, router_id, gw_info):
|
||||
"""Upon router gw update - verify no-snat"""
|
||||
# ckeck if this router has a vpn service
|
||||
filters = {'router_id': [router_id],
|
||||
'status': [constants.ACTIVE]}
|
||||
services = self.vpn_plugin.get_vpnservices(
|
||||
context.elevated(), filters=filters)
|
||||
if services:
|
||||
# do not allow enable-snat
|
||||
if (gw_info and
|
||||
gw_info.get('enable_snat', cfg.CONF.enable_snat_by_default)):
|
||||
raise RouterWithSNAT(router_id=router_id)
|
||||
|
||||
def _get_session_rules(self, context, connection, vpnservice):
|
||||
# TODO(asarfaty): support vpn-endpoint-groups too
|
||||
peer_cidrs = connection['peer_cidrs']
|
||||
|
@ -323,6 +323,11 @@ class IPsecV3Validator(vpn_validator.VpnReferenceValidator):
|
||||
"with ACTIVE_STANDBY HA mode")
|
||||
raise nsx_exc.NsxVpnValidationError(details=msg)
|
||||
|
||||
# Verify that this is a no-snat router
|
||||
if router_db.enable_snat:
|
||||
msg = _("VPN is supported only for routers with disabled SNAT")
|
||||
raise nsx_exc.NsxVpnValidationError(details=msg)
|
||||
|
||||
def validate_vpnservice(self, context, vpnservice):
|
||||
"""Called upon create/update of a service"""
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
import mock
|
||||
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron_lib import context as n_ctx
|
||||
from neutron_vpnaas.tests import base
|
||||
|
||||
@ -156,16 +157,31 @@ class TestDriverValidation(base.BaseTestCase):
|
||||
self.validator.validate_ipsec_policy(self.context, policy_info)
|
||||
|
||||
def test_vpn_service_validation_router(self):
|
||||
router = {'high_availability_mode': 'ACITVE_ACTIVE'}
|
||||
db_router = l3_models.Router()
|
||||
nsx_router = {'high_availability_mode': 'ACITVE_ACTIVE'}
|
||||
db_router.enable_snat = False
|
||||
with mock.patch.object(self.validator.nsxlib.logical_router, 'get',
|
||||
return_value=router):
|
||||
return_value=nsx_router):
|
||||
self.assertRaises(nsx_exc.NsxVpnValidationError,
|
||||
self.validator.validate_vpnservice,
|
||||
self.context, self.vpn_service)
|
||||
|
||||
router = {'high_availability_mode': 'ACTIVE_STANDBY'}
|
||||
nsx_router = {'high_availability_mode': 'ACTIVE_STANDBY'}
|
||||
db_router.enable_snat = True
|
||||
with mock.patch.object(self.validator.nsxlib.logical_router, 'get',
|
||||
return_value=router):
|
||||
return_value=nsx_router),\
|
||||
mock.patch.object(self.validator._core_plugin, '_get_router',
|
||||
return_value=db_router):
|
||||
self.assertRaises(nsx_exc.NsxVpnValidationError,
|
||||
self.validator.validate_vpnservice,
|
||||
self.context, self.vpn_service)
|
||||
|
||||
nsx_router = {'high_availability_mode': 'ACTIVE_STANDBY'}
|
||||
db_router.enable_snat = False
|
||||
with mock.patch.object(self.validator.nsxlib.logical_router, 'get',
|
||||
return_value=nsx_router),\
|
||||
mock.patch.object(self.validator._core_plugin, '_get_router',
|
||||
return_value=db_router):
|
||||
self.validator.validate_vpnservice(self.context, self.vpn_service)
|
||||
|
||||
def _test_conn_validation(self, conn_params=None, success=True,
|
||||
|
Loading…
x
Reference in New Issue
Block a user