From eb4e43d9a083376cf701121ff564f69b245db923 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Mon, 6 Mar 2017 10:19:05 +0200 Subject: [PATCH] Generalize the availability-zones code Create a common availability-zones code, and use it for nsxv, as a first step for adding availability zones for nsx-v3 too. Change-Id: I33bdfd3efc66ab8b39b9cde9636b1d31c1865559 --- vmware_nsx/common/availability_zones.py | 171 +++++++++ .../plugins/nsx_v/availability_zones.py | 334 ++++++++---------- vmware_nsx/plugins/nsx_v/plugin.py | 74 ++-- .../plugins/nsx_v/vshield/edge_utils.py | 23 +- vmware_nsx/services/l2gateway/nsx_v/driver.py | 2 +- .../services/lbaas/nsx_v/lbaas_common.py | 2 +- .../admin/plugins/nsxv/resources/edges.py | 8 +- .../admin/plugins/nsxv/resources/metadata.py | 7 +- .../unit/nsx_v/test_availability_zones.py | 40 +-- vmware_nsx/tests/unit/nsx_v/test_plugin.py | 10 +- .../unit/nsx_v/vshield/test_edge_utils.py | 14 +- .../unit/nsx_v/vshield/test_vcns_driver.py | 2 +- 12 files changed, 391 insertions(+), 296 deletions(-) create mode 100644 vmware_nsx/common/availability_zones.py diff --git a/vmware_nsx/common/availability_zones.py b/vmware_nsx/common/availability_zones.py new file mode 100644 index 0000000000..017721e500 --- /dev/null +++ b/vmware_nsx/common/availability_zones.py @@ -0,0 +1,171 @@ +# Copyright 2016 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. + +import abc + +from neutron.extensions import availability_zone as az_ext +from neutron_lib import exceptions as n_exc + +from vmware_nsx._i18n import _ +from vmware_nsx.common import exceptions as nsx_exc + +DEFAULT_NAME = 'default' + + +class ConfiguredAvailabilityZone(object): + + def __init__(self, config_line): + self.name = "" + if config_line and ':' in config_line: + # Older configuration - each line contains all the relevant + # values for one availability zones, separated by ':' + values = config_line.split(':') + self.name = values[0] + self._validate_zone_name(self.name) + self.init_from_config_line(config_line) + elif config_line: + # Newer configuration - the name of the availability zone can be + # used to get the rest of the configuration for this AZ + self.name = config_line + self._validate_zone_name(config_line) + self.init_from_config_section(self.name) + else: + # Default zone configuration + self.name = DEFAULT_NAME + self.init_default_az() + + def is_default(self): + return self.name == DEFAULT_NAME + + def _validate_zone_name(self, config_line): + if len(self.name) > 36: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="availability_zones", + opt_value=config_line, + reason=_("Maximum name length is 36")) + + @abc.abstractmethod + def init_from_config_line(self, config_values): + pass + + @abc.abstractmethod + def init_from_config_section(self, az_name): + pass + + @abc.abstractmethod + def init_default_az(self): + pass + + +class ConfiguredAvailabilityZones(object): + + def __init__(self, az_conf, az_class): + self.availability_zones = {} + + # Add the configured availability zones + for az in az_conf: + obj = az_class(az) + self.availability_zones[obj.name] = obj + + # add a default entry + obj = az_class(None) + self.availability_zones[obj.name] = obj + + @abc.abstractmethod + def get_resources(self): + """Return a list of all the resources in all the availability zones + """ + pass + + def get_availability_zone(self, name): + """Return an availability zone object by its name + """ + if name in self.availability_zones.keys(): + return self.availability_zones[name] + return self.get_default_availability_zone() + + def get_default_availability_zone(self): + """Return the default availability zone object + """ + return self.availability_zones[DEFAULT_NAME] + + def list_availability_zones(self): + """Return a list of availability zones names + """ + return self.availability_zones.keys() + + def list_availability_zones_objects(self): + """Return a list of availability zones objects + """ + return self.availability_zones.values() + + +class NSXAvailabilityZonesPluginCommon(object): + + @abc.abstractmethod + def init_availability_zones(self): + # To be initialized by the real plugin + self._availability_zones_data = None + + def get_azs_list(self): + return self._availability_zones_data.list_availability_zones_objects() + + def get_azs_names(self): + return self._availability_zones_data.list_availability_zones() + + def validate_obj_azs(self, availability_zones): + """Verify that the availability zones exist, and only 1 hint + was set. + """ + # For now we support only 1 hint per network/router + # TODO(asarfaty): support multiple hints + if len(availability_zones) > 1: + err_msg = _("Can't use multiple availability zone hints") + raise n_exc.InvalidInput(error_message=err_msg) + + # check that all hints appear in the predefined list of availability + # zones + diff = (set(availability_zones) - set(self.get_azs_names())) + if diff: + raise az_ext.AvailabilityZoneNotFound( + availability_zone=diff.pop()) + + def get_az_by_hint(self, hint): + az = self._availability_zones_data.get_availability_zone(hint) + if not az: + raise az_ext.AvailabilityZoneNotFound(availability_zone=hint) + return az + + def get_default_az(self): + return self._availability_zones_data.get_default_availability_zone() + + def get_obj_az_by_hints(self, obj): + if az_ext.AZ_HINTS in obj: + hints = obj[az_ext.AZ_HINTS] + # if this is a string and not a list - need to convert it + if not isinstance(hints, list): + hints = az_ext.convert_az_string_to_list(hints) + for hint in hints: + # For now we use only the first hint + return self.get_az_by_hint(hint) + + # return the default + return self.get_default_az() + + def get_network_az(self, network): + return self.get_obj_az_by_hints(network) + + def get_router_az(self, router): + return self.get_obj_az_by_hints(router) diff --git a/vmware_nsx/plugins/nsx_v/availability_zones.py b/vmware_nsx/plugins/nsx_v/availability_zones.py index 38d6162941..316aa6daf8 100644 --- a/vmware_nsx/plugins/nsx_v/availability_zones.py +++ b/vmware_nsx/plugins/nsx_v/availability_zones.py @@ -16,192 +16,168 @@ from oslo_config import cfg from vmware_nsx._i18n import _ +from vmware_nsx.common import availability_zones as common_az from vmware_nsx.common import config from vmware_nsx.common import exceptions as nsx_exc -DEFAULT_NAME = 'default' +DEFAULT_NAME = common_az.DEFAULT_NAME -class ConfiguredAvailabilityZone(object): +class NsxVAvailabilityZone(common_az.ConfiguredAvailabilityZone): - def __init__(self, config_line): - if config_line and ':' in config_line: - # Older configuration - each line contains all the relevant - # values for one availability zones, separated by ':' - values = config_line.split(':') - if len(values) < 4 or len(values) > 5: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="availability_zones", - opt_value=config_line, - reason=_("Expected 4 or 5 values per zone")) + def init_from_config_line(self, config_line): + values = config_line.split(':') + if len(values) < 4 or len(values) > 5: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="availability_zones", + opt_value=config_line, + reason=_("Expected 4 or 5 values per zone")) - self.name = values[0] - # field name size in the DB is 36 - if len(self.name) > 36: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="availability_zones", - opt_value=config_line, - reason=_("Maximum name length is 36")) + self.resource_pool = values[1] + self.datastore_id = values[2] - self.resource_pool = values[1] - self.datastore_id = values[2] + # validate the edge_ha + if values[3].lower() == "true": + self.edge_ha = True + elif values[3].lower() == "false": + self.edge_ha = False + else: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="availability_zones", + opt_value=config_line, + reason=_("Expected the 4th value to be true/false")) - # validate the edge_ha - if values[3].lower() == "true": - self.edge_ha = True - elif values[3].lower() == "false": - self.edge_ha = False - else: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="availability_zones", - opt_value=config_line, - reason=_("Expected the 4th value to be true/false")) + # HA datastore id is relevant only with edge_ha + if not self.edge_ha and len(values) == 5: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="availability_zones", + opt_value=config_line, + reason=_("Expected HA datastore ID only when edge_ha is " + "enabled")) - # HA datastore id is relevant only with edge_ha - if not self.edge_ha and len(values) == 5: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="availability_zones", - opt_value=config_line, - reason=_("Expected HA datastore ID only when edge_ha is " - "enabled")) + self.ha_datastore_id = values[4] if len(values) == 5 else None - self.ha_datastore_id = values[4] if len(values) == 5 else None + # Some parameters are not supported in this format. + # using the global ones instead. + self.ha_placement_random = cfg.CONF.nsxv.ha_placement_random + self.backup_edge_pool = cfg.CONF.nsxv.backup_edge_pool + self.external_network = cfg.CONF.nsxv.external_network + self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id + self.dvs_id = cfg.CONF.nsxv.dvs_id + self.edge_host_groups = cfg.CONF.nsxv.edge_host_groups - # Some parameters are not supported in this format. - # using the global ones instead. - self.ha_placement_random = cfg.CONF.nsxv.ha_placement_random + # No support for metadata per az + self.az_metadata_support = False + self.mgt_net_moid = None + self.mgt_net_proxy_ips = [] + self.mgt_net_proxy_netmask = None + self.mgt_net_default_gateway = None + + def init_from_config_section(self, az_name): + az_info = config.get_nsxv_az_opts(az_name) + self.resource_pool = az_info.get('resource_pool_id') + if not self.resource_pool: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="resource_pool_id", + opt_value='None', + reason=(_("resource_pool_id for availability zone %s " + "must be defined") % az_name)) + self.datastore_id = az_info.get('datastore_id') + if not self.datastore_id: + raise nsx_exc.NsxInvalidConfiguration( + opt_name="datastore_id", + opt_value='None', + reason=(_("datastore_id for availability zone %s " + "must be defined") % az_name)) + self.edge_ha = az_info.get('edge_ha', False) + # The HA datastore can be empty + self.ha_datastore_id = (az_info.get('ha_datastore_id') + if self.edge_ha else None) + + # The optional parameters will get the global values if not + # defined for this AZ + self.ha_placement_random = az_info.get('ha_placement_random') + if self.ha_placement_random is None: + self.ha_placement_random = ( + cfg.CONF.nsxv.ha_placement_random) + + self.backup_edge_pool = az_info.get('backup_edge_pool', []) + if not self.backup_edge_pool: self.backup_edge_pool = cfg.CONF.nsxv.backup_edge_pool + + self.external_network = az_info.get('external_network') + if not self.external_network: self.external_network = cfg.CONF.nsxv.external_network + + self.vdn_scope_id = az_info.get('vdn_scope_id') + if not self.vdn_scope_id: self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id + + self.dvs_id = az_info.get('dvs_id') + if not self.dvs_id: self.dvs_id = cfg.CONF.nsxv.dvs_id + + self.edge_host_groups = az_info.get('edge_host_groups', []) + if not self.edge_host_groups: self.edge_host_groups = cfg.CONF.nsxv.edge_host_groups - # No support for metadata per az + # Support for metadata per az only if configured, and different + # from the global one + self.mgt_net_proxy_ips = az_info.get('mgt_net_proxy_ips') + if self.mgt_net_proxy_ips: + # make sure there are no over lapping ips with the + # global configuration + if (set(self.mgt_net_proxy_ips) & + set(cfg.CONF.nsxv.mgt_net_proxy_ips)): + raise nsx_exc.NsxInvalidConfiguration( + opt_name="mgt_net_proxy_ips", + opt_value='None', + reason=(_("mgt_net_proxy_ips for availability zone " + "%s must be different from global one") % + az_name)) + + self.az_metadata_support = True + self.mgt_net_moid = az_info.get('mgt_net_moid') + if not self.mgt_net_moid: + self.mgt_net_moid = cfg.CONF.nsxv.mgt_net_moid + + self.mgt_net_proxy_netmask = az_info.get( + 'mgt_net_proxy_netmask') + if not self.mgt_net_proxy_netmask: + self.mgt_net_proxy_netmask = ( + cfg.CONF.nsxv.mgt_net_proxy_netmask) + + self.mgt_net_default_gateway = az_info.get( + 'mgt_net_default_gateway') + if not self.mgt_net_default_gateway: + self.mgt_net_default_gateway = ( + cfg.CONF.nsxv.mgt_net_default_gateway) + + else: self.az_metadata_support = False self.mgt_net_moid = None self.mgt_net_proxy_ips = [] self.mgt_net_proxy_netmask = None self.mgt_net_default_gateway = None - elif config_line: - # Newer configuration - the name of the availability zone can be - # used to get the rest of the configuration for this AZ - self.name = config_line - # field name size in the DB is 36 - if len(self.name) > 36: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="availability_zones", - opt_value=config_line, - reason=_("Maximum name length is 36")) - - az_info = config.get_nsxv_az_opts(self.name) - self.resource_pool = az_info.get('resource_pool_id') - if not self.resource_pool: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="resource_pool_id", - opt_value='None', - reason=(_("resource_pool_id for availability zone %s " - "must be defined") % self.name)) - self.datastore_id = az_info.get('datastore_id') - if not self.datastore_id: - raise nsx_exc.NsxInvalidConfiguration( - opt_name="datastore_id", - opt_value='None', - reason=(_("datastore_id for availability zone %s " - "must be defined") % self.name)) - self.edge_ha = az_info.get('edge_ha', False) - # The HA datastore can be empty - self.ha_datastore_id = (az_info.get('ha_datastore_id') - if self.edge_ha else None) - - # The optional parameters will get the global values if not - # defined for this AZ - self.ha_placement_random = az_info.get('ha_placement_random') - if self.ha_placement_random is None: - self.ha_placement_random = ( - cfg.CONF.nsxv.ha_placement_random) - - self.backup_edge_pool = az_info.get('backup_edge_pool', []) - if not self.backup_edge_pool: - self.backup_edge_pool = cfg.CONF.nsxv.backup_edge_pool - - self.external_network = az_info.get('external_network') - if not self.external_network: - self.external_network = cfg.CONF.nsxv.external_network - - self.vdn_scope_id = az_info.get('vdn_scope_id') - if not self.vdn_scope_id: - self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id - - self.dvs_id = az_info.get('dvs_id') - if not self.dvs_id: - self.dvs_id = cfg.CONF.nsxv.dvs_id - - self.edge_host_groups = az_info.get('edge_host_groups', []) - if not self.edge_host_groups: - self.edge_host_groups = cfg.CONF.nsxv.edge_host_groups - - # Support for metadata per az only if configured, and different - # from the global one - self.mgt_net_proxy_ips = az_info.get('mgt_net_proxy_ips') - if self.mgt_net_proxy_ips: - # make sure there are no over lapping ips with the - # global configuration - if (set(self.mgt_net_proxy_ips) & - set(cfg.CONF.nsxv.mgt_net_proxy_ips)): - raise nsx_exc.NsxInvalidConfiguration( - opt_name="mgt_net_proxy_ips", - opt_value='None', - reason=(_("mgt_net_proxy_ips for availability zone " - "%s must be different from global one") % - self.name)) - - self.az_metadata_support = True - self.mgt_net_moid = az_info.get('mgt_net_moid') - if not self.mgt_net_moid: - self.mgt_net_moid = cfg.CONF.nsxv.mgt_net_moid - - self.mgt_net_proxy_netmask = az_info.get( - 'mgt_net_proxy_netmask') - if not self.mgt_net_proxy_netmask: - self.mgt_net_proxy_netmask = ( - cfg.CONF.nsxv.mgt_net_proxy_netmask) - - self.mgt_net_default_gateway = az_info.get( - 'mgt_net_default_gateway') - if not self.mgt_net_default_gateway: - self.mgt_net_default_gateway = ( - cfg.CONF.nsxv.mgt_net_default_gateway) - - else: - self.az_metadata_support = False - self.mgt_net_moid = None - self.mgt_net_proxy_ips = [] - self.mgt_net_proxy_netmask = None - self.mgt_net_default_gateway = None - - else: - # use the default configuration - self.name = DEFAULT_NAME - self.resource_pool = cfg.CONF.nsxv.resource_pool_id - self.datastore_id = cfg.CONF.nsxv.datastore_id - self.edge_ha = cfg.CONF.nsxv.edge_ha - self.ha_datastore_id = cfg.CONF.nsxv.ha_datastore_id - self.ha_placement_random = cfg.CONF.nsxv.ha_placement_random - self.backup_edge_pool = cfg.CONF.nsxv.backup_edge_pool - self.az_metadata_support = True - self.mgt_net_moid = cfg.CONF.nsxv.mgt_net_moid - self.mgt_net_proxy_ips = cfg.CONF.nsxv.mgt_net_proxy_ips - self.mgt_net_proxy_netmask = cfg.CONF.nsxv.mgt_net_proxy_netmask - self.mgt_net_default_gateway = ( - cfg.CONF.nsxv.mgt_net_default_gateway) - self.external_network = cfg.CONF.nsxv.external_network - self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id - self.dvs_id = cfg.CONF.nsxv.dvs_id - self.edge_host_groups = cfg.CONF.nsxv.edge_host_groups - - def is_default(self): - return self.name == DEFAULT_NAME + def init_default_az(self): + # use the default configuration + self.resource_pool = cfg.CONF.nsxv.resource_pool_id + self.datastore_id = cfg.CONF.nsxv.datastore_id + self.edge_ha = cfg.CONF.nsxv.edge_ha + self.ha_datastore_id = cfg.CONF.nsxv.ha_datastore_id + self.ha_placement_random = cfg.CONF.nsxv.ha_placement_random + self.backup_edge_pool = cfg.CONF.nsxv.backup_edge_pool + self.az_metadata_support = True + self.mgt_net_moid = cfg.CONF.nsxv.mgt_net_moid + self.mgt_net_proxy_ips = cfg.CONF.nsxv.mgt_net_proxy_ips + self.mgt_net_proxy_netmask = cfg.CONF.nsxv.mgt_net_proxy_netmask + self.mgt_net_default_gateway = ( + cfg.CONF.nsxv.mgt_net_default_gateway) + self.external_network = cfg.CONF.nsxv.external_network + self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id + self.dvs_id = cfg.CONF.nsxv.dvs_id + self.edge_host_groups = cfg.CONF.nsxv.edge_host_groups def supports_metadata(self): # Return True if this az has it's own metadata configuration @@ -209,25 +185,18 @@ class ConfiguredAvailabilityZone(object): return self.az_metadata_support -class ConfiguredAvailabilityZones(object): +class NsxVAvailabilityZones(common_az.ConfiguredAvailabilityZones): def __init__(self): - self.availability_zones = {} - - # Add the configured availability zones - for az in cfg.CONF.nsxv.availability_zones: - obj = ConfiguredAvailabilityZone(az) - self.availability_zones[obj.name] = obj - - # add a default entry - obj = ConfiguredAvailabilityZone(None) - self.availability_zones[obj.name] = obj + super(NsxVAvailabilityZones, self).__init__( + cfg.CONF.nsxv.availability_zones, + NsxVAvailabilityZone) def get_resources(self): """Return a list of all the resources in all the availability zones """ resources = [] - for az in self.availability_zones.values(): + for az in self.list_availability_zones_objects(): resources.append(az.resource_pool) resources.append(az.datastore_id) if az.ha_datastore_id: @@ -241,20 +210,3 @@ class ConfiguredAvailabilityZones(object): if az.mgt_net_moid: resources.append(az.mgt_net_moid) return resources - - def get_availability_zone(self, name): - """Return an availability zone object by its name - """ - if name in self.availability_zones.keys(): - return self.availability_zones[name] - return self.get_default_availability_zone() - - def get_default_availability_zone(self): - """Return the default availability zone object - """ - return self.availability_zones[DEFAULT_NAME] - - def list_availability_zones(self): - """Return a list of availability zones names - """ - return self.availability_zones.keys() diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index b85209ff6f..b07bf286c0 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -86,6 +86,7 @@ from vmware_nsx.services.qos.nsx_v import utils as qos_utils import vmware_nsx from vmware_nsx._i18n import _, _LE, _LI, _LW +from vmware_nsx.common import availability_zones as nsx_com_az from vmware_nsx.common import config # noqa from vmware_nsx.common import exceptions as nsx_exc from vmware_nsx.common import l3_rpc_agent_api @@ -148,7 +149,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, extended_secgroup.ExtendedSecurityGroupPropertiesMixin, vnic_index_db.VnicIndexDbMixin, dns_db.DNSDbMixin, nsxpolicy.NsxPolicyPluginBase, - vlantransparent_db.Vlantransparent_db_mixin): + vlantransparent_db.Vlantransparent_db_mixin, + nsx_com_az.NSXAvailabilityZonesPluginCommon): supported_extension_aliases = ["agent", "allowed-address-pairs", @@ -226,14 +228,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, self.edge_manager = edge_utils.EdgeManager(self.nsx_v, self) self.nsx_sg_utils = securitygroup_utils.NsxSecurityGroupUtils( self.nsx_v) - self._availability_zones_data = nsx_az.ConfiguredAvailabilityZones() - # Validate the host_groups for each AZ - if cfg.CONF.nsxv.use_dvs_features: - azs = self._availability_zones_data.availability_zones.values() - for az in azs: - if az.edge_host_groups and az.edge_ha: - self._vcm.validate_host_groups(az.resource_pool, - az.edge_host_groups) + self.init_availability_zones() self._validate_config() self._use_nsx_policies = False @@ -305,13 +300,11 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, if has_metadata_cfg: # Init md_proxy handler per availability zone self.metadata_proxy_handler = {} - az_list = self._availability_zones_data.list_availability_zones() - for name in az_list: - az = self._availability_zones_data.get_availability_zone(name) + for az in self.get_azs_list(): # create metadata handler only if the az supports it. # if not, the global one will be used if az.supports_metadata(): - self.metadata_proxy_handler[name] = ( + self.metadata_proxy_handler[az.name] = ( nsx_v_md_proxy.NsxVMetadataProxyHandler(self, az)) self.init_is_complete = True @@ -969,11 +962,14 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, # The vnic-id format which is expected by NSXv return '%s.%03d' % (device_id, port_index) + def init_availability_zones(self): + self._availability_zones_data = nsx_az.NsxVAvailabilityZones() + def _list_availability_zones(self, context, filters=None): #TODO(asarfaty): We may need to use the filters arg, but now it # is here only for overriding the original api result = {} - for az in self._availability_zones_data.list_availability_zones(): + for az in self.get_azs_names(): # Add this availability zone as a router & network resource for resource in ('router', 'network'): result[(az, resource)] = True @@ -990,39 +986,15 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, """Verify that the availability zones exist, and only 1 hint was set. """ - # For now we support only 1 hint per network/router - # TODO(asarfaty): support multiple hints - if len(availability_zones) > 1: - err_msg = _("Can't use multiple availability zone hints") - raise n_exc.InvalidInput(error_message=err_msg) + return self.validate_obj_azs(availability_zones) - # check that all hints appear in the predefined list of availability - # zones - diff = (set(availability_zones) - - set(self._availability_zones_data.list_availability_zones())) - if diff: - raise az_ext.AvailabilityZoneNotFound( - availability_zone=diff.pop()) - - def get_network_or_router_az(self, object): - if az_ext.AZ_HINTS in object: - for hint in object[az_ext.AZ_HINTS]: - # For now we use only the first hint - return self.get_az_by_hint(hint) - - # return the default - return self.get_default_az() - - def get_network_az(self, context, network_id): + def get_network_az_by_net_id(self, context, network_id): try: network = self.get_network(context, network_id) except Exception: return self.get_default_az() - return self.get_network_or_router_az(network) - - def get_router_az(self, router): - return self.get_network_or_router_az(router) + return self.get_network_az(network) def _prepare_spoofguard_policy(self, network_type, net_data, net_morefs): # The method will determine if a portgroup is already assigned to a @@ -1276,7 +1248,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, context=context, qos_policy_id=qos_policy_id) # default dvs for this network - az = self.get_network_az(context, net_id) + az = self.get_network_az_by_net_id(context, net_id) az_dvs_id = az.dvs_id # get the network moref/s from the db @@ -4099,6 +4071,15 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, if version.LooseVersion(ver) < version.LooseVersion('6.2.0'): LOG.warning(_LW("Skipping validations. Not supported by version.")) return + + # Validate the host_groups for each AZ + if cfg.CONF.nsxv.use_dvs_features: + azs = self.get_azs_list() + for az in azs: + if az.edge_host_groups and az.edge_ha: + self._dvs.validate_host_groups(az.resource_pool, + az.edge_host_groups) + # Validations below only supported by 6.2.0 and above inventory = [(cfg.CONF.nsxv.resource_pool_id, 'resource_pool_id'), @@ -4136,15 +4117,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, qos_policys, event_type): qos_utils.handle_qos_notification(qos_policys, event_type, self) - def get_az_by_hint(self, hint): - az = self._availability_zones_data.get_availability_zone(hint) - if not az: - raise az_ext.AvailabilityZoneNotFound(availability_zone=hint) - return az - - def get_default_az(self): - return self._availability_zones_data.get_default_availability_zone() - def _nsx_policy_is_hidden(self, policy): for attrib in policy.get('extendedAttributes', []): if (attrib['name'].lower() == 'ishidden' and diff --git a/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py b/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py index 0a4975bc7d..3c455adbfb 100644 --- a/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py +++ b/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py @@ -186,7 +186,7 @@ class EdgeManager(object): self._worker_pool_pid = None self._worker_pool = None self.nsxv_manager = nsxv_manager - self._availability_zones = nsx_az.ConfiguredAvailabilityZones() + self._availability_zones = nsx_az.NsxVAvailabilityZones() self.edge_pool_dicts = self._parse_backup_edge_pool_opt() self.nsxv_plugin = nsxv_manager.callbacks.plugin self.plugin = plugin @@ -196,10 +196,9 @@ class EdgeManager(object): def _parse_backup_edge_pool_opt(self): """Parse edge pool opts for all availability zones.""" - az_list = self._availability_zones.list_availability_zones() + az_list = self._availability_zones.list_availability_zones_objects() az_pools = {} - for az_name in az_list: - az = self._availability_zones.get_availability_zone(az_name) + for az in az_list: az_pools[az.name] = parse_backup_edge_pool_opt_per_az(az) return az_pools @@ -358,8 +357,7 @@ class EdgeManager(object): def _check_backup_edge_pools(self): admin_ctx = q_context.get_admin_context() - for az_name in self._availability_zones.list_availability_zones(): - az = self._availability_zones.get_availability_zone(az_name) + for az in self._availability_zones.list_availability_zones_objects(): self._clean_all_error_edge_bindings(admin_ctx, az) for edge_type, v in self._get_az_pool(az.name).items(): for edge_size in vcns_const.ALLOWED_EDGE_SIZES: @@ -478,7 +476,7 @@ class EdgeManager(object): def _create_sub_interface(self, context, network_id, network_name, tunnel_index, address_groups, port_group_id=None): - az = self.plugin.get_network_az(context, network_id) + az = self.plugin.get_network_az_by_net_id(context, network_id) vcns_network_id = _retrieve_nsx_switch_id(context, network_id, az.name) if port_group_id is None: @@ -531,7 +529,8 @@ class EdgeManager(object): header, _ = self.nsxv_manager.vcns.delete_interface(edge_id, vnic_index) if port_group_id: - az = self.plugin.get_network_az(context, network_id) + az = self.plugin.get_network_az_by_net_id( + context, network_id) dvs_id, net_type = self._get_physical_provider_network( context, network_id, az.dvs_id) self.nsxv_manager.delete_port_group(dvs_id, @@ -1261,7 +1260,8 @@ class EdgeManager(object): If new edge was allocated, return resource_id, else return None """ - availability_zone = self.plugin.get_network_az(context, network_id) + availability_zone = self.plugin.get_network_az_by_net_id( + context, network_id) # Check if the network has one related dhcp edge resource_id = (vcns_const.DHCP_EDGE_PREFIX + network_id)[:36] dhcp_edge_binding = nsxv_db.get_nsxv_router_binding(context.session, @@ -1428,7 +1428,8 @@ class EdgeManager(object): # Find DHCP Edge which is associated with this VDR vdr_dhcp_binding = nsxv_db.get_vdr_dhcp_binding_by_vdr( context.session, vdr_router_id) - availability_zone = self.plugin.get_network_az(context, network_id) + availability_zone = self.plugin.get_network_az_by_net_id( + context, network_id) if vdr_dhcp_binding: with locking.LockManager.get_lock('nsx-edge-pool'): dhcp_edge_id = vdr_dhcp_binding['dhcp_edge_id'] @@ -2150,7 +2151,7 @@ def _retrieve_nsx_switch_id(context, network_id, az_name): # If network is of type VLAN and multiple dvs associated with # one neutron network, retrieve the logical network id for the # edge/mgmt cluster's DVS from the networks availability zone. - azs = nsx_az.ConfiguredAvailabilityZones() + azs = nsx_az.NsxVAvailabilityZones() az = azs.get_availability_zone(az_name) dvs_id = az.dvs_id return nsx_db.get_nsx_switch_id_for_dvs( diff --git a/vmware_nsx/services/l2gateway/nsx_v/driver.py b/vmware_nsx/services/l2gateway/nsx_v/driver.py index ea43cf075b..91b98b6123 100644 --- a/vmware_nsx/services/l2gateway/nsx_v/driver.py +++ b/vmware_nsx/services/l2gateway/nsx_v/driver.py @@ -108,7 +108,7 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): lrouter = {'name': nsxv_constants.L2_GATEWAY_EDGE, 'id': uuidutils.generate_uuid()} # Create the router on the default availability zone - availability_zone = (nsx_az.ConfiguredAvailabilityZones(). + availability_zone = (nsx_az.NsxVAvailabilityZones(). get_default_availability_zone()) self._edge_manager.create_lrouter(context, lrouter, lswitch=None, dist=True, diff --git a/vmware_nsx/services/lbaas/nsx_v/lbaas_common.py b/vmware_nsx/services/lbaas/nsx_v/lbaas_common.py index 90833de74e..ad4afb0a6e 100644 --- a/vmware_nsx/services/lbaas/nsx_v/lbaas_common.py +++ b/vmware_nsx/services/lbaas/nsx_v/lbaas_common.py @@ -90,7 +90,7 @@ def delete_lb_interface(context, plugin, lb_id, subnet_id): def get_lbaas_edge_id(context, plugin, lb_id, vip_addr, subnet_id, tenant_id): subnet = plugin.get_subnet(context, subnet_id) network_id = subnet.get('network_id') - availability_zone = plugin.get_network_az(context, network_id) + availability_zone = plugin.get_network_az_by_net_id(context, network_id) resource_id = get_lb_resource_id(lb_id) diff --git a/vmware_nsx/shell/admin/plugins/nsxv/resources/edges.py b/vmware_nsx/shell/admin/plugins/nsxv/resources/edges.py index 9912782332..4559c6c309 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv/resources/edges.py +++ b/vmware_nsx/shell/admin/plugins/nsxv/resources/edges.py @@ -311,7 +311,7 @@ def change_edge_appliance(edge_id): """ # find out what is the current resource pool & size, so we can keep them az_name, size = _get_edge_az_and_size(edge_id) - az = nsx_az.ConfiguredAvailabilityZones().get_availability_zone(az_name) + az = nsx_az.NsxVAvailabilityZones().get_availability_zone(az_name) appliances = [{'resourcePoolId': az.resource_pool, 'datastoreId': az.datastore_id}] @@ -372,7 +372,7 @@ def _update_host_group_for_edge(nsxv, dvs_mng, edge_id, edge): if edge.get('type') == 'gatewayServices': try: az_name, size = _get_edge_az_and_size(edge_id) - zones = nsx_az.ConfiguredAvailabilityZones() + zones = nsx_az.NsxVAvailabilityZones() az = zones.get_availability_zone(az_name) edge_utils.update_edge_host_groups(nsxv, edge_id, dvs_mng, az, @@ -406,8 +406,8 @@ def change_edge_hostgroup(properties): _update_host_group_for_edge(nsxv, dvs_mng, edge_id, edge) elif properties.get('hostgroup').lower() == "clean": - azs = nsx_az.ConfiguredAvailabilityZones() - for az in azs.availability_zones.values(): + azs = nsx_az.NsxVAvailabilityZones() + for az in azs.list_availability_zones_objects(): try: edge_utils.clean_host_groups(dvs_mng, az) except Exception: diff --git a/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py b/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py index 97bc531a50..0190546465 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py +++ b/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py @@ -46,10 +46,9 @@ def nsx_redo_metadata_cfg(resource, event, trigger, **kwargs): edgeapi = utils.NeutronDbClient() config.register_nsxv_azs(cfg.CONF, cfg.CONF.nsxv.availability_zones) - conf_az = nsx_az.ConfiguredAvailabilityZones() - az_list = conf_az.list_availability_zones() - for name in az_list: - az = conf_az.get_availability_zone(name) + conf_az = nsx_az.NsxVAvailabilityZones() + az_list = conf_az.list_availability_zones_objects() + for az in az_list: if az.supports_metadata(): nsx_redo_metadata_cfg_for_az(az, edgeapi) else: diff --git a/vmware_nsx/tests/unit/nsx_v/test_availability_zones.py b/vmware_nsx/tests/unit/nsx_v/test_availability_zones.py index cf441f618d..5064889ff4 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_availability_zones.py +++ b/vmware_nsx/tests/unit/nsx_v/test_availability_zones.py @@ -93,7 +93,7 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_simple_availability_zone(self): self._config_az() - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) self.assertEqual("respool", az.resource_pool) self.assertEqual("datastore", az.datastore_id) @@ -112,7 +112,7 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_availability_zone_no_edge_ha(self): self._config_az(edge_ha=False) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) self.assertEqual("respool", az.resource_pool) self.assertEqual("datastore", az.datastore_id) @@ -122,7 +122,7 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_availability_zone_no_ha_datastore(self): self._config_az(ha_datastore_id=None) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) self.assertEqual("respool", az.resource_pool) self.assertEqual("datastore", az.datastore_id) @@ -133,26 +133,26 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_missing_group_section(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "doesnt_exist") def test_availability_zone_missing_respool(self): self._config_az(resource_pool_id=None) self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, self.az_name) def test_availability_zone_missing_datastore(self): self._config_az(datastore_id=None) self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, self.az_name) def test_availability_zone_missing_edge_ha(self): self._config_az(edge_ha=None) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) self.assertEqual("respool", az.resource_pool) self.assertEqual("datastore", az.datastore_id) @@ -162,7 +162,7 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_availability_zone_missing_edge_placement(self): self._config_az(ha_placement_random=None) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) self.assertEqual("respool", az.resource_pool) self.assertEqual("datastore", az.datastore_id) @@ -173,14 +173,14 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): def test_availability_zone_missing_backup_pool(self): self._config_az(backup_edge_pool=None) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertEqual(self.az_name, az.name) # Should use the global configuration instead self.assertEqual(DEF_GLOBAL_POOL, az.backup_edge_pool) def test_availability_zone_missing_metadata(self): self._config_az(mgt_net_proxy_ips=None) - az = nsx_az.ConfiguredAvailabilityZone(self.az_name) + az = nsx_az.NsxVAvailabilityZone(self.az_name) self.assertIsNone(az.mgt_net_moid) self.assertEqual([], az.mgt_net_proxy_ips) self.assertIsNone(az.mgt_net_proxy_netmask) @@ -191,13 +191,13 @@ class NsxvAvailabilityZonesTestCase(base.BaseTestCase): self._config_az(mgt_net_proxy_ips=["2.2.2.2"]) self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, self.az_name) self._config_az(mgt_net_proxy_ips=["2.2.2.2", "3.3.3.3"]) self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, self.az_name) @@ -213,7 +213,7 @@ class NsxvAvailabilityZonesOldTestCase(base.BaseTestCase): cfg.CONF.set_override("dvs_id", "dvs-1", group="nsxv") def test_simple_availability_zone(self): - az = nsx_az.ConfiguredAvailabilityZone( + az = nsx_az.NsxVAvailabilityZone( "name:respool:datastore:true:hastore") self.assertEqual("name", az.name) self.assertEqual("respool", az.resource_pool) @@ -234,7 +234,7 @@ class NsxvAvailabilityZonesOldTestCase(base.BaseTestCase): self.assertIsNone(az.mgt_net_default_gateway) def test_availability_zone_without_ha_datastore(self): - az = nsx_az.ConfiguredAvailabilityZone( + az = nsx_az.NsxVAvailabilityZone( "name:respool:datastore:true") self.assertEqual("name", az.name) self.assertEqual("respool", az.resource_pool) @@ -243,7 +243,7 @@ class NsxvAvailabilityZonesOldTestCase(base.BaseTestCase): self.assertIsNone(az.ha_datastore_id) def test_availability_zone_without_edge_ha(self): - az = nsx_az.ConfiguredAvailabilityZone( + az = nsx_az.NsxVAvailabilityZone( "name:respool:datastore:FALSE") self.assertEqual("name", az.name) self.assertEqual("respool", az.resource_pool) @@ -254,29 +254,29 @@ class NsxvAvailabilityZonesOldTestCase(base.BaseTestCase): def test_availability_fail_long_name(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "very-very-very-very-very-longest-name:respool:da:true:ha") def test_availability_fail_few_args(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "name:respool") def test_availability_fail_many_args(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "name:1:2:3:4:5:6") def test_availability_fail_bad_edge_ha(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "name:respool:datastore:truex:hastore") def test_availability_fail_no_ha_datastore(self): self.assertRaises( nsx_exc.NsxInvalidConfiguration, - nsx_az.ConfiguredAvailabilityZone, + nsx_az.NsxVAvailabilityZone, "name:respool:datastore:false:hastore") diff --git a/vmware_nsx/tests/unit/nsx_v/test_plugin.py b/vmware_nsx/tests/unit/nsx_v/test_plugin.py index 17116edf52..d304dd69dd 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v/test_plugin.py @@ -714,7 +714,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase): az_name = 'az7' set_az_in_config(az_name) p = directory.get_plugin() - p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones() + p._availability_zones_data = nsx_az.NsxVAvailabilityZones() ctx = context.get_admin_context() data = {'network': { @@ -3305,7 +3305,7 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, az_name = 'az7' set_az_in_config(az_name) p = directory.get_plugin() - p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones() + p._availability_zones_data = nsx_az.NsxVAvailabilityZones() p._get_edge_id_by_rtr_id = p.real_get_edge router = {'router': {'admin_state_up': True, @@ -3727,7 +3727,7 @@ class TestVdrTestCase(L3NatTest, L3NatTestCaseBase, az_name = 'az7' set_az_in_config(az_name) p = directory.get_plugin() - p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones() + p._availability_zones_data = nsx_az.NsxVAvailabilityZones() # create a router with/without hints router = {'router': {'admin_state_up': True, @@ -4983,7 +4983,7 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, az_name = 'az7' set_az_in_config(az_name) p = directory.get_plugin() - p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones() + p._availability_zones_data = nsx_az.NsxVAvailabilityZones() # create a router with/without hints router = {'router': {'admin_state_up': True, @@ -5056,7 +5056,7 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase, self.az_name = 'az7' set_az_in_config(self.az_name) self.plugin._availability_zones_data = ( - nsx_az.ConfiguredAvailabilityZones()) + nsx_az.NsxVAvailabilityZones()) self._iteration = 1 def assertSyslogConfig(self, expected): diff --git a/vmware_nsx/tests/unit/nsx_v/vshield/test_edge_utils.py b/vmware_nsx/tests/unit/nsx_v/vshield/test_edge_utils.py index 8dd76f09be..9859829de4 100644 --- a/vmware_nsx/tests/unit/nsx_v/vshield/test_edge_utils.py +++ b/vmware_nsx/tests/unit/nsx_v/vshield/test_edge_utils.py @@ -58,7 +58,7 @@ class EdgeUtilsTestCaseMixin(testlib_api.SqlTestCase): get_ver.return_value = '6.1.4' self.ctx = context.get_admin_context() self.addCleanup(nsxv_manager_p.stop) - self.az = (nsx_az.ConfiguredAvailabilityZones(). + self.az = (nsx_az.NsxVAvailabilityZones(). get_default_availability_zone()) def _create_router(self, name='router1'): @@ -86,8 +86,8 @@ class EdgeUtilsTestCaseMixin(testlib_api.SqlTestCase): class DummyPlugin(object): - def get_network_az(self, context, network_id): - return (nsx_az.ConfiguredAvailabilityZones(). + def get_network_az_by_net_id(self, context, network_id): + return (nsx_az.NsxVAvailabilityZones(). get_default_availability_zone()) @@ -352,14 +352,14 @@ class EdgeManagerTestCase(EdgeUtilsTestCaseMixin): cfg.CONF.set_override('backup_edge_pool', ['service:large:1:3', 'service:compact:1:3'], 'nsxv') - az = nsx_az.ConfiguredAvailabilityZone(None) + az = nsx_az.NsxVAvailabilityZone(None) edge_pool_dicts = edge_utils.parse_backup_edge_pool_opt_per_az(az) self.assertEqual(self.default_edge_pool_dicts['default'], edge_pool_dicts) def test_backup_edge_pool_with_empty_conf(self): cfg.CONF.set_override('backup_edge_pool', [], 'nsxv') - az = nsx_az.ConfiguredAvailabilityZone(None) + az = nsx_az.NsxVAvailabilityZone(None) edge_pool_dicts = edge_utils.parse_backup_edge_pool_opt_per_az(az) expect_edge_pool_dicts = { nsxv_constants.SERVICE_EDGE: {}, @@ -368,7 +368,7 @@ class EdgeManagerTestCase(EdgeUtilsTestCaseMixin): def test_backup_edge_pool_with_vdr_conf(self): cfg.CONF.set_override('backup_edge_pool', ['vdr:large:1:3'], 'nsxv') - az = nsx_az.ConfiguredAvailabilityZone(None) + az = nsx_az.NsxVAvailabilityZone(None) edge_pool_dicts = edge_utils.parse_backup_edge_pool_opt_per_az(az) expect_edge_pool_dicts = self.vdr_edge_pool_dicts['default'] self.assertEqual(expect_edge_pool_dicts, edge_pool_dicts) @@ -377,7 +377,7 @@ class EdgeManagerTestCase(EdgeUtilsTestCaseMixin): cfg.CONF.set_override('backup_edge_pool', ['service:compact:1:3', 'service::3:4'], 'nsxv') - az = nsx_az.ConfiguredAvailabilityZone(None) + az = nsx_az.NsxVAvailabilityZone(None) self.assertRaises(n_exc.Invalid, edge_utils.parse_backup_edge_pool_opt_per_az, az) diff --git a/vmware_nsx/tests/unit/nsx_v/vshield/test_vcns_driver.py b/vmware_nsx/tests/unit/nsx_v/vshield/test_vcns_driver.py index 9e11b4038b..0fdb85ccb0 100644 --- a/vmware_nsx/tests/unit/nsx_v/vshield/test_vcns_driver.py +++ b/vmware_nsx/tests/unit/nsx_v/vshield/test_vcns_driver.py @@ -332,7 +332,7 @@ class VcnsDriverTestCase(base.BaseTestCase): self.vcns_driver = vcns_driver.VcnsDriver(self) - self.az = (nsx_az.ConfiguredAvailabilityZones(). + self.az = (nsx_az.NsxVAvailabilityZones(). get_default_availability_zone()) self.edge_id = None self.result = None