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,
|
context.elevated(), router_id,
|
||||||
gw_info['network_id'], fip['subnet_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
|
nsx_router_id = None
|
||||||
routes_added = []
|
routes_added = []
|
||||||
routes_removed = []
|
routes_removed = []
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
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 registry
|
||||||
from neutron_lib.callbacks import resources
|
from neutron_lib.callbacks import resources
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
from neutron_lib import exceptions as nexception
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
from neutron_vpnaas.services.vpn import service_drivers
|
from neutron_vpnaas.services.vpn import service_drivers
|
||||||
|
|
||||||
@ -37,6 +39,11 @@ LOG = logging.getLogger(__name__)
|
|||||||
IPSEC = 'ipsec'
|
IPSEC = 'ipsec'
|
||||||
|
|
||||||
|
|
||||||
|
class RouterWithSNAT(nexception.BadRequest):
|
||||||
|
message = _("Router %(router_id)s has a VPN service and cannot enable "
|
||||||
|
"SNAT")
|
||||||
|
|
||||||
|
|
||||||
class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
|
class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
|
||||||
|
|
||||||
def __init__(self, service_plugin):
|
def __init__(self, service_plugin):
|
||||||
@ -354,6 +361,19 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver):
|
|||||||
if local_ep_id:
|
if local_ep_id:
|
||||||
self._nsx_vpn.local_endpoint.delete(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):
|
def _get_session_rules(self, context, connection, vpnservice):
|
||||||
# TODO(asarfaty): support vpn-endpoint-groups too
|
# TODO(asarfaty): support vpn-endpoint-groups too
|
||||||
peer_cidrs = connection['peer_cidrs']
|
peer_cidrs = connection['peer_cidrs']
|
||||||
|
@ -323,6 +323,11 @@ class IPsecV3Validator(vpn_validator.VpnReferenceValidator):
|
|||||||
"with ACTIVE_STANDBY HA mode")
|
"with ACTIVE_STANDBY HA mode")
|
||||||
raise nsx_exc.NsxVpnValidationError(details=msg)
|
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):
|
def validate_vpnservice(self, context, vpnservice):
|
||||||
"""Called upon create/update of a service"""
|
"""Called upon create/update of a service"""
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from neutron.db.models import l3 as l3_models
|
||||||
from neutron_lib import context as n_ctx
|
from neutron_lib import context as n_ctx
|
||||||
from neutron_vpnaas.tests import base
|
from neutron_vpnaas.tests import base
|
||||||
|
|
||||||
@ -156,16 +157,31 @@ class TestDriverValidation(base.BaseTestCase):
|
|||||||
self.validator.validate_ipsec_policy(self.context, policy_info)
|
self.validator.validate_ipsec_policy(self.context, policy_info)
|
||||||
|
|
||||||
def test_vpn_service_validation_router(self):
|
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',
|
with mock.patch.object(self.validator.nsxlib.logical_router, 'get',
|
||||||
return_value=router):
|
return_value=nsx_router):
|
||||||
self.assertRaises(nsx_exc.NsxVpnValidationError,
|
self.assertRaises(nsx_exc.NsxVpnValidationError,
|
||||||
self.validator.validate_vpnservice,
|
self.validator.validate_vpnservice,
|
||||||
self.context, self.vpn_service)
|
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',
|
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)
|
self.validator.validate_vpnservice(self.context, self.vpn_service)
|
||||||
|
|
||||||
def _test_conn_validation(self, conn_params=None, success=True,
|
def _test_conn_validation(self, conn_params=None, success=True,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user