NSXv3: router intf support

Change-Id: I9182bdb879be40370e905d417d7dba07f2ae1bf9
This commit is contained in:
linb 2015-08-18 11:25:08 +08:00
parent 8d26063364
commit c485c8af31
4 changed files with 100 additions and 39 deletions

View File

@ -35,8 +35,6 @@ LROUTER_TYPES = [LROUTERPORT_UPLINK,
LROUTERPORT_DOWNLINK,
LROUTERPORT_LINK]
ROUTER_INTF_PORT_NAME = "Tier1-RouterDownLinkPort"
def get_edge_cluster(edge_cluster_uuid):
resource = "edge-clusters/%s" % edge_cluster_uuid
@ -243,23 +241,6 @@ def get_logical_router_port_by_ls_id(logical_switch_id):
operation=err_msg)
def create_logical_router_port_by_ls_id(logical_router_id,
ls_id,
logical_switch_port_id,
resource_type,
address_groups):
try:
port = get_logical_router_port_by_ls_id(ls_id)
except nsx_exc.ResourceNotFound:
return create_logical_router_port(logical_router_id,
ROUTER_INTF_PORT_NAME,
resource_type,
logical_switch_port_id,
address_groups)
else:
return update_logical_router_port(port['id'], subnets=address_groups)
def create_logical_router_port(logical_router_id,
display_name,
resource_type,

View File

@ -34,6 +34,7 @@ MIN_EDGE_NODE_NUM = 1
TIER0_ROUTER_LINK_PORT_NAME = "TIER0-RouterLinkPort"
TIER1_ROUTER_LINK_PORT_NAME = "TIER1-RouterLinkPort"
ROUTER_INTF_PORT_NAME = "Tier1-RouterDownLinkPort"
def validate_tier0(tier0_groups_dict, tier0_uuid):
@ -126,3 +127,20 @@ def add_gw_snat_rule(logical_router_id, gw_ip):
def update_router_edge_cluster(nsx_router_id, edge_cluster_uuid):
return nsxlib.update_logical_router(nsx_router_id,
edge_cluster_id=edge_cluster_uuid)
def create_logical_router_intf_port_by_ls_id(logical_router_id,
ls_id,
logical_switch_port_id,
address_groups):
try:
port = nsxlib.get_logical_router_port_by_ls_id(ls_id)
except nsx_exc.ResourceNotFound:
return nsxlib.create_logical_router_port(logical_router_id,
ROUTER_INTF_PORT_NAME,
nsxlib.LROUTERPORT_DOWNLINK,
logical_switch_port_id,
address_groups)
else:
return nsxlib.update_logical_router_port(
port['id'], subnets=address_groups)

View File

@ -763,26 +763,54 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
address_groups.append(address_group)
return (ports, address_groups)
def _validate_multiple_subnets_diff_routers(self, context, network_id):
port_filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
'network_id': [network_id]}
intf_ports = self.get_ports(context.elevated(), filters=port_filters)
router_ids = [port['device_id'] for port in intf_ports]
router_id_set = set(router_ids)
if len(router_id_set) >= 2:
err_msg = _("Subnets on network %s cannot be attached to "
"different routers") % network_id
raise n_exc.InvalidInput(error_message=err_msg)
def add_router_interface(self, context, router_id, interface_info):
# TODO(berlin): disallow multiple subnets attached to different routers
info = super(NsxV3Plugin, self).add_router_interface(
context, router_id, interface_info)
subnet = self.get_subnet(context, info['subnet_ids'][0])
port = self.get_port(context, info['port_id'])
network_id = subnet['network_id']
nsx_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
context.session, port['id'])
try:
subnet = self.get_subnet(context, info['subnet_ids'][0])
port = self.get_port(context, info['port_id'])
network_id = subnet['network_id']
# disallow multiple subnets belong to same network being attached
# to different routers
self._validate_multiple_subnets_diff_routers(context, network_id)
nsx_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
context.session, port['id'])
nsx_router_id = nsx_db.get_nsx_router_id(context.session,
router_id)
_ports, address_groups = self._get_ports_and_address_groups(
context, router_id, network_id)
nsxlib.create_logical_router_port_by_ls_id(
logical_router_id=nsx_router_id,
ls_id=nsx_net_id,
logical_switch_port_id=nsx_port_id,
resource_type="LogicalRouterDownLinkPort",
address_groups=address_groups)
nsx_router_id = nsx_db.get_nsx_router_id(context.session,
router_id)
_ports, address_groups = self._get_ports_and_address_groups(
context, router_id, network_id)
routerlib.create_logical_router_intf_port_by_ls_id(
logical_router_id=nsx_router_id,
ls_id=nsx_net_id,
logical_switch_port_id=nsx_port_id,
address_groups=address_groups)
router_db = self._get_router(context, router_id)
if router_db.gw_port and not router_db.enable_snat:
# TODO(berlin): Announce the subnet on tier0 if enable_snat
# is False
pass
except n_exc.InvalidInput:
with excutils.save_and_reraise_exception():
super(NsxV3Plugin, self).remove_router_interface(
context, router_id, interface_info)
except nsx_exc.ManagerError:
with excutils.save_and_reraise_exception():
self.remove_router_interface(
context, router_id, interface_info)
return info
def remove_router_interface(self, context, router_id, interface_info):
@ -816,6 +844,12 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id,
subnet_id=subnet_id)
try:
# TODO(berlin): Revocate announce the subnet on tier0 if
# enable_snat is False
router_db = self._get_router(context, router_id)
if router_db.gw_port and not router_db.enable_snat:
pass
nsx_net_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
context.session, port_id)
subnet = self.get_subnet(context, subnet_id)

View File

@ -18,6 +18,7 @@ from oslo_config import cfg
import six
from neutron.api.v2 import attributes
from neutron.common import exceptions as n_exc
from neutron import context
from neutron.extensions import external_net
from neutron.extensions import extraroute
@ -188,11 +189,11 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxPluginV3TestCase):
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__
nsxlib.create_logical_port = self.v3_mock.create_logical_port
nsxlib.create_logical_router = self.v3_mock.create_logical_router
nsxlib.update_logical_router = self.v3_mock.update_logical_router
@ -251,6 +252,33 @@ class TestL3NatTestCase(L3NatTest,
def test_floatingip_with_invalid_create_port(self):
self._test_floatingip_with_invalid_create_port(self._plugin_name)
def test_routes_update_for_multiple_routers(self):
self.skipTest('not supported')
def test_floatingip_multi_external_one_internal(self):
self.skipTest('not supported')
def test_multiple_subnets_on_different_routers(self):
with self.network() as network:
with self.subnet(network=network) as s1,\
self.subnet(network=network,
cidr='11.0.0.0/24') as s2,\
self.router() as r1,\
self.router() as r2:
self._router_interface_action('add', r1['router']['id'],
s1['subnet']['id'], None)
self.assertRaises(n_exc.InvalidInput,
self.plugin_instance.add_router_interface,
context.get_admin_context(),
r2['router']['id'],
{'subnet_id': s2['subnet']['id']})
self._router_interface_action('remove', r1['router']['id'],
s1['subnet']['id'], None)
self._router_interface_action('add', r2['router']['id'],
s2['subnet']['id'], None)
self._router_interface_action('remove', r2['router']['id'],
s2['subnet']['id'], None)
class ExtGwModeTestCase(L3NatTest,
test_ext_gw_mode.ExtGwModeIntTestCase):