Exclusive Router Support
Exclusive router is the router who exclusivly occupies one edge. You can create an exclusive router with "--router_type exclusive" For distributed router, it would always be exclusive router. Change-Id: Ice8cbc20912bc9becc5a82a646c76b9153418189 DocImapct:
This commit is contained in:
parent
d9bc7df7c6
commit
2eb68aa2c3
@ -196,7 +196,7 @@ function run_pep8_changed {
|
||||
}
|
||||
|
||||
|
||||
TESTRTESTS="python -m neutron.openstack.common.lockutils python setup.py testr"
|
||||
TESTRTESTS="python setup.py testr"
|
||||
|
||||
if [ $never_venv -eq 0 ]
|
||||
then
|
||||
|
@ -23,7 +23,11 @@ packages =
|
||||
vmware_nsx
|
||||
namespace_packages =
|
||||
vmware_nsx
|
||||
|
||||
[entry_points]
|
||||
vmware_nsx.neutron.nsxv.router_type_drivers =
|
||||
shared = vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers.shared_router_driver:RouterSharedDriver
|
||||
distributed = vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers.distributed_router_driver:RouterDistributedDriver
|
||||
exclusive = vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers.exclusive_router_driver:RouterExclusiveDriver
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
|
@ -239,7 +239,11 @@ nsxv_opts = [
|
||||
cfg.BoolOpt('spoofguard_enabled',
|
||||
default=True,
|
||||
help=_("If True then plugin will use NSXV spoofguard "
|
||||
"component for port-security feature."))
|
||||
"component for port-security feature.")),
|
||||
cfg.ListOpt('tenant_router_types',
|
||||
default=['shared', 'distributed', 'exclusive'],
|
||||
help=_("Ordered list of router_types to allocate as tenant "
|
||||
"routers."))
|
||||
]
|
||||
|
||||
# Register the configuration options
|
||||
|
@ -105,3 +105,12 @@ class LsnMigrationConflict(n_exc.Conflict):
|
||||
|
||||
class LsnConfigurationConflict(NsxPluginException):
|
||||
message = _("Configuration conflict on Logical Service Node %(lsn_id)s")
|
||||
|
||||
|
||||
class DvsNotFound(n_exc.NotFound):
|
||||
message = _('Unable to find DVS %(dvs)s')
|
||||
|
||||
|
||||
class NoRouterAvailable(n_exc.ResourceExhausted):
|
||||
message = _("Unable to create the router. "
|
||||
"No tenant router is available for allocation.")
|
||||
|
30
vmware_nsx/neutron/plugins/vmware/dbexts/routertype.py
Normal file
30
vmware_nsx/neutron/plugins/vmware/dbexts/routertype.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright 2014 VMware, Inc. All rights reserved.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from neutron.plugins.vmware.extensions import routertype as rt_rtr
|
||||
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import (
|
||||
distributedrouter as dist_rtr)
|
||||
|
||||
|
||||
class RouterType_mixin(dist_rtr.DistributedRouter_mixin):
|
||||
"""Mixin class to enable Router type support."""
|
||||
|
||||
nsx_attributes = (
|
||||
dist_rtr.DistributedRouter_mixin.nsx_attributes + [{
|
||||
'name': rt_rtr.ROUTER_TYPE,
|
||||
'default': False
|
||||
}])
|
92
vmware_nsx/neutron/plugins/vmware/plugins/managers.py
Normal file
92
vmware_nsx/neutron/plugins/vmware/plugins/managers.py
Normal file
@ -0,0 +1,92 @@
|
||||
# Copyright 2014 VMware, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
import stevedore
|
||||
|
||||
from neutron.openstack.common import log
|
||||
from neutron.plugins.vmware.common import exceptions as nsx_exc
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
ROUTER_TYPE_DRIVERS = ["distributed", "exclusive", "shared"]
|
||||
|
||||
|
||||
class RouterTypeManager(stevedore.named.NamedExtensionManager):
|
||||
"""Manage router segment types using drivers."""
|
||||
|
||||
def __init__(self, plugin):
|
||||
# Mapping from type name to DriverManager
|
||||
self.drivers = {}
|
||||
|
||||
LOG.info(_("Configured router type driver names: %s"),
|
||||
ROUTER_TYPE_DRIVERS)
|
||||
super(RouterTypeManager, self).__init__(
|
||||
'vmware_nsx.neutron.nsxv.router_type_drivers',
|
||||
ROUTER_TYPE_DRIVERS,
|
||||
invoke_on_load=True,
|
||||
invoke_args=(plugin,))
|
||||
LOG.info(_("Loaded type driver names: %s"), self.names())
|
||||
self._register_types()
|
||||
self._check_tenant_router_types(cfg.CONF.nsxv.tenant_router_types)
|
||||
|
||||
def _register_types(self):
|
||||
for ext in self:
|
||||
router_type = ext.obj.get_type()
|
||||
if router_type in self.drivers:
|
||||
LOG.error(_("Type driver '%(new_driver)s' ignored because "
|
||||
"type driver '%(old_driver)s' is already "
|
||||
"registered for type '%(type)s'"),
|
||||
{'new_driver': ext.name,
|
||||
'old_driver': self.drivers[router_type].name,
|
||||
'type': router_type})
|
||||
else:
|
||||
self.drivers[router_type] = ext
|
||||
LOG.info(_("Registered types: %s"), self.drivers.keys())
|
||||
|
||||
def _check_tenant_router_types(self, types):
|
||||
self.tenant_router_types = []
|
||||
for router_type in types:
|
||||
if router_type in self.drivers:
|
||||
self.tenant_router_types.append(router_type)
|
||||
else:
|
||||
msg = _("No type driver for tenant router_type: %s. "
|
||||
"Service terminated!") % router_type
|
||||
LOG.error(msg)
|
||||
raise SystemExit(msg)
|
||||
LOG.info(_("Tenant router_types: %s"), self.tenant_router_types)
|
||||
|
||||
def get_tenant_router_driver(self, context, router_type):
|
||||
driver = self.drivers.get(router_type)
|
||||
if driver:
|
||||
return driver.obj
|
||||
raise nsx_exc.NoRouterAvailable()
|
||||
|
||||
def decide_tenant_router_type(self, context, router_type=None):
|
||||
if router_type is None:
|
||||
for rt in self.tenant_router_types:
|
||||
driver = self.drivers.get(rt)
|
||||
if driver:
|
||||
return rt
|
||||
raise nsx_exc.NoRouterAvailable()
|
||||
elif context.is_admin:
|
||||
driver = self.drivers.get(router_type)
|
||||
if driver:
|
||||
return router_type
|
||||
elif router_type in self.tenant_router_types:
|
||||
driver = self.drivers.get(router_type)
|
||||
if driver:
|
||||
return router_type
|
||||
raise nsx_exc.NoRouterAvailable()
|
@ -58,13 +58,12 @@ from vmware_nsx.neutron.plugins import vmware
|
||||
from vmware_nsx.neutron.plugins.vmware.common import config # noqa
|
||||
from vmware_nsx.neutron.plugins.vmware.common import utils as c_utils
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import (
|
||||
distributedrouter as dist_rtr)
|
||||
routertype as rt_rtr)
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import db as nsx_db
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import nsxv_db
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import vnic_index_db
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins import managers
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins import nsx_v_md_proxy
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield.common import (
|
||||
constants as vcns_const)
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield.common import (
|
||||
exceptions as vsh_exc)
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield import edge_utils
|
||||
@ -77,7 +76,7 @@ PORTGROUP_PREFIX = 'dvportgroup'
|
||||
|
||||
class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
db_base_plugin_v2.NeutronDbPluginV2,
|
||||
dist_rtr.DistributedRouter_mixin,
|
||||
rt_rtr.RouterType_mixin,
|
||||
external_net_db.External_net_db_mixin,
|
||||
extraroute_db.ExtraRoute_db_mixin,
|
||||
l3_gwmode_db.L3_NAT_db_mixin,
|
||||
@ -98,6 +97,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
"extraroute",
|
||||
"router",
|
||||
"security-group",
|
||||
"nsxv-router-type",
|
||||
"vnic-index",
|
||||
"advanced-service-providers"]
|
||||
|
||||
@ -130,6 +130,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
self.sg_container_id = self._create_security_group_container()
|
||||
self._validate_config()
|
||||
self._create_cluster_default_fw_rules()
|
||||
self._router_managers = managers.RouterTypeManager(self)
|
||||
|
||||
has_metadata_cfg = (
|
||||
cfg.CONF.nsxv.nova_metadata_ips
|
||||
@ -151,6 +152,37 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
h, container_id = self.nsx_v.vcns.create_security_group(container)
|
||||
return container_id
|
||||
|
||||
def _find_router_driver(self, context, router_id):
|
||||
router_db = self._get_router(context, router_id)
|
||||
return self._get_router_driver(context, router_db)
|
||||
|
||||
def _get_router_driver(self, context, router_db):
|
||||
router_type_dict = {}
|
||||
self._extend_nsx_router_dict(router_type_dict, router_db)
|
||||
router_type = None
|
||||
if router_type_dict.get("distributed", False):
|
||||
router_type = "distributed"
|
||||
else:
|
||||
router_type = router_type_dict.get("router_type")
|
||||
return self._router_managers.get_tenant_router_driver(
|
||||
context, router_type)
|
||||
|
||||
def _decide_router_type(self, context, r):
|
||||
router_type = None
|
||||
if attr.is_attr_set(r.get("distributed")) and r.get("distributed"):
|
||||
router_type = "distributed"
|
||||
elif attr.is_attr_set(r.get("router_type")):
|
||||
router_type = r.get("router_type")
|
||||
|
||||
router_type = self._router_managers.decide_tenant_router_type(
|
||||
context, router_type)
|
||||
if router_type == "distributed":
|
||||
r["distributed"] = True
|
||||
r["router_type"] = "exclusive"
|
||||
else:
|
||||
r["distributed"] = False
|
||||
r["router_type"] = router_type
|
||||
|
||||
def _create_cluster_default_fw_rules(self):
|
||||
# default cluster rules
|
||||
rules = [{'name': 'Default DHCP rule for OS Security Groups',
|
||||
@ -1160,34 +1192,25 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
gw_info = self._extract_external_gw(context, router)
|
||||
lrouter = super(NsxVPluginV2, self).create_router(context, router)
|
||||
r = router['router']
|
||||
distributed = r.get('distributed')
|
||||
r['distributed'] = attr.is_attr_set(distributed) and distributed
|
||||
self.edge_manager.create_lrouter(context, lrouter,
|
||||
dist=r['distributed'])
|
||||
self._decide_router_type(context, r)
|
||||
with context.session.begin(subtransactions=True):
|
||||
router_db = self._get_router(context, lrouter['id'])
|
||||
self._process_nsx_router_create(context, router_db, r)
|
||||
router_driver = self._get_router_driver(context, router_db)
|
||||
router_driver.create_router(
|
||||
context, lrouter,
|
||||
allow_metadata=(allow_metadata and self.metadata_proxy_handler))
|
||||
if gw_info is not None:
|
||||
self._update_router_gw_info(context, lrouter['id'], gw_info)
|
||||
if (not r['distributed']
|
||||
and allow_metadata
|
||||
and self.metadata_proxy_handler):
|
||||
self.metadata_proxy_handler.configure_router_edge(lrouter['id'])
|
||||
router_driver._update_router_gw_info(
|
||||
context, lrouter['id'], gw_info)
|
||||
return self.get_router(context, lrouter['id'])
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
# TODO(berlin): admin_state_up update
|
||||
if router['router'].get('admin_state_up') is False:
|
||||
LOG.warning(_LW("admin_state_up=False router is not supported."))
|
||||
gw_info = self._extract_external_gw(context, router, is_extract=False)
|
||||
router_updated = super(NsxVPluginV2, self).update_router(
|
||||
context, router_id, router)
|
||||
# here is used to handle routes which tenant updates.
|
||||
if gw_info is None:
|
||||
router_db = self._get_router(context, router_id)
|
||||
nexthop = self._get_external_attachment_info(context, router_db)[2]
|
||||
self._update_routes(context, router_id, nexthop)
|
||||
return router_updated
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
return router_driver.update_router(context, router_id, router)
|
||||
|
||||
def _check_router_in_use(self, context, router_id):
|
||||
with context.session.begin(subtransactions=True):
|
||||
@ -1207,10 +1230,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
|
||||
def delete_router(self, context, id):
|
||||
self._check_router_in_use(context, id)
|
||||
distributed = self.get_router(context, id).get('distributed', False)
|
||||
if self.metadata_proxy_handler and not distributed:
|
||||
self.metadata_proxy_handler.cleanup_router_edge(id)
|
||||
self.edge_manager.delete_lrouter(context, id, dist=distributed)
|
||||
router_driver = self._find_router_driver(context, id)
|
||||
router_driver.delete_router(context, id)
|
||||
super(NsxVPluginV2, self).delete_router(context, id)
|
||||
|
||||
def _get_external_attachment_info(self, context, router):
|
||||
@ -1258,101 +1279,9 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
edge_utils.update_routes(self.nsx_v, context, router_id,
|
||||
routes, nexthop)
|
||||
|
||||
def _update_routes_on_plr(self, context, router_id, plr_id, newnexthop):
|
||||
subnets = self._find_router_subnets_cidrs(
|
||||
context.elevated(), router_id)
|
||||
routes = []
|
||||
for subnet in subnets:
|
||||
routes.append({
|
||||
'destination': subnet,
|
||||
'nexthop': (vcns_const.INTEGRATION_LR_IPADDRESS.
|
||||
split('/')[0])
|
||||
})
|
||||
edge_utils.update_routes_on_plr(self.nsx_v, context,
|
||||
plr_id, router_id, routes,
|
||||
nexthop=newnexthop)
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info):
|
||||
router = self._get_router(context, router_id)
|
||||
org_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
org_enable_snat = router.enable_snat
|
||||
orgaddr, orgmask, orgnexthop = self._get_external_attachment_info(
|
||||
context, router)
|
||||
|
||||
super(NsxVPluginV2, self)._update_router_gw_info(
|
||||
context, router_id, info, router=router)
|
||||
|
||||
new_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
new_enable_snat = router.enable_snat
|
||||
newaddr, newmask, newnexthop = self._get_external_attachment_info(
|
||||
context, router)
|
||||
|
||||
router_dict = self._make_router_dict(router)
|
||||
if not router_dict.get('distributed', False):
|
||||
if new_ext_net_id != org_ext_net_id and orgnexthop:
|
||||
# network changed, so need to remove default gateway before
|
||||
# vnic can be configured
|
||||
LOG.debug("Delete default gateway %s", orgnexthop)
|
||||
edge_utils.clear_gateway(self.nsx_v, context, router_id)
|
||||
# Delete SNAT rules
|
||||
if org_enable_snat:
|
||||
edge_utils.clear_nat_rules(self.nsx_v, context, router_id)
|
||||
|
||||
# Update external vnic if addr or mask is changed
|
||||
if orgaddr != newaddr or orgmask != newmask:
|
||||
edge_utils.update_external_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
new_ext_net_id, newaddr, newmask)
|
||||
|
||||
# Update SNAT rules if ext net changed and snat enabled
|
||||
# or ext net not changed but snat is changed.
|
||||
if ((new_ext_net_id != org_ext_net_id and
|
||||
newnexthop and new_enable_snat) or
|
||||
(new_ext_net_id == org_ext_net_id and
|
||||
new_enable_snat != org_enable_snat)):
|
||||
self._update_nat_rules(context, router)
|
||||
|
||||
# Update static routes in all.
|
||||
self._update_routes(context, router_id, newnexthop)
|
||||
else:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
|
||||
if not new_ext_net_id:
|
||||
if plr_id:
|
||||
# delete all plr relative conf
|
||||
self.edge_manager.delete_plr_by_tlr_id(
|
||||
context, plr_id, router_id)
|
||||
else:
|
||||
# Connecting one plr to the tlr if new_ext_net_id is not None.
|
||||
if not plr_id:
|
||||
plr_id = self.edge_manager.create_plr_with_tlr_id(
|
||||
context, router_id, router_dict.get('name'))
|
||||
if new_ext_net_id != org_ext_net_id and orgnexthop:
|
||||
# network changed, so need to remove default gateway and
|
||||
# all static routes before vnic can be configured
|
||||
edge_utils.clear_gateway(self.nsx_v, context, plr_id)
|
||||
# Delete SNAT rules
|
||||
if org_enable_snat:
|
||||
edge_utils.clear_nat_rules(self.nsx_v, context, plr_id)
|
||||
|
||||
# Update external vnic if addr or mask is changed
|
||||
if orgaddr != newaddr or orgmask != newmask:
|
||||
edge_utils.update_external_interface(
|
||||
self.nsx_v, context, plr_id,
|
||||
new_ext_net_id, newaddr, newmask)
|
||||
|
||||
# Update SNAT rules if ext net changed and snat enabled
|
||||
# or ext net not changed but snat is changed.
|
||||
if ((new_ext_net_id != org_ext_net_id and
|
||||
newnexthop and new_enable_snat) or
|
||||
(new_ext_net_id == org_ext_net_id and
|
||||
new_enable_snat != org_enable_snat)):
|
||||
self._update_nat_rules(context, router, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self._update_subnets_and_dnat_firewall(
|
||||
context, router, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, newnexthop)
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
router_driver._update_router_gw_info(context, router_id, info)
|
||||
|
||||
def _get_router_interface_ports_by_network(
|
||||
self, context, router_id, network_id):
|
||||
@ -1429,96 +1358,14 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
self.nsx_v, context, router_id, snat, dnat)
|
||||
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
info = super(NsxVPluginV2, self).add_router_interface(
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
return router_driver.add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
|
||||
router_db = self._get_router(context, router_id)
|
||||
router = self._make_router_dict(router_db)
|
||||
distributed = router.get('distributed', False)
|
||||
subnet = self.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
|
||||
address_groups = self._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
if not distributed:
|
||||
edge_utils.update_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
else:
|
||||
try:
|
||||
edge_utils.add_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
except n_exc.BadRequest:
|
||||
with excutils.save_and_reraise_exception():
|
||||
super(NsxVPluginV2, self).remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
# Update edge's firewall rules to accept subnets flows.
|
||||
self._update_subnets_and_dnat_firewall(context, router_db)
|
||||
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
if not distributed:
|
||||
# Update Nat rules on external edge vnic
|
||||
self._update_nat_rules(context, router_db)
|
||||
else:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(
|
||||
context, router_id)
|
||||
self._update_nat_rules(context, router_db, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self._update_subnets_and_dnat_firewall(
|
||||
context, router_db, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
nexthop = self._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, nexthop)
|
||||
return info
|
||||
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
info = super(NsxVPluginV2, self).remove_router_interface(
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
return router_driver.remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
router_db = self._get_router(context, router_id)
|
||||
router = self._make_router_dict(router_db)
|
||||
distributed = router.get('distributed', False)
|
||||
|
||||
subnet = self.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
if not distributed:
|
||||
# First update nat rules
|
||||
self._update_nat_rules(context, router_db)
|
||||
else:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(
|
||||
context, router_id)
|
||||
self._update_nat_rules(context, router_db, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self._update_subnets_and_dnat_firewall(
|
||||
context, router_db, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
nexthop = self._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
nexthop = self._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, nexthop)
|
||||
|
||||
ports = self._get_router_interface_ports_by_network(
|
||||
context, router_id, network_id)
|
||||
self._update_subnets_and_dnat_firewall(context, router_db)
|
||||
# No subnet on the network connects to the edge vnic
|
||||
if not ports:
|
||||
edge_utils.delete_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
dist=distributed)
|
||||
else:
|
||||
address_groups = self._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
if not distributed:
|
||||
edge_utils.update_internal_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
address_groups)
|
||||
else:
|
||||
edge_utils.update_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
return info
|
||||
|
||||
def _get_floatingips_by_router(self, context, router_id):
|
||||
fip_qry = context.session.query(l3_db.FloatingIP)
|
||||
@ -1546,6 +1393,10 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
floatingip_db['status'] = status
|
||||
self.update_floatingip_status(context, floatingip_db['id'], status)
|
||||
|
||||
def _update_edge_router(self, context, router_id):
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
router_driver._update_edge_router(context, router_id)
|
||||
|
||||
def create_floatingip(self, context, floatingip):
|
||||
fip_db = super(NsxVPluginV2, self).create_floatingip(
|
||||
context, floatingip)
|
||||
@ -1583,19 +1434,6 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
self._set_floatingip_status(context, fip_db)
|
||||
return fip_db
|
||||
|
||||
def _update_edge_router(self, context, router_id):
|
||||
router = self._get_router(context, router_id)
|
||||
distributed = self._make_router_dict(router).get(
|
||||
'distributed', False)
|
||||
if distributed:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
|
||||
else:
|
||||
plr_id = None
|
||||
self._update_external_interface(context, router, router_id=plr_id)
|
||||
self._update_nat_rules(context, router, router_id=plr_id)
|
||||
self._update_subnets_and_dnat_firewall(context, router,
|
||||
router_id=plr_id)
|
||||
|
||||
def delete_floatingip(self, context, id):
|
||||
fip_db = self._get_floatingip(context, id)
|
||||
router_id = None
|
||||
@ -1603,21 +1441,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
router_id = fip_db.router_id
|
||||
super(NsxVPluginV2, self).delete_floatingip(context, id)
|
||||
if router_id:
|
||||
router = self._get_router(context, router_id)
|
||||
distributed = self._make_router_dict(router).get(
|
||||
'distributed', False)
|
||||
if not distributed:
|
||||
self._update_subnets_and_dnat_firewall(context, router)
|
||||
self._update_nat_rules(context, router)
|
||||
self._update_external_interface(context, router)
|
||||
else:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context,
|
||||
router_id)
|
||||
self._update_subnets_and_dnat_firewall(
|
||||
context, router, router_id=plr_id)
|
||||
self._update_nat_rules(context, router, router_id=plr_id)
|
||||
self._update_external_interface(
|
||||
context, router, router_id=plr_id)
|
||||
self._update_edge_router(context, router_id)
|
||||
|
||||
def disassociate_floatingips(self, context, port_id):
|
||||
router_id = None
|
||||
@ -1632,21 +1456,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
router_id = None
|
||||
super(NsxVPluginV2, self).disassociate_floatingips(context, port_id)
|
||||
if router_id:
|
||||
router = self._get_router(context, router_id)
|
||||
distributed = self._make_router_dict(router).get(
|
||||
'distributed', False)
|
||||
if not distributed:
|
||||
self._update_subnets_and_dnat_firewall(context, router)
|
||||
self._update_nat_rules(context, router)
|
||||
self._update_external_interface(context, router)
|
||||
else:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context,
|
||||
router_id)
|
||||
self._update_subnets_and_dnat_firewall(
|
||||
context, router, router_id=plr_id)
|
||||
self._update_nat_rules(context, router, router_id=plr_id)
|
||||
self._update_external_interface(
|
||||
context, router, router_id=plr_id)
|
||||
self._update_edge_router(context, router_id)
|
||||
|
||||
def _update_subnets_and_dnat_firewall(self, context, router,
|
||||
router_id=None, allow_external=True):
|
||||
@ -1659,8 +1469,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
fake_subnet_fw_rule = {
|
||||
'action': 'allow',
|
||||
'enabled': True,
|
||||
'source_ip_address': subnet_cidrs,
|
||||
'destination_ip_address': subnet_cidrs}
|
||||
'source_ip_address': sorted(subnet_cidrs),
|
||||
'destination_ip_address': sorted(subnet_cidrs)}
|
||||
fake_fw_rules.append(fake_subnet_fw_rule)
|
||||
_, dnat_rules = self._get_nat_rules(context, router)
|
||||
|
||||
@ -1674,7 +1484,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
fake_dnat_fw_rule = {
|
||||
'action': 'allow',
|
||||
'enabled': True,
|
||||
'destination_ip_address': dnat_cidrs}
|
||||
'destination_ip_address': sorted(dnat_cidrs)}
|
||||
fake_fw_rules.append(fake_dnat_fw_rule)
|
||||
# TODO(berlin): Add fw rules if fw service is supported
|
||||
fake_fw = {'firewall_rule_list': fake_fw_rules}
|
||||
|
@ -0,0 +1,66 @@
|
||||
# Copyright 2014 VMware, Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# 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 abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class RouterAbstractDriver(object):
|
||||
"""Abstract router driver that expose API for nsxv plugin."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_type(self):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_router(self, context, lrouter):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_router(self, context, router_id, router):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_router(self, context, router_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_routes(self, context, router_id, nexthop):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def _update_router_gw_info(self, context, router_id, info):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def _update_edge_router(self, context, router_id):
|
||||
pass
|
||||
|
||||
|
||||
class RouterBaseDriver(RouterAbstractDriver):
|
||||
|
||||
def __init__(self, plugin):
|
||||
self.plugin = plugin
|
||||
self.nsx_v = plugin.nsx_v
|
||||
self.edge_manager = plugin.edge_manager
|
@ -0,0 +1,194 @@
|
||||
# Copyright 2014 VMware, Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo.utils import excutils
|
||||
|
||||
from neutron.common import exceptions as n_exc
|
||||
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins import nsx_v
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers import (
|
||||
abstract_router_driver as router_driver)
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield.common import (
|
||||
constants as vcns_const)
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield import edge_utils
|
||||
|
||||
|
||||
class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
|
||||
def get_type(self):
|
||||
return "distributed"
|
||||
|
||||
def _update_routes_on_plr(self, context, router_id, plr_id, newnexthop):
|
||||
subnets = self.plugin._find_router_subnets_cidrs(
|
||||
context.elevated(), router_id)
|
||||
routes = []
|
||||
for subnet in subnets:
|
||||
routes.append({
|
||||
'destination': subnet,
|
||||
'nexthop': (vcns_const.INTEGRATION_LR_IPADDRESS.
|
||||
split('/')[0])
|
||||
})
|
||||
edge_utils.update_routes_on_plr(self.nsx_v, context,
|
||||
plr_id, router_id, routes,
|
||||
nexthop=newnexthop)
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
self.edge_manager.create_lrouter(context, lrouter, dist=True)
|
||||
# TODO(kobi) can't configure metadata service on VDR at present.
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
context, router_id, router)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
self.edge_manager.delete_lrouter(context, router_id, dist=True)
|
||||
|
||||
def update_routes(self, context, router_id, nexthop):
|
||||
# Since there may be an internal plr connected to the VDR affecting
|
||||
# static routes, static routes feature should be avoided on VDR now.
|
||||
pass
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info):
|
||||
router = self.plugin._get_router(context, router_id)
|
||||
org_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
org_enable_snat = router.enable_snat
|
||||
orgaddr, orgmask, orgnexthop = (
|
||||
self.plugin._get_external_attachment_info(
|
||||
context, router))
|
||||
|
||||
super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
|
||||
context, router_id, info, router=router)
|
||||
|
||||
new_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
new_enable_snat = router.enable_snat
|
||||
newaddr, newmask, newnexthop = (
|
||||
self.plugin._get_external_attachment_info(
|
||||
context, router))
|
||||
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
|
||||
if not new_ext_net_id:
|
||||
if plr_id:
|
||||
# delete all plr relative conf
|
||||
self.edge_manager.delete_plr_by_tlr_id(
|
||||
context, plr_id, router_id)
|
||||
else:
|
||||
# Connecting plr to the tlr if new_ext_net_id is not None.
|
||||
if not plr_id:
|
||||
plr_id = self.edge_manager.create_plr_with_tlr_id(
|
||||
context, router_id, router.get('name'))
|
||||
if new_ext_net_id != org_ext_net_id and orgnexthop:
|
||||
# network changed, so need to remove default gateway
|
||||
# and all static routes before vnic can be configured
|
||||
edge_utils.clear_gateway(self.nsx_v, context, plr_id)
|
||||
# Delete SNAT rules
|
||||
if org_enable_snat:
|
||||
edge_utils.clear_nat_rules(self.nsx_v, context,
|
||||
plr_id)
|
||||
|
||||
# Update external vnic if addr or mask is changed
|
||||
if orgaddr != newaddr or orgmask != newmask:
|
||||
edge_utils.update_external_interface(
|
||||
self.nsx_v, context, plr_id,
|
||||
new_ext_net_id, newaddr, newmask)
|
||||
|
||||
# Update SNAT rules if ext net changed and snat enabled
|
||||
# or ext net not changed but snat is changed.
|
||||
if ((new_ext_net_id != org_ext_net_id and
|
||||
newnexthop and new_enable_snat) or
|
||||
(new_ext_net_id == org_ext_net_id and
|
||||
new_enable_snat != org_enable_snat)):
|
||||
self.plugin._update_nat_rules(context, router, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self.plugin._update_subnets_and_dnat_firewall(
|
||||
context, router, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, newnexthop)
|
||||
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
subnet = self.plugin.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
try:
|
||||
edge_utils.add_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
network_id, address_groups)
|
||||
except n_exc.BadRequest:
|
||||
with excutils.save_and_reraise_exception():
|
||||
super(nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
# Update edge's firewall rules to accept subnets flows.
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
|
||||
self.plugin._update_nat_rules(context, router_db, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self.plugin._update_subnets_and_dnat_firewall(
|
||||
context, router_db, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
nexthop = self.plugin._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, nexthop)
|
||||
return info
|
||||
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
subnet = self.plugin.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(
|
||||
context, router_id)
|
||||
self.plugin._update_nat_rules(context, router_db, plr_id)
|
||||
# Open firewall flows on plr
|
||||
self.plugin._update_subnets_and_dnat_firewall(
|
||||
context, router_db, router_id=plr_id)
|
||||
# Update static routes of plr
|
||||
nexthop = self.plugin._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self._update_routes_on_plr(
|
||||
context, router_id, plr_id, nexthop)
|
||||
|
||||
ports = self.plugin._get_router_interface_ports_by_network(
|
||||
context, router_id, network_id)
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
# No subnet on the network connects to the edge vnic
|
||||
if not ports:
|
||||
edge_utils.delete_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
dist=True)
|
||||
else:
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
network_id, address_groups)
|
||||
return info
|
||||
|
||||
def _update_edge_router(self, context, router_id):
|
||||
router = self.plugin._get_router(context, router_id)
|
||||
plr_id = self.edge_manager.get_plr_by_tlr_id(context, router_id)
|
||||
self.plugin._update_external_interface(
|
||||
context, router, router_id=plr_id)
|
||||
self.plugin._update_nat_rules(context, router, router_id=plr_id)
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router,
|
||||
router_id=plr_id)
|
@ -0,0 +1,148 @@
|
||||
# Copyright 2014 VMware, Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.openstack.common import log as logging
|
||||
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins import nsx_v
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers import (
|
||||
abstract_router_driver as router_driver)
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield import edge_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
||||
|
||||
def get_type(self):
|
||||
return "exclusive"
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
self.edge_manager.create_lrouter(context, lrouter, dist=False)
|
||||
if allow_metadata:
|
||||
self.plugin.metadata_proxy_handler.configure_router_edge(
|
||||
lrouter['id'])
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
gw_info = self.plugin._extract_external_gw(context, router,
|
||||
is_extract=False)
|
||||
router_updated = super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
context, router_id, router)
|
||||
# here is used to handle routes which tenant updates.
|
||||
if gw_info is None:
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
nexthop = self.plugin._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self.update_routes(context, router_id, nexthop)
|
||||
return router_updated
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
self.edge_manager.delete_lrouter(context, router_id, dist=False)
|
||||
if self.plugin.metadata_proxy_handler:
|
||||
self.plugin.metadata_proxy_handler.cleanup_router_edge(router_id)
|
||||
|
||||
def update_routes(self, context, router_id, nexthop):
|
||||
self.plugin._update_routes(context, router_id, nexthop)
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info):
|
||||
router = self.plugin._get_router(context, router_id)
|
||||
org_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
org_enable_snat = router.enable_snat
|
||||
orgaddr, orgmask, orgnexthop = (
|
||||
self.plugin._get_external_attachment_info(
|
||||
context, router))
|
||||
|
||||
super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
|
||||
context, router_id, info, router=router)
|
||||
|
||||
new_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||
new_enable_snat = router.enable_snat
|
||||
newaddr, newmask, newnexthop = (
|
||||
self.plugin._get_external_attachment_info(
|
||||
context, router))
|
||||
|
||||
if new_ext_net_id != org_ext_net_id and orgnexthop:
|
||||
# network changed, so need to remove default gateway before
|
||||
# vnic can be configured
|
||||
LOG.debug("Delete default gateway %s", orgnexthop)
|
||||
edge_utils.clear_gateway(self.nsx_v, context, router_id)
|
||||
# Delete SNAT rules
|
||||
if org_enable_snat:
|
||||
edge_utils.clear_nat_rules(self.nsx_v, context, router_id)
|
||||
|
||||
# Update external vnic if addr or mask is changed
|
||||
if orgaddr != newaddr or orgmask != newmask:
|
||||
edge_utils.update_external_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
new_ext_net_id, newaddr, newmask)
|
||||
|
||||
# Update SNAT rules if ext net changed and snat enabled
|
||||
# or ext net not changed but snat is changed.
|
||||
if ((new_ext_net_id != org_ext_net_id and
|
||||
newnexthop and new_enable_snat) or
|
||||
(new_ext_net_id == org_ext_net_id and
|
||||
new_enable_snat != org_enable_snat)):
|
||||
self.plugin._update_nat_rules(context, router)
|
||||
|
||||
# Update static routes in all.
|
||||
self.plugin._update_routes(context, router_id, newnexthop)
|
||||
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
subnet = self.plugin.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
# Update edge's firewall rules to accept subnets flows.
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
# Update Nat rules on external edge vnic
|
||||
self.plugin._update_nat_rules(context, router_db)
|
||||
return info
|
||||
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
subnet = self.plugin.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
# First update nat rules
|
||||
self.plugin._update_nat_rules(context, router_db)
|
||||
ports = self.plugin._get_router_interface_ports_by_network(
|
||||
context, router_id, network_id)
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
# No subnet on the network connects to the edge vnic
|
||||
if not ports:
|
||||
edge_utils.delete_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
dist=False)
|
||||
else:
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_internal_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
address_groups)
|
||||
return info
|
||||
|
||||
def _update_edge_router(self, context, router_id):
|
||||
router = self.plugin._get_router(context, router_id)
|
||||
self.plugin._update_external_interface(context, router)
|
||||
self.plugin._update_nat_rules(context, router)
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router)
|
@ -0,0 +1,60 @@
|
||||
# Copyright 2014 VMware, Inc
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins import nsx_v
|
||||
from vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers import (
|
||||
abstract_router_driver as router_driver)
|
||||
|
||||
|
||||
class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
|
||||
def get_type(self):
|
||||
return "shared"
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
pass
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
context, router_id, router)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
pass
|
||||
|
||||
def update_routes(self, context, router_id, nexthop):
|
||||
#TODO(berlin) do non-exclusive router op.
|
||||
pass
|
||||
|
||||
def _update_router_gw_info(self, context, router_id, info):
|
||||
#TODO(berlin) do non-exclusive router op.
|
||||
router = self.plugin._get_router(context, router_id)
|
||||
super(nsx_v.NsxVPluginV2, self.plugin)._update_router_gw_info(
|
||||
context, router_id, info, router=router)
|
||||
pass
|
||||
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
#TODO(berlin): add router interface.
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
return info
|
||||
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
#TODO(berlin) do non-exclusive router op.
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
return info
|
||||
|
||||
def _update_edge_router(self, context, router_id):
|
||||
#TODO(berlin) do non-exclusive router op.
|
||||
pass
|
@ -223,6 +223,7 @@ class NsxVMetadataProxyHandler:
|
||||
'router': {
|
||||
'name': 'metadata_proxy_router',
|
||||
'admin_state_up': True,
|
||||
'router_type': 'exclusive',
|
||||
'tenant_id': None}}
|
||||
|
||||
rtr = self.nsxv_plugin.create_router(
|
||||
|
@ -142,7 +142,8 @@ class EdgeFirewallDriver(db_base_plugin_v2.NeutronDbPluginV2):
|
||||
vcns_rules.append(
|
||||
{'action': "accept",
|
||||
'enabled': True,
|
||||
'destination': {'vnicGroupId': ["external"]}})
|
||||
'destination': {'vnicGroupId': ["external"]},
|
||||
'ruleTag': ruleTag})
|
||||
return {
|
||||
'featureType': "firewall_4.0",
|
||||
'firewallRules': {
|
||||
|
@ -37,6 +37,8 @@ from neutron import manager
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.vmware.extensions import (
|
||||
vnicindex as ext_vnic_idx)
|
||||
from neutron.plugins.vmware.extensions import routertype as router_type
|
||||
|
||||
from neutron.tests.unit import _test_extension_portbindings as test_bindings
|
||||
import neutron.tests.unit.test_db_plugin as test_plugin
|
||||
import neutron.tests.unit.test_extension_allowedaddresspairs as test_addr_pair
|
||||
@ -45,6 +47,7 @@ import neutron.tests.unit.test_extension_portsecurity as test_psec
|
||||
import neutron.tests.unit.test_extension_security_group as ext_sg
|
||||
import neutron.tests.unit.test_l3_plugin as test_l3_plugin
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
from vmware_nsx.neutron.plugins.vmware.dbexts import nsxv_db
|
||||
from vmware_nsx.neutron.plugins.vmware.vshield.common import (
|
||||
constants as vcns_const)
|
||||
@ -1033,6 +1036,8 @@ class TestL3ExtensionManager(object):
|
||||
l3_ext_gw_mode.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
||||
dist_router.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
||||
router_type.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
# Finally add l3 resources to the global attribute map
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||
l3.RESOURCE_ATTRIBUTE_MAP)
|
||||
@ -1074,11 +1079,11 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxVPluginV2TestCase):
|
||||
ext_mgr = ext_mgr or TestL3ExtensionManager()
|
||||
super(L3NatTest, self).setUp(
|
||||
plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins)
|
||||
plugin_instance = manager.NeutronManager.get_plugin()
|
||||
self.plugin_instance = manager.NeutronManager.get_plugin()
|
||||
self._plugin_name = "%s.%s" % (
|
||||
plugin_instance.__module__,
|
||||
plugin_instance.__class__.__name__)
|
||||
self._plugin_class = plugin_instance.__class__
|
||||
self.plugin_instance.__module__,
|
||||
self.plugin_instance.__class__.__name__)
|
||||
self._plugin_class = self.plugin_instance.__class__
|
||||
|
||||
def tearDown(self):
|
||||
plugin = manager.NeutronManager.get_plugin()
|
||||
@ -1116,9 +1121,31 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxVPluginV2TestCase):
|
||||
self._delete('routers', router['router']['id'])
|
||||
|
||||
|
||||
class TestL3NatTestCase(L3NatTest,
|
||||
class TestExclusiveRouterTestCase(L3NatTest,
|
||||
test_l3_plugin.L3NatDBIntTestCase,
|
||||
NsxVPluginV2TestCase):
|
||||
def _create_router(self, fmt, tenant_id, name=None,
|
||||
admin_state_up=None, set_context=False,
|
||||
arg_list=None, **kwargs):
|
||||
data = {'router': {'tenant_id': tenant_id}}
|
||||
if name:
|
||||
data['router']['name'] = name
|
||||
if admin_state_up:
|
||||
data['router']['admin_state_up'] = admin_state_up
|
||||
for arg in (('admin_state_up', 'tenant_id') + (arg_list or ())):
|
||||
# Arg must be present and not empty
|
||||
if arg in kwargs and kwargs[arg]:
|
||||
data['router'][arg] = kwargs[arg]
|
||||
|
||||
data['router']['router_type'] = kwargs.get('router_type', 'exclusive')
|
||||
|
||||
router_req = self.new_create_request('routers', data, fmt)
|
||||
if set_context and tenant_id:
|
||||
# create a specific auth context for this request
|
||||
router_req.environ['neutron.context'] = context.Context(
|
||||
'', tenant_id)
|
||||
|
||||
return router_req.get_response(self.ext_api)
|
||||
|
||||
def _test_create_l3_ext_network(self, vlan_id=0):
|
||||
name = 'l3_ext_net'
|
||||
@ -1247,7 +1274,7 @@ class TestL3NatTestCase(L3NatTest,
|
||||
self._test_floatingip_with_invalid_create_port(self._plugin_name)
|
||||
|
||||
def test_floatingip_update(self):
|
||||
super(TestL3NatTestCase, self).test_floatingip_update(
|
||||
super(TestExclusiveRouterTestCase, self).test_floatingip_update(
|
||||
constants.FLOATINGIP_STATUS_DOWN)
|
||||
|
||||
def test_floatingip_disassociate(self):
|
||||
|
Loading…
Reference in New Issue
Block a user