NSX|T: Optional distinct edge cluster uuid for T1 router

Allowing the user to define a different edge cluster UUID than
the one defined by default, allowing the ability to define another
cluster for the T1 logical router.

Change-Id: I7976a90b2134a53c3ff80e5f0785f999c05137d3
Signed-off-by: Michal Kelner Mishali <mkelnermishal@vmware.com>
This commit is contained in:
Michal Kelner Mishali 2018-12-12 14:52:43 +02:00
parent e5649bc23c
commit d2a44b76a3
4 changed files with 66 additions and 13 deletions

View File

@ -378,6 +378,10 @@ nsx_v3_and_p = [
help=_("List of nameservers to configure for the DHCP " help=_("List of nameservers to configure for the DHCP "
"binding entries. These will be used if there are no " "binding entries. These will be used if there are no "
"nameservers defined on the subnet.")), "nameservers defined on the subnet.")),
cfg.StrOpt('edge_cluster',
help=_("(Optional) Specifying an edge cluster for Tier1 "
"routers to connect other that the one connected to"
" the Tier0 router")),
] ]
nsx_v3_opts = nsx_v3_and_p + [ nsx_v3_opts = nsx_v3_and_p + [
@ -916,6 +920,10 @@ nsxv3_az_opts = [
help=_("Name or UUID of the default tier0 router that will be " help=_("Name or UUID of the default tier0 router that will be "
"used for connecting to tier1 logical routers and " "used for connecting to tier1 logical routers and "
"configuring external networks")), "configuring external networks")),
cfg.StrOpt('edge_cluster',
help=_("(Optional) Specifying an edge cluster for Tier1 "
"routers to connect other that the one connected to"
" the Tier0 router")),
] ]
nsx_tvd_opts = [ nsx_tvd_opts = [

View File

@ -40,6 +40,10 @@ class NsxV3AvailabilityZone(v3_az.NsxV3AvailabilityZone):
if dhcp_relay_service: if dhcp_relay_service:
self.dhcp_relay_service = dhcp_relay_service self.dhcp_relay_service = dhcp_relay_service
edge_cluster = az_info.get('edge_cluster')
if edge_cluster:
self.edge_cluster = edge_cluster
def init_defaults(self): def init_defaults(self):
# use the default configuration # use the default configuration
self.metadata_proxy = cfg.CONF.nsx_v3.metadata_proxy self.metadata_proxy = cfg.CONF.nsx_v3.metadata_proxy
@ -52,10 +56,25 @@ class NsxV3AvailabilityZone(v3_az.NsxV3AvailabilityZone):
self.switching_profiles = cfg.CONF.nsx_v3.switching_profiles self.switching_profiles = cfg.CONF.nsx_v3.switching_profiles
self.dhcp_relay_service = cfg.CONF.nsx_v3.dhcp_relay_service self.dhcp_relay_service = cfg.CONF.nsx_v3.dhcp_relay_service
self.default_tier0_router = cfg.CONF.nsx_v3.default_tier0_router self.default_tier0_router = cfg.CONF.nsx_v3.default_tier0_router
self.edge_cluster = cfg.CONF.nsx_v3.edge_cluster
def translate_configured_names_to_uuids(self, nsxlib): def translate_configured_names_to_uuids(self, nsxlib):
# Mandatory configurations (in AZ or inherited from global values) # Mandatory configurations (in AZ or inherited from global values)
# Unless this is the default AZ, and metadata is disabled. # Unless this is the default AZ, and metadata is disabled.
if self.edge_cluster:
edge_cluster_uuid = None
if cfg.CONF.nsx_v3.init_objects_by_tags:
# Find the edge cluster by its tag
edge_cluster_uuid = nsxlib.get_id_by_resource_and_tag(
nsxlib.edge_cluster.resource_type,
cfg.CONF.nsx_v3.search_objects_scope,
self.edge_cluster)
if not edge_cluster_uuid:
edge_cluster_uuid = (nsxlib.edge_cluster
.get_id_by_name_or_id(self.edge_cluster))
self._edge_cluster_uuid = edge_cluster_uuid
else:
self._edge_cluster_uuid = None
if self.dhcp_profile: if self.dhcp_profile:
dhcp_id = None dhcp_id = None
if cfg.CONF.nsx_v3.init_objects_by_tags: if cfg.CONF.nsx_v3.init_objects_by_tags:

View File

@ -879,7 +879,15 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
return self.conn.consume_in_threads() return self.conn.consume_in_threads()
def _get_edge_cluster(self, tier0_uuid): def _get_router_az_obj(self, router):
l3_attrs_db.ExtraAttributesMixin._extend_extra_router_dict(
router, router)
return self.get_router_az(router)
def _get_edge_cluster(self, tier0_uuid, router):
az = self._get_router_az_obj(router)
if az and az._edge_cluster_uuid:
return az._edge_cluster_uuid
if (not self.tier0_groups_dict.get(tier0_uuid) or not self. if (not self.tier0_groups_dict.get(tier0_uuid) or not self.
tier0_groups_dict[tier0_uuid].get('edge_cluster_uuid')): tier0_groups_dict[tier0_uuid].get('edge_cluster_uuid')):
self.nsxlib.router.validate_tier0(self.tier0_groups_dict, self.nsxlib.router.validate_tier0(self.tier0_groups_dict,
@ -3216,7 +3224,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
def create_service_router(self, context, router_id): def create_service_router(self, context, router_id):
router = self._get_router(context, router_id) router = self._get_router(context, router_id)
tier0_uuid = self._get_tier0_uuid_by_router(context, router) tier0_uuid = self._get_tier0_uuid_by_router(context, router)
edge_cluster_uuid = self._get_edge_cluster(tier0_uuid) edge_cluster_uuid = self._get_edge_cluster(tier0_uuid, router)
nsx_router_id = nsx_db.get_nsx_router_id(context.session, nsx_router_id = nsx_db.get_nsx_router_id(context.session,
router_id) router_id)
self.nsxlib.router.update_router_edge_cluster(nsx_router_id, self.nsxlib.router.update_router_edge_cluster(nsx_router_id,
@ -3241,7 +3249,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
router_subnets = self._find_router_subnets( router_subnets = self._find_router_subnets(
context.elevated(), router_id) context.elevated(), router_id)
if info and info.get('network_id'): if info and info.get('network_id'):
new_tier0_uuid = self._get_tier0_uuid_by_net_id(context.elevated(), new_tier0_uuid = self._get_tier0_uuid_by_net_id(context.elevated(),
info['network_id']) info['network_id'])
@ -3482,11 +3489,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
def get_router_availability_zones(self, router): def get_router_availability_zones(self, router):
"""Return availability zones which a router belongs to.""" """Return availability zones which a router belongs to."""
# add the hints to the structure first return [self._get_router_az_obj(router).name]
l3_attrs_db.ExtraAttributesMixin._extend_extra_router_dict(
router, router)
# get the availability zones from the hints
return [self.get_router_az(router).name]
def _update_router_wrapper(self, context, router_id, router): def _update_router_wrapper(self, context, router_id, router):
if cfg.CONF.api_replay_mode: if cfg.CONF.api_replay_mode:

View File

@ -206,11 +206,6 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
mock_ensure_global_sg_placeholder = mock.patch.object( mock_ensure_global_sg_placeholder = mock.patch.object(
nsx_plugin.NsxV3Plugin, '_ensure_global_sg_placeholder') nsx_plugin.NsxV3Plugin, '_ensure_global_sg_placeholder')
mock_ensure_global_sg_placeholder.start() mock_ensure_global_sg_placeholder.start()
mock_get_edge_cluster = mock.patch.object(
nsx_plugin.NsxV3Plugin, '_get_edge_cluster',
return_value=uuidutils.generate_uuid())
mock_get_edge_cluster.start()
mock.patch( mock.patch(
'neutron_lib.rpc.Connection.consume_in_threads', 'neutron_lib.rpc.Connection.consume_in_threads',
return_value=[]).start() return_value=[]).start()
@ -223,6 +218,10 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
_mock_nsx_backend_calls() _mock_nsx_backend_calls()
self.setup_conf_overrides() self.setup_conf_overrides()
self.mock_get_edge_cluster = mock.patch.object(
nsx_plugin.NsxV3Plugin, '_get_edge_cluster',
return_value=uuidutils.generate_uuid())
self.mock_get_edge_cluster.start()
self.mock_plugin_methods() self.mock_plugin_methods()
# ignoring the given plugin and use the nsx-v3 one # ignoring the given plugin and use the nsx-v3 one
if not plugin.endswith('NsxTVDPlugin'): if not plugin.endswith('NsxTVDPlugin'):
@ -3005,6 +3004,30 @@ class TestL3NatTestCase(L3NatTest,
self._test_route_update_illegal('0.0.0.0/0') self._test_route_update_illegal('0.0.0.0/0')
self._test_route_update_illegal('0.0.0.0/16') self._test_route_update_illegal('0.0.0.0/16')
def test_update_router_distinct_edge_cluster(self):
self.mock_get_edge_cluster.stop()
edge_cluster = uuidutils.generate_uuid()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibEdgeCluster."
"get_id_by_name_or_id",
return_value=edge_cluster).start()
cfg.CONF.set_override('edge_cluster', edge_cluster, 'nsx_v3')
with self.address_scope(name='as1') as addr_scope, \
self._create_l3_ext_network() as ext_net:
ext_subnet = self._prepare_external_subnet_on_address_scope(
ext_net, addr_scope)
# create a router with this gateway
with self.router() as r, \
self._mock_add_remove_service_router() as change_sr:
router_id = r['router']['id']
self.plugin.init_availability_zones()
for az in self.plugin.get_azs_list():
az.translate_configured_names_to_uuids(self.plugin.nsxlib)
self._add_external_gateway_to_router(
router_id, ext_subnet['network_id'])
change_sr.assert_called_once_with(mock.ANY, edge_cluster)
class ExtGwModeTestCase(test_ext_gw_mode.ExtGwModeIntTestCase, class ExtGwModeTestCase(test_ext_gw_mode.ExtGwModeIntTestCase,
L3NatTest): L3NatTest):