diff --git a/releasenotes/notes/nsxv3-init-from-tags-bcd4f3245a78e9a6.yaml b/releasenotes/notes/nsxv3-init-from-tags-bcd4f3245a78e9a6.yaml new file mode 100644 index 0000000000..1bfa67a588 --- /dev/null +++ b/releasenotes/notes/nsxv3-init-from-tags-bcd4f3245a78e9a6.yaml @@ -0,0 +1,10 @@ +--- +prelude: > + NSX-V3 plugin supports a new configuration option for the transport zones, + tier-0 router, dhcp profile and md-proxy in the nsx ini file using NSX + Tags insead of names or IDs. +features: + - | + NSX-V3 plugin supports a new configuration option for the transport zones, + tier-0 router, dhcp profile and md-proxy in the nsx ini file using NSX + Tags insead of names or IDs. diff --git a/vmware_nsx/common/config.py b/vmware_nsx/common/config.py index f65f6b34bc..6a312006aa 100644 --- a/vmware_nsx/common/config.py +++ b/vmware_nsx/common/config.py @@ -423,6 +423,18 @@ nsx_v3_opts = [ 'zones names for the native dhcp configuration. The ' 'configuration of each zone will be under a group ' 'names [az:]')), + cfg.BoolOpt('init_objects_by_tags', + default=False, + help=_("When True, the configured transport zones, router and " + "profiles will be found by tags on the NSX. The scope " + "of the tag will be the value of search_objects_" + "scope. The value of the search tag will be the name " + "configured in each respective configuration.")), + cfg.StrOpt('search_objects_scope', + help=_("This is the scope of the tag that will be used for " + "finding the objects uuids on the NSX during plugin " + "init.")), + ] DEFAULT_STATUS_CHECK_INTERVAL = 2000 diff --git a/vmware_nsx/plugins/nsx_v3/availability_zones.py b/vmware_nsx/plugins/nsx_v3/availability_zones.py index 0f76d8ae4f..971d4a90e0 100644 --- a/vmware_nsx/plugins/nsx_v3/availability_zones.py +++ b/vmware_nsx/plugins/nsx_v3/availability_zones.py @@ -88,30 +88,68 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone): # Mandatory configurations (in AZ or inherited from global values) # Unless this is the default AZ, and metadata is disabled. if self.dhcp_profile: - dhcp_id = nsxlib.native_dhcp_profile.get_id_by_name_or_id( - self.dhcp_profile) + dhcp_id = None + if cfg.CONF.nsx_v3.init_objects_by_tags: + # Find the TZ by its tag + dhcp_id = nsxlib.get_id_by_resource_and_tag( + nsxlib.native_dhcp_profile.resource_type, + cfg.CONF.nsx_v3.search_objects_scope, + self.dhcp_profile) + if not dhcp_id: + dhcp_id = nsxlib.native_dhcp_profile.get_id_by_name_or_id( + self.dhcp_profile) self._native_dhcp_profile_uuid = dhcp_id else: self._native_dhcp_profile_uuid = None if self.metadata_proxy: - proxy_id = nsxlib.native_md_proxy.get_id_by_name_or_id( - self.metadata_proxy) + proxy_id = None + if cfg.CONF.nsx_v3.init_objects_by_tags: + # Find the TZ by its tag + proxy_id = nsxlib.get_id_by_resource_and_tag( + nsxlib.native_md_proxy.resource_type, + cfg.CONF.nsx_v3.search_objects_scope, + self.metadata_proxy) + if not proxy_id: + proxy_id = nsxlib.native_md_proxy.get_id_by_name_or_id( + self.metadata_proxy) self._native_md_proxy_uuid = proxy_id else: self._native_md_proxy_uuid = None if self.default_overlay_tz: - tz_id = nsxlib.transport_zone.get_id_by_name_or_id( - self.default_overlay_tz) + tz_id = None + if cfg.CONF.nsx_v3.init_objects_by_tags: + # Find the TZ by its tag + resource_type = (nsxlib.transport_zone.resource_type + + ' AND transport_type:OVERLAY') + tz_id = nsxlib.get_id_by_resource_and_tag( + resource_type, + cfg.CONF.nsx_v3.search_objects_scope, + self.default_overlay_tz) + if not tz_id: + # Find the TZ by its name or id + tz_id = nsxlib.transport_zone.get_id_by_name_or_id( + self.default_overlay_tz) self._default_overlay_tz_uuid = tz_id else: self._default_overlay_tz_uuid = None # 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) + tz_id = None + if cfg.CONF.nsx_v3.init_objects_by_tags: + # Find the TZ by its tag + resource_type = (nsxlib.transport_zone.resource_type + + ' AND transport_type:VLAN') + tz_id = nsxlib.get_id_by_resource_and_tag( + resource_type, + cfg.CONF.nsx_v3.search_objects_scope, + self.default_vlan_tz) + if not tz_id: + # Find the TZ by its name or id + 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 diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 977af0e8f1..260ba698c7 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -298,20 +298,39 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, 'reason': e}) def _translate_configured_names_to_uuids(self): + # If using tags to find the objects, make sure tag scope is configured + if (cfg.CONF.nsx_v3.init_objects_by_tags and + not cfg.CONF.nsx_v3.search_objects_scope): + raise cfg.RequiredOptError("search_objects_scope", + group=cfg.OptGroup('nsx_v3')) + # default tier0 router self._default_tier0_router = None if cfg.CONF.nsx_v3.default_tier0_router: - rtr_id = self.nsxlib.logical_router.get_id_by_name_or_id( - cfg.CONF.nsx_v3.default_tier0_router) + rtr_id = None + if cfg.CONF.nsx_v3.init_objects_by_tags: + # Find the router by its tag + resource_type = (self.nsxlib.logical_router.resource_type + + ' AND router_type:TIER0') + rtr_id = self.nsxlib.get_id_by_resource_and_tag( + resource_type, + cfg.CONF.nsx_v3.search_objects_scope, + cfg.CONF.nsx_v3.default_tier0_router) + if not rtr_id: + # find the router by name or id + rtr_id = self.nsxlib.logical_router.get_id_by_name_or_id( + cfg.CONF.nsx_v3.default_tier0_router) self._default_tier0_router = rtr_id # Validate and translate native dhcp profiles per az if cfg.CONF.nsx_v3.native_dhcp_metadata: if not cfg.CONF.nsx_v3.dhcp_profile: - raise cfg.RequiredOptError("dhcp_profile") + raise cfg.RequiredOptError("dhcp_profile", + group=cfg.OptGroup('nsx_v3')) if not cfg.CONF.nsx_v3.metadata_proxy: - raise cfg.RequiredOptError("metadata_proxy") + raise cfg.RequiredOptError("metadata_proxy", + group=cfg.OptGroup('nsx_v3')) # Translate all the uuids in each of the availability for az in self.get_azs_list():