NSX|V add edge_ha per availability zone
Support different edge_ha flag per availability zone Change-Id: Iff1b9d76a62d23d600b57ad83d868c4de2b04ee9
This commit is contained in:
parent
2b7210313c
commit
2f2d770b9b
@ -27,7 +27,7 @@ NSXV_PASSWORD # NSXv password.
|
||||
NSXV_CLUSTER_MOID # clusters ids containing OpenStack hosts.
|
||||
NSXV_DATACENTER_MOID # datacenter id for edge deployment.
|
||||
NSXV_RESOURCE_POOL_ID # resource-pool id for edge deployment.
|
||||
NSXV_AVAILABILITY_ZONES # alternative resource-pools ids for edge deployment
|
||||
NSXV_AVAILABILITY_ZONES # alternative resource-pools/data stores ids/edge_ha for edge deployment
|
||||
NSXV_DATASTORE_ID # datastore id for edge deployment.
|
||||
NSXV_EXTERNAL_NETWORK # id of logic switch for physical network connectivity.
|
||||
NSXV_VDN_SCOPE_ID # network scope id for VXLAN virtual-wires.
|
||||
|
@ -431,8 +431,8 @@ nsxv_opts = [
|
||||
default=[],
|
||||
help=_('Optional parameter defining the availability zones '
|
||||
'for deploying NSX Edges with the format: <zone name>:'
|
||||
'<resource pool id]:<datastore id>:<(optional)HA '
|
||||
'datastore id>.')),
|
||||
'<resource pool id]:<datastore id>:<edge_ha True/False>'
|
||||
'<(optional)HA datastore id>.')),
|
||||
cfg.StrOpt('datastore_id',
|
||||
deprecated_group="vcns",
|
||||
help=_('Optional parameter identifying the ID of datastore to '
|
||||
|
@ -188,3 +188,8 @@ class NsxTaaSDriverException(NsxPluginException):
|
||||
|
||||
class NsxPortMirrorSessionMappingNotFound(n_exc.NotFound):
|
||||
message = _("Unable to find mapping for Tap Flow: %(tf)s")
|
||||
|
||||
|
||||
class NsxInvalidConfiguration(n_exc.InvalidConfigurationOption):
|
||||
message = _("An invalid value was provided for %(opt_name)s: "
|
||||
"%(opt_value)s: %(reason)s")
|
||||
|
@ -13,10 +13,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
|
||||
DEFAULT_NAME = 'default'
|
||||
|
||||
@ -26,23 +26,49 @@ class ConfiguredAvailabilityZone(object):
|
||||
def __init__(self, config_line):
|
||||
if config_line:
|
||||
values = config_line.split(':')
|
||||
if len(values) < 3 or len(values) > 4:
|
||||
raise n_exc.Invalid(_("Invalid availability zones format"))
|
||||
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 limit in the DB
|
||||
# field name size in the DB is 36
|
||||
if len(self.name) > 36:
|
||||
raise n_exc.Invalid(_("Invalid availability zone name %s: "
|
||||
"max name length is 36"), self.name)
|
||||
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.ha_datastore_id = values[3] if len(values) == 4 else None
|
||||
|
||||
# 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"))
|
||||
|
||||
self.ha_datastore_id = values[4] if len(values) == 5 else 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
|
||||
|
||||
|
||||
@ -55,7 +81,6 @@ class ConfiguredAvailabilityZones(object):
|
||||
for az in cfg.CONF.nsxv.availability_zones:
|
||||
obj = ConfiguredAvailabilityZone(az)
|
||||
self.availability_zones[obj.name] = obj
|
||||
# DEBUG ADIT - name max len 36 (DB)
|
||||
|
||||
# add a default entry
|
||||
obj = ConfiguredAvailabilityZone(None)
|
||||
|
@ -46,7 +46,8 @@ class EdgeApplianceDriver(object):
|
||||
def _assemble_edge(self, name, appliance_size="compact",
|
||||
deployment_container_id=None, datacenter_moid=None,
|
||||
enable_aesni=True, dist=False,
|
||||
enable_fips=False, remote_access=False):
|
||||
enable_fips=False, remote_access=False,
|
||||
edge_ha=False):
|
||||
edge = {
|
||||
'name': name,
|
||||
'fqdn': None,
|
||||
@ -86,7 +87,7 @@ class EdgeApplianceDriver(object):
|
||||
if datacenter_moid:
|
||||
edge['datacenterMoid'] = datacenter_moid
|
||||
|
||||
if not dist and cfg.CONF.nsxv.edge_ha:
|
||||
if not dist and edge_ha:
|
||||
self._enable_high_availability(edge)
|
||||
|
||||
return edge
|
||||
@ -97,7 +98,7 @@ class EdgeApplianceDriver(object):
|
||||
appliances.append(self._assemble_edge_appliance(
|
||||
availability_zone.resource_pool,
|
||||
availability_zone.datastore_id))
|
||||
if availability_zone.ha_datastore_id and cfg.CONF.nsxv.edge_ha:
|
||||
if availability_zone.ha_datastore_id and availability_zone.edge_ha:
|
||||
appliances.append(self._assemble_edge_appliance(
|
||||
availability_zone.resource_pool,
|
||||
availability_zone.ha_datastore_id))
|
||||
@ -522,7 +523,8 @@ class EdgeApplianceDriver(object):
|
||||
edge = self._assemble_edge(
|
||||
edge_name, datacenter_moid=self.datacenter_moid,
|
||||
deployment_container_id=self.deployment_container_id,
|
||||
appliance_size=appliance_size, remote_access=False, dist=dist)
|
||||
appliance_size=appliance_size, remote_access=False, dist=dist,
|
||||
edge_ha=availability_zone.edge_ha)
|
||||
appliances = self._assemble_edge_appliances(availability_zone)
|
||||
if appliances:
|
||||
edge['appliances']['appliances'] = appliances
|
||||
@ -610,7 +612,8 @@ class EdgeApplianceDriver(object):
|
||||
edge = self._assemble_edge(
|
||||
edge_name, datacenter_moid=self.datacenter_moid,
|
||||
deployment_container_id=self.deployment_container_id,
|
||||
appliance_size=appliance_size, remote_access=False, dist=dist)
|
||||
appliance_size=appliance_size, remote_access=False, dist=dist,
|
||||
edge_ha=availability_zone.edge_ha)
|
||||
edge['id'] = edge_id
|
||||
appliances = self._assemble_edge_appliances(availability_zone)
|
||||
if appliances:
|
||||
|
@ -19,7 +19,6 @@ from networking_l2gw.services.l2gateway.common import constants as l2gw_const
|
||||
from networking_l2gw.services.l2gateway import exceptions as l2gw_exc
|
||||
from neutron import manager
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
@ -119,7 +118,7 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin):
|
||||
if not edge_binding:
|
||||
raise nsx_exc.NsxL2GWDeviceNotFound()
|
||||
# Enable edge HA on the DLR
|
||||
if cfg.CONF.nsxv.edge_ha:
|
||||
if availability_zone.edge_ha:
|
||||
edge_id = edge_binding['edge_id']
|
||||
self._edge_manager.nsxv_manager.update_edge_ha(edge_id)
|
||||
return edge_binding['edge_id']
|
||||
|
@ -25,7 +25,6 @@ import vmware_nsx.shell.resources as shell
|
||||
|
||||
from neutron.callbacks import registry
|
||||
from neutron_lib import exceptions
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _LE, _LI
|
||||
from vmware_nsx.common import nsxv_constants
|
||||
@ -208,14 +207,13 @@ def change_edge_appliance(edge_id):
|
||||
configuration is updated, or when the configuration of a specific
|
||||
availability zone was updated.
|
||||
"""
|
||||
edge_ha = cfg.CONF.nsxv.edge_ha
|
||||
# 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)
|
||||
appliances = [{'resourcePoolId': az.resource_pool,
|
||||
'datastoreId': az.datastore_id}]
|
||||
|
||||
if az.ha_datastore_id and edge_ha:
|
||||
if az.ha_datastore_id and az.edge_ha:
|
||||
appliances.append({'resourcePoolId': az.resource_pool,
|
||||
'datastoreId': az.ha_datastore_id})
|
||||
request = {'appliances': appliances, 'applianceSize': size}
|
||||
@ -227,7 +225,7 @@ def change_edge_appliance(edge_id):
|
||||
LOG.error(_LE("%s"), str(e))
|
||||
else:
|
||||
# also update the edge_ha of the edge
|
||||
change_edge_ha(edge_ha, edge_id)
|
||||
change_edge_ha(az.edge_ha, edge_id)
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
|
79
vmware_nsx/tests/unit/nsx_v/test_availability_zones.py
Normal file
79
vmware_nsx/tests/unit/nsx_v/test_availability_zones.py
Normal file
@ -0,0 +1,79 @@
|
||||
# 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.
|
||||
|
||||
from neutron.tests import base
|
||||
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.plugins.nsx_v import availability_zones as nsx_az
|
||||
|
||||
|
||||
class NsxvAvailabilityZonesTestCase(base.BaseTestCase):
|
||||
|
||||
def test_simple_availability_zone(self):
|
||||
az = nsx_az.ConfiguredAvailabilityZone(
|
||||
"name:respool:datastore:true:hastore")
|
||||
self.assertEqual("name", az.name)
|
||||
self.assertEqual("respool", az.resource_pool)
|
||||
self.assertEqual("datastore", az.datastore_id)
|
||||
self.assertEqual(True, az.edge_ha)
|
||||
self.assertEqual("hastore", az.ha_datastore_id)
|
||||
|
||||
def test_availability_zone_without_ha_datastore(self):
|
||||
az = nsx_az.ConfiguredAvailabilityZone(
|
||||
"name:respool:datastore:true")
|
||||
self.assertEqual("name", az.name)
|
||||
self.assertEqual("respool", az.resource_pool)
|
||||
self.assertEqual("datastore", az.datastore_id)
|
||||
self.assertEqual(True, az.edge_ha)
|
||||
self.assertEqual(None, az.ha_datastore_id)
|
||||
|
||||
def test_availability_zone_without_edge_ha(self):
|
||||
az = nsx_az.ConfiguredAvailabilityZone(
|
||||
"name:respool:datastore:FALSE")
|
||||
self.assertEqual("name", az.name)
|
||||
self.assertEqual("respool", az.resource_pool)
|
||||
self.assertEqual("datastore", az.datastore_id)
|
||||
self.assertEqual(False, az.edge_ha)
|
||||
self.assertEqual(None, az.ha_datastore_id)
|
||||
|
||||
def test_availability_fail_long_name(self):
|
||||
self.assertRaises(
|
||||
nsx_exc.NsxInvalidConfiguration,
|
||||
nsx_az.ConfiguredAvailabilityZone,
|
||||
"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,
|
||||
"name:respool")
|
||||
|
||||
def test_availability_fail_many_args(self):
|
||||
self.assertRaises(
|
||||
nsx_exc.NsxInvalidConfiguration,
|
||||
nsx_az.ConfiguredAvailabilityZone,
|
||||
"name:1:2:3:4:5:6")
|
||||
|
||||
def test_availability_fail_bad_edge_ha(self):
|
||||
self.assertRaises(
|
||||
nsx_exc.NsxInvalidConfiguration,
|
||||
nsx_az.ConfiguredAvailabilityZone,
|
||||
"name:respool:datastore:truex:hastore")
|
||||
|
||||
def test_availability_fail_no_ha_datastore(self):
|
||||
self.assertRaises(
|
||||
nsx_exc.NsxInvalidConfiguration,
|
||||
nsx_az.ConfiguredAvailabilityZone,
|
||||
"name:respool:datastore:false:hastore")
|
@ -632,7 +632,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
|
||||
def test_create_network_with_az_hint(self):
|
||||
az_name = 'az7'
|
||||
az_config = az_name + ':respool-7:datastore-7'
|
||||
az_config = az_name + ':respool-7:datastore-7:False'
|
||||
cfg.CONF.set_override('availability_zones', [az_config], group="nsxv")
|
||||
p = manager.NeutronManager.get_plugin()
|
||||
p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones()
|
||||
@ -3085,7 +3085,7 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
|
||||
|
||||
def test_create_router_with_az_hint(self):
|
||||
az_name = 'az7'
|
||||
az_config = az_name + ':respool-7:datastore-7'
|
||||
az_config = az_name + ':respool-7:datastore-7:True'
|
||||
cfg.CONF.set_override('availability_zones', [az_config], group="nsxv")
|
||||
p = manager.NeutronManager.get_plugin()
|
||||
p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones()
|
||||
@ -3379,7 +3379,7 @@ class TestVdrTestCase(L3NatTest, L3NatTestCaseBase,
|
||||
def _test_create_rotuer_with_az_hint(self, with_hint):
|
||||
# init the availability zones in the plugin
|
||||
az_name = 'az7'
|
||||
az_config = az_name + ':respool-7:datastore-7'
|
||||
az_config = az_name + ':respool-7:datastore-7:False'
|
||||
cfg.CONF.set_override('availability_zones', [az_config], group="nsxv")
|
||||
p = manager.NeutronManager.get_plugin()
|
||||
p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones()
|
||||
@ -4584,7 +4584,7 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase,
|
||||
def _test_create_rotuer_with_az_hint(self, with_hint):
|
||||
# init the availability zones in the plugin
|
||||
az_name = 'az7'
|
||||
az_config = az_name + ':respool-7:datastore-7'
|
||||
az_config = az_name + ':respool-7:datastore-7:True'
|
||||
cfg.CONF.set_override('availability_zones', [az_config], group="nsxv")
|
||||
p = manager.NeutronManager.get_plugin()
|
||||
p._availability_zones_data = nsx_az.ConfiguredAvailabilityZones()
|
||||
|
Loading…
Reference in New Issue
Block a user