From 391d0983b77b11643d526aa424a8b9b6c58105f9 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Thu, 16 Mar 2017 12:04:10 +0200 Subject: [PATCH] NSX-V3: add transport zones to availability zones default_overlay_tz and default_vlan_tz will be added as optional parameres for each AZ for provider networks creation Change-Id: I3cedcc5f797b31c4659f96d318b2281677d308ec --- vmware_nsx/common/config.py | 12 +++++ .../plugins/nsx_v3/availability_zones.py | 23 +++++++++ vmware_nsx/plugins/nsx_v3/plugin.py | 50 +++++++------------ .../unit/nsx_v3/test_availability_zones.py | 12 ++++- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/vmware_nsx/common/config.py b/vmware_nsx/common/config.py index ad0d78cad5..cf96589f05 100644 --- a/vmware_nsx/common/config.py +++ b/vmware_nsx/common/config.py @@ -756,6 +756,18 @@ nsxv3_az_opts = [ help=_("(Optional) List of nameservers to configure for the " "DHCP binding entries. These will be used if there are " "no nameservers defined on the subnet.")), + cfg.StrOpt('default_overlay_tz', + help=_("(Optional) This is the name or UUID of the default NSX " + "overlay transport zone that will be used for creating " + "tunneled isolated Neutron networks. It needs to be " + "created in NSX before starting Neutron with the NSX " + "plugin.")), + cfg.StrOpt('default_vlan_tz', + help=_("(Optional) Only required when creating VLAN or flat " + "provider networks. Name or UUID of default NSX VLAN " + "transport zone that will be used for bridging between " + "Neutron networks, if no physical network has been " + "specified")), ] # Register the configuration options diff --git a/vmware_nsx/plugins/nsx_v3/availability_zones.py b/vmware_nsx/plugins/nsx_v3/availability_zones.py index e8b36d86c8..d5d060c9ed 100644 --- a/vmware_nsx/plugins/nsx_v3/availability_zones.py +++ b/vmware_nsx/plugins/nsx_v3/availability_zones.py @@ -66,6 +66,14 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone): if self.nameservers is None: self.nameservers = cfg.CONF.nsx_v3.nameservers + self.default_overlay_tz = az_info.get('default_overlay_tz') + if self.default_overlay_tz is None: + self.default_overlay_tz = cfg.CONF.nsx_v3.default_overlay_tz + + self.default_vlan_tz = az_info.get('default_vlan_tz') + if self.default_vlan_tz is None: + self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz + def init_default_az(self): # use the default configuration self.metadata_proxy = cfg.CONF.nsx_v3.metadata_proxy @@ -73,8 +81,11 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone): self.native_metadata_route = cfg.CONF.nsx_v3.native_metadata_route self.dns_domain = cfg.CONF.nsx_v3.dns_domain self.nameservers = cfg.CONF.nsx_v3.nameservers + self.default_overlay_tz = cfg.CONF.nsx_v3.default_overlay_tz + self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz def translate_configured_names_to_uuids(self, nsxlib): + # Mandatory configurations (in AZ or inherited from global values) dhcp_id = nsxlib.native_dhcp_profile.get_id_by_name_or_id( self.dhcp_profile) self._native_dhcp_profile_uuid = dhcp_id @@ -83,6 +94,18 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone): self.metadata_proxy) self._native_md_proxy_uuid = proxy_id + tz_id = nsxlib.transport_zone.get_id_by_name_or_id( + self.default_overlay_tz) + self._default_overlay_tz_uuid = tz_id + + # Optional configurations (may be None) + if self.default_vlan_tz: + tz_id = nsxlib.transport_zone.get_id_by_name_or_id( + self.default_vlan_tz) + self._default_vlan_tz_uuid = tz_id + else: + self._default_vlan_tz_uuid = None + class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones): diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index d2aedd7324..ab9dd98176 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -303,20 +303,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, 'reason': e}) def _translate_configured_names_to_uuids(self): - # default VLAN transport zone name / uuid - self._default_vlan_tz_uuid = None - if cfg.CONF.nsx_v3.default_vlan_tz: - tz_id = self.nsxlib.transport_zone.get_id_by_name_or_id( - cfg.CONF.nsx_v3.default_vlan_tz) - self._default_vlan_tz_uuid = tz_id - - # default overlay transport zone name / uuid - self._default_overlay_tz_uuid = None - if cfg.CONF.nsx_v3.default_overlay_tz: - tz_id = self.nsxlib.transport_zone.get_id_by_name_or_id( - cfg.CONF.nsx_v3.default_overlay_tz) - self._default_overlay_tz_uuid = tz_id - # default tier0 router self._default_tier0_router = None if cfg.CONF.nsx_v3.default_tier0_router: @@ -332,8 +318,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, if not cfg.CONF.nsx_v3.metadata_proxy: raise cfg.RequiredOptError("metadata_proxy") - for az in self.get_azs_list(): - az.translate_configured_names_to_uuids(self.nsxlib) + # Translate all the uuids in each of the availability + for az in self.get_azs_list(): + az.translate_configured_names_to_uuids(self.nsxlib) def _extend_port_dict_binding(self, context, port_data): port_data[pbin.VIF_TYPE] = pbin.VIF_TYPE_OVS @@ -610,7 +597,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, self._extension_manager.extend_subnet_dict( ctx.session, subnetdb, result) - def _validate_provider_create(self, context, network_data): + def _validate_provider_create(self, context, network_data, az): is_provider_net = any( validators.is_attr_set(network_data.get(f)) for f in (pnet.NETWORK_TYPE, @@ -637,11 +624,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # Set VLAN id to 0 for flat networks vlan_id = '0' if physical_net is None: - physical_net = self._default_vlan_tz_uuid + physical_net = az._default_vlan_tz_uuid elif net_type == utils.NsxV3NetworkTypes.VLAN: # Use default VLAN transport zone if physical network not given if physical_net is None: - physical_net = self._default_vlan_tz_uuid + physical_net = az._default_vlan_tz_uuid # Validate VLAN id if not vlan_id: @@ -687,7 +674,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, if physical_net is None: # Default to transport type overlay - physical_net = self._default_overlay_tz_uuid + physical_net = az._default_overlay_tz_uuid return is_provider_net, net_type, physical_net, vlan_id @@ -706,9 +693,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, self._routerlib.validate_tier0(self.tier0_groups_dict, tier0_uuid) return (is_provider_net, utils.NetworkTypes.L3_EXT, tier0_uuid, 0) - def _create_network_at_the_backend(self, context, net_data): + def _create_network_at_the_backend(self, context, net_data, az): is_provider_net, net_type, physical_net, vlan_id = ( - self._validate_provider_create(context, net_data)) + self._validate_provider_create(context, net_data, az)) neutron_net_id = net_data.get('id') or uuidutils.generate_uuid() # To ensure that the correct tag will be set net_data['id'] = neutron_net_id @@ -784,6 +771,12 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, is_backend_network = False tenant_id = net_data['tenant_id'] + # validate the availability zone, and get the AZ object + if az_ext.AZ_HINTS in net_data: + self.validate_availability_zones(context, 'network', + net_data[az_ext.AZ_HINTS]) + az = self.get_obj_az_by_hints(net_data) + self._ensure_default_security_group(context, tenant_id) if validators.is_attr_set(external) and external: self._assert_on_external_net_with_qos(net_data) @@ -791,10 +784,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, self._validate_external_net_create(net_data)) else: is_provider_net, net_type, physical_net, vlan_id, nsx_net_id = ( - self._create_network_at_the_backend(context, net_data)) + self._create_network_at_the_backend(context, net_data, az)) is_backend_network = True try: - az_name = nsx_az.DEFAULT_NAME with context.session.begin(subtransactions=True): # Create network in Neutron created_net = super(NsxV3Plugin, self).create_network(context, @@ -808,12 +800,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, self._process_l3_create(context, created_net, net_data) if az_ext.AZ_HINTS in net_data: - net_hints = net_data[az_ext.AZ_HINTS] - self.validate_availability_zones(context, 'network', - net_hints) - if net_hints: - az_name = net_hints[0] - az_hints = az_ext.convert_az_list_to_string(net_hints) + # Update the AZ hints in the neutron object + az_hints = az_ext.convert_az_list_to_string( + net_data[az_ext.AZ_HINTS]) super(NsxV3Plugin, self).update_network( context, created_net['id'], @@ -836,7 +825,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, nsx_net_id) if is_backend_network and cfg.CONF.nsx_v3.native_dhcp_metadata: - az = self.get_az_by_hint(az_name) # Enable native metadata proxy for this network. tags = self.nsxlib.build_v3_tags_payload( net_data, resource_type='os-neutron-net-id', diff --git a/vmware_nsx/tests/unit/nsx_v3/test_availability_zones.py b/vmware_nsx/tests/unit/nsx_v3/test_availability_zones.py index edc47d732f..57c767a46c 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_availability_zones.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_availability_zones.py @@ -46,7 +46,9 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase): dhcp_profile="dhcp_profile1", native_metadata_route="2.2.2.2", dns_domain="aaa.com", - nameservers=["20.1.1.1"]): + nameservers=["20.1.1.1"], + default_overlay_tz='otz', + default_vlan_tz='vtz'): if metadata_proxy is not None: cfg.CONF.set_override("metadata_proxy", metadata_proxy, group=self.group_name) @@ -63,6 +65,12 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase): if nameservers is not None: cfg.CONF.set_override("nameservers", nameservers, group=self.group_name) + if default_overlay_tz is not None: + cfg.CONF.set_override("default_overlay_tz", default_overlay_tz, + group=self.group_name) + if default_vlan_tz is not None: + cfg.CONF.set_override("default_vlan_tz", default_vlan_tz, + group=self.group_name) def test_simple_availability_zone(self): self._config_az() @@ -73,6 +81,8 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase): self.assertEqual("2.2.2.2", az.native_metadata_route) self.assertEqual("aaa.com", az.dns_domain) self.assertEqual(["20.1.1.1"], az.nameservers) + self.assertEqual("otz", az.default_overlay_tz) + self.assertEqual("vtz", az.default_vlan_tz) def test_missing_group_section(self): self.assertRaises(