NSX|v3 replace configuration uuids with names
Support configuration of name or uuid (instead of only uuid) for 4 nsx_v3 parameters: default_overlay_tz, default_vlan_tz, default_bridge_cluster and default_tier0_router. Assert on init if the uuid or name was no found on the backend, or if the name is not unique. DocImpact: Configuration options default_overlay_tz_uuid, default_vlan_tz_uuid, default_bridge_cluster_uuid and default_tier0_router_uuid were replaced with default_overlay_tz, default_vlan_tz, default_bridge_cluster and default_tier0_router and support name or uuid now. Change-Id: Id153d4d69165b161c04c403b578657c51af20e9c
This commit is contained in:
parent
ae3023dc1e
commit
a88b99b6c9
@ -100,10 +100,10 @@ function _nsxv3_ini_set {
|
||||
}
|
||||
|
||||
function neutron_plugin_configure_service {
|
||||
_nsxv3_ini_set default_overlay_tz_uuid $DEFAULT_OVERLAY_TZ_UUID "The VMware NSX plugin won't work without a default transport zone."
|
||||
_nsxv3_ini_set default_vlan_tz_uuid $DEFAULT_VLAN_TZ_UUID
|
||||
_nsxv3_ini_set default_overlay_tz $DEFAULT_OVERLAY_TZ_UUID "The VMware NSX plugin won't work without a default transport zone."
|
||||
_nsxv3_ini_set default_vlan_tz $DEFAULT_VLAN_TZ_UUID
|
||||
if [[ "$DEFAULT_TIER0_ROUTER_UUID" != "" ]]; then
|
||||
_nsxv3_ini_set default_tier0_router_uuid $DEFAULT_TIER0_ROUTER_UUID
|
||||
_nsxv3_ini_set default_tier0_router $DEFAULT_TIER0_ROUTER_UUID
|
||||
Q_L3_ENABLED=True
|
||||
Q_L3_ROUTER_PER_TENANT=True
|
||||
fi
|
||||
@ -123,7 +123,7 @@ function neutron_plugin_configure_service {
|
||||
_nsxv3_ini_set retries $NSX_RETRIES
|
||||
_nsxv3_ini_set insecure $NSX_INSECURE
|
||||
_nsxv3_ini_set ca_file $NSX_CA_FILE
|
||||
_nsxv3_ini_set default_bridge_cluster_uuid $DEFAULT_BRIDGE_CLUSTER_UUID
|
||||
_nsxv3_ini_set default_bridge_cluster $DEFAULT_BRIDGE_CLUSTER_UUID
|
||||
}
|
||||
|
||||
function neutron_plugin_setup_interface_driver {
|
||||
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
prelude: >
|
||||
The 'default_tier0_router_uuid', 'default_overlay_tz_uuid',
|
||||
'default_vlan_tz_uuid', and 'default_bridge_cluster_uuid'
|
||||
options have been deprecated and replaced by 'default_tier0_router',
|
||||
'default_overlay_tz', 'default_vlan_tz', and 'default_bridge_cluster'
|
||||
respectively, which can accept both name or uuid
|
||||
deprecations:
|
||||
- The 'default_tier0_router_uuid', 'default_overlay_tz_uuid',
|
||||
'default_vlan_tz_uuid', and 'default_bridge_cluster_uuid'
|
||||
options have been deprecated and replaced by 'default_tier0_router',
|
||||
'default_overlay_tz', 'default_vlan_tz', and 'default_bridge_cluster'
|
||||
respectively, which can accept both name or uuid
|
@ -249,25 +249,30 @@ nsx_v3_opts = [
|
||||
"[<scheme>://]<ip_adress>[:<port>]\nIf scheme is not "
|
||||
"provided https is used. If port is not provided port "
|
||||
"80 is used for http and port 443 for https.")),
|
||||
cfg.StrOpt('default_overlay_tz_uuid',
|
||||
deprecated_name='default_tz_uuid',
|
||||
help=_("This is the 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_uuid',
|
||||
cfg.StrOpt('default_overlay_tz',
|
||||
deprecated_name='default_overlay_tz_uuid',
|
||||
help=_("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',
|
||||
deprecated_name='default_vlan_tz_uuid',
|
||||
help=_("(Optional) Only required when creating VLAN or flat "
|
||||
"provider networks. UUID of default NSX VLAN transport "
|
||||
"zone that will be used for bridging between Neutron "
|
||||
"networks, if no physical network has been specified")),
|
||||
cfg.StrOpt('default_bridge_cluster_uuid',
|
||||
help=_("(Optional) UUID of the default NSX bridge cluster that "
|
||||
"will be used to perform L2 gateway bridging between "
|
||||
"VXLAN and VLAN networks. If default bridge cluster "
|
||||
"UUID is not specified, admin will have to manually "
|
||||
"create a L2 gateway corresponding to a NSX Bridge "
|
||||
"Cluster using L2 gateway APIs. This field must be "
|
||||
"specified on one of the active neutron servers only.")),
|
||||
"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")),
|
||||
cfg.StrOpt('default_bridge_cluster',
|
||||
deprecated_name='default_bridge_cluster_uuid',
|
||||
help=_("(Optional) Name or UUID of the default NSX bridge "
|
||||
"cluster that will be used to perform L2 gateway "
|
||||
"bridging between VXLAN and VLAN networks. If default "
|
||||
"bridge cluster UUID is not specified, admin will have "
|
||||
"to manually create a L2 gateway corresponding to a "
|
||||
"NSX Bridge Cluster using L2 gateway APIs. This field "
|
||||
"must be specified on one of the active neutron "
|
||||
"servers only.")),
|
||||
cfg.IntOpt('retries',
|
||||
default=10,
|
||||
help=_('Maximum number of times to retry API requests upon '
|
||||
@ -306,10 +311,11 @@ nsx_v3_opts = [
|
||||
cfg.IntOpt('redirects',
|
||||
default=2,
|
||||
help=_('Number of times a HTTP redirect should be followed.')),
|
||||
cfg.StrOpt('default_tier0_router_uuid',
|
||||
help=_("UUID of the default tier0 router that will be used for "
|
||||
"connecting to tier1 logical routers and configuring "
|
||||
"external networks")),
|
||||
cfg.StrOpt('default_tier0_router',
|
||||
deprecated_name='default_tier0_router_uuid',
|
||||
help=_("Name or UUID of the default tier0 router that will be "
|
||||
"used for connecting to tier1 logical routers and "
|
||||
"configuring external networks")),
|
||||
cfg.IntOpt('number_of_nested_groups',
|
||||
default=8,
|
||||
help=_("(Optional) The number of nested groups which are used "
|
||||
|
@ -231,3 +231,57 @@ def delete_bridge_endpoint(bridge_endpoint_id):
|
||||
"""
|
||||
resource = 'bridge-endpoints/%s' % bridge_endpoint_id
|
||||
client.delete_resource(resource)
|
||||
|
||||
|
||||
def _get_resource_by_name_or_id(name_or_id, resource):
|
||||
all_results = client.get_resource(resource)['results']
|
||||
matched_results = []
|
||||
for rs in all_results:
|
||||
if rs.get('id') == name_or_id:
|
||||
# Matched by id - must be unique
|
||||
return name_or_id
|
||||
|
||||
if rs.get('display_name') == name_or_id:
|
||||
# Matched by name - add to the list to verify it is unique
|
||||
matched_results.append(rs)
|
||||
|
||||
if len(matched_results) == 0:
|
||||
err_msg = (_("Could not find %(resource)s %(name)s") %
|
||||
{'name': name_or_id, 'resource': resource})
|
||||
raise nsx_exc.NsxPluginException(err_msg=err_msg)
|
||||
elif len(matched_results) > 1:
|
||||
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
||||
{'name': name_or_id, 'resource': resource})
|
||||
raise nsx_exc.NsxPluginException(err_msg=err_msg)
|
||||
|
||||
return matched_results[0].get('id')
|
||||
|
||||
|
||||
def get_transport_zone_id_by_name_or_id(name_or_id):
|
||||
"""Get a transport zone by it's display name or uuid
|
||||
|
||||
Return the transport zone data, or raise an exception if not found or
|
||||
not unique
|
||||
"""
|
||||
|
||||
return _get_resource_by_name_or_id(name_or_id, 'transport-zones')
|
||||
|
||||
|
||||
def get_logical_router_id_by_name_or_id(name_or_id):
|
||||
"""Get a logical router by it's display name or uuid
|
||||
|
||||
Return the logical router data, or raise an exception if not found or
|
||||
not unique
|
||||
"""
|
||||
|
||||
return _get_resource_by_name_or_id(name_or_id, 'logical-routers')
|
||||
|
||||
|
||||
def get_bridge_cluster_id_by_name_or_id(name_or_id):
|
||||
"""Get a bridge cluster by it's display name or uuid
|
||||
|
||||
Return the bridge cluster data, or raise an exception if not found or
|
||||
not unique
|
||||
"""
|
||||
|
||||
return _get_resource_by_name_or_id(name_or_id, 'bridge-clusters')
|
||||
|
@ -180,6 +180,31 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
raise nsx_exc.NsxPluginException(msg)
|
||||
self._unsubscribe_callback_events()
|
||||
|
||||
# translate configured transport zones/rotuers names to uuid
|
||||
self._translate_configured_names_2_uuids()
|
||||
|
||||
def _translate_configured_names_2_uuids(self):
|
||||
# default VLAN transport zone name / uuid
|
||||
self._default_vlan_tz_uuid = None
|
||||
if cfg.CONF.nsx_v3.default_vlan_tz:
|
||||
tz_id = nsxlib.get_transport_zone_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 = nsxlib.get_transport_zone_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:
|
||||
rtr_id = nsxlib.get_logical_router_id_by_name_or_id(
|
||||
cfg.CONF.nsx_v3.default_tier0_router)
|
||||
self._default_tier0_router = rtr_id
|
||||
|
||||
def _extend_port_dict_binding(self, context, port_data):
|
||||
port_data[pbin.VIF_TYPE] = pbin.VIF_TYPE_OVS
|
||||
port_data[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
|
||||
@ -344,11 +369,11 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# Set VLAN id to 0 for flat networks
|
||||
vlan_id = '0'
|
||||
if physical_net is None:
|
||||
physical_net = cfg.CONF.nsx_v3.default_vlan_tz_uuid
|
||||
physical_net = self._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 = cfg.CONF.nsx_v3.default_vlan_tz_uuid
|
||||
physical_net = self._default_vlan_tz_uuid
|
||||
|
||||
# Validate VLAN id
|
||||
if not vlan_id:
|
||||
@ -394,7 +419,7 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
|
||||
if physical_net is None:
|
||||
# Default to transport type overlay
|
||||
physical_net = cfg.CONF.nsx_v3.default_overlay_tz_uuid
|
||||
physical_net = self._default_overlay_tz_uuid
|
||||
|
||||
return is_provider_net, net_type, physical_net, vlan_id
|
||||
|
||||
@ -407,7 +432,7 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
def _validate_external_net_create(self, net_data):
|
||||
is_provider_net = False
|
||||
if not attributes.is_attr_set(net_data.get(pnet.PHYSICAL_NETWORK)):
|
||||
tier0_uuid = cfg.CONF.nsx_v3.default_tier0_router_uuid
|
||||
tier0_uuid = self._default_tier0_router
|
||||
else:
|
||||
tier0_uuid = net_data[pnet.PHYSICAL_NETWORK]
|
||||
is_provider_net = True
|
||||
@ -1237,7 +1262,7 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
|
||||
return
|
||||
network = self.get_network(context, network_id)
|
||||
if not network.get(pnet.PHYSICAL_NETWORK):
|
||||
return cfg.CONF.nsx_v3.default_tier0_router_uuid
|
||||
return self._default_tier0_router
|
||||
else:
|
||||
return network.get(pnet.PHYSICAL_NETWORK)
|
||||
|
||||
|
@ -49,7 +49,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
||||
gateway_resource = l2gw_const.GATEWAY_RESOURCE_NAME
|
||||
|
||||
def __init__(self):
|
||||
# Create a default L2 gateway if default_bridge_cluster_uuid is
|
||||
# Create a default L2 gateway if default_bridge_cluster is
|
||||
# provided in nsx.ini
|
||||
self._ensure_default_l2_gateway()
|
||||
self.subscribe_callback_notifications()
|
||||
@ -69,16 +69,20 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
||||
Create a default logical L2 gateway.
|
||||
|
||||
Create a logical L2 gateway in the neutron database if the
|
||||
default_bridge_cluster_uuid config parameter is set and if it is
|
||||
default_bridge_cluster config parameter is set and if it is
|
||||
not previously created. If not set, return.
|
||||
"""
|
||||
def_l2gw_uuid = cfg.CONF.nsx_v3.default_bridge_cluster_uuid
|
||||
# Return if no default_bridge_cluster_uuid set in config
|
||||
if not def_l2gw_uuid:
|
||||
LOG.info(_LI("NSX: Default bridge cluster UUID not configured "
|
||||
def_l2gw_name = cfg.CONF.nsx_v3.default_bridge_cluster
|
||||
# Return if no default_bridge_cluster set in config
|
||||
if not def_l2gw_name:
|
||||
LOG.info(_LI("NSX: Default bridge cluster not configured "
|
||||
"in nsx.ini. No default L2 gateway created."))
|
||||
return
|
||||
admin_ctx = context.get_admin_context()
|
||||
|
||||
def_l2gw_uuid = nsxlib.get_bridge_cluster_id_by_name_or_id(
|
||||
def_l2gw_name)
|
||||
|
||||
# Optimistically create the default L2 gateway in neutron DB
|
||||
device = {'device_name': def_l2gw_uuid,
|
||||
'interfaces': [{'name': 'default-bridge-cluster'}]}
|
||||
|
@ -22,6 +22,7 @@ from vmware_nsx.common import nsx_constants
|
||||
|
||||
FAKE_NAME = "fake_name"
|
||||
DEFAULT_TIER0_ROUTER_UUID = "efad0078-9204-4b46-a2d8-d4dd31ed448f"
|
||||
NSX_BRIDGE_CLUSTER_NAME = 'default bridge cluster'
|
||||
FAKE_MANAGER = "fake_manager_ip"
|
||||
|
||||
|
||||
|
@ -123,6 +123,20 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
|
||||
'display_name': nsx_plugin.NSX_V3_NO_PSEC_PROFILE_NAME
|
||||
}), headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS)
|
||||
|
||||
self.mock_api.post(
|
||||
'api/v1/transport-zones',
|
||||
data=jsonutils.dumps({
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'display_name': nsxlib_testcase.NSX_TZ_NAME
|
||||
}), headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS)
|
||||
|
||||
self.mock_api.post(
|
||||
'api/v1/bridge-clusters',
|
||||
data=jsonutils.dumps({
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'display_name': nsx_v3_mocks.NSX_BRIDGE_CLUSTER_NAME
|
||||
}), headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS)
|
||||
|
||||
super(NsxV3PluginTestCaseMixin, self).setUp(plugin=plugin,
|
||||
ext_mgr=ext_mgr)
|
||||
|
||||
|
@ -18,8 +18,8 @@ import mock
|
||||
import unittest
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
from requests import exceptions as requests_exceptions
|
||||
|
||||
from vmware_nsx.nsxlib.v3 import client as nsx_client
|
||||
from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster
|
||||
|
||||
@ -30,6 +30,7 @@ NSX_INSECURE = False
|
||||
NSX_CERT = '/opt/stack/certs/nsx.pem'
|
||||
NSX_HTTP_TIMEOUT = 10
|
||||
NSX_HTTP_READ_TIMEOUT = 180
|
||||
NSX_TZ_NAME = 'default transport zone'
|
||||
|
||||
V3_CLIENT_PKG = 'vmware_nsx.nsxlib.v3.client'
|
||||
BRIDGE_FNS = ['create_resource', 'delete_resource',
|
||||
@ -40,8 +41,7 @@ class NsxLibTestCase(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setup_conf_overrides(cls):
|
||||
cfg.CONF.set_override('default_overlay_tz_uuid',
|
||||
uuidutils.generate_uuid(), 'nsx_v3')
|
||||
cfg.CONF.set_override('default_overlay_tz', NSX_TZ_NAME, 'nsx_v3')
|
||||
cfg.CONF.set_override('nsx_api_user', NSX_USER, 'nsx_v3')
|
||||
cfg.CONF.set_override('nsx_api_password', NSX_PASSWORD, 'nsx_v3')
|
||||
cfg.CONF.set_override('nsx_api_managers', [NSX_MANAGER], 'nsx_v3')
|
||||
|
@ -26,8 +26,10 @@ from neutron.tests import base
|
||||
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
||||
from vmware_nsx.services.l2gateway.common import plugin as l2gw_plugin
|
||||
from vmware_nsx.services.l2gateway.nsx_v3 import driver as nsx_v3_driver
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin as test_nsx_v3_plugin
|
||||
|
||||
|
||||
@ -69,14 +71,16 @@ class TestNsxV3L2GatewayDriver(test_l2gw_db.L2GWTestCase,
|
||||
self.assertTrue(debug.called)
|
||||
|
||||
def test_create_default_l2_gateway(self):
|
||||
def_bridge_cluster_id = uuidutils.generate_uuid()
|
||||
def_bridge_cluster_name = nsx_v3_mocks.NSX_BRIDGE_CLUSTER_NAME
|
||||
with mock.patch.object(nsx_v3_driver.NsxV3Driver,
|
||||
'subscribe_callback_notifications'):
|
||||
cfg.CONF.set_override("default_bridge_cluster_uuid",
|
||||
def_bridge_cluster_id,
|
||||
cfg.CONF.set_override("default_bridge_cluster",
|
||||
def_bridge_cluster_name,
|
||||
"nsx_v3")
|
||||
l2gw_plugin.NsxL2GatewayPlugin()
|
||||
l2gws = self.driver._get_l2_gateways(self.context)
|
||||
def_bridge_cluster_id = nsxlib.get_bridge_cluster_id_by_name_or_id(
|
||||
def_bridge_cluster_name)
|
||||
def_l2gw = None
|
||||
for l2gw in l2gws:
|
||||
for device in l2gw['devices']:
|
||||
@ -89,11 +93,11 @@ class TestNsxV3L2GatewayDriver(test_l2gw_db.L2GWTestCase,
|
||||
'default-bridge-cluster')
|
||||
|
||||
def test_create_duplicate_default_l2_gateway_noop(self):
|
||||
def_bridge_cluster_id = uuidutils.generate_uuid()
|
||||
def_bridge_cluster_name = nsx_v3_mocks.NSX_BRIDGE_CLUSTER_NAME
|
||||
with mock.patch.object(nsx_v3_driver.NsxV3Driver,
|
||||
'subscribe_callback_notifications'):
|
||||
cfg.CONF.set_override("default_bridge_cluster_uuid",
|
||||
def_bridge_cluster_id,
|
||||
cfg.CONF.set_override("default_bridge_cluster",
|
||||
def_bridge_cluster_name,
|
||||
"nsx_v3")
|
||||
l2gw_plugin.NsxL2GatewayPlugin()
|
||||
l2gw_plugin.NsxL2GatewayPlugin()
|
||||
|
Loading…
Reference in New Issue
Block a user