NSX|v3: configure additional switching profiles per AZ
New configuration option is added to the nsx-v3 plugin: switching_profiles. It will contain a list of switching profiles uuids that will be added to NSX ports created by neutron. The configuration is global or per availability zone. In case the port should contain a different profile of some type, the port-specific profile will be used, since the backend takes the last one of each type. Change-Id: Ifa1dba2250b224201e6f81816feb536a35b642a5
This commit is contained in:
parent
81753f0584
commit
ef3db6aba7
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
prelude: >
|
||||||
|
The nsx-v3 plugin can add pre-configured switching profiles to new nsx
|
||||||
|
ports. The configuration can also be done per availability zone.
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The nsx-v3 plugin can add pre-configured switching profiles to new nsx
|
||||||
|
ports. The configuration can also be done per availability zone.
|
@ -434,6 +434,11 @@ nsx_v3_opts = [
|
|||||||
help=_("This is the scope of the tag that will be used for "
|
help=_("This is the scope of the tag that will be used for "
|
||||||
"finding the objects uuids on the NSX during plugin "
|
"finding the objects uuids on the NSX during plugin "
|
||||||
"init.")),
|
"init.")),
|
||||||
|
cfg.ListOpt('switching_profiles',
|
||||||
|
default=[],
|
||||||
|
help=_("Optional parameter defining a list switching profiles "
|
||||||
|
"uuids that will be attached to all neutron created "
|
||||||
|
"nsx ports.")),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -792,6 +797,9 @@ nsxv3_az_opts = [
|
|||||||
"transport zone that will be used for bridging between "
|
"transport zone that will be used for bridging between "
|
||||||
"Neutron networks, if no physical network has been "
|
"Neutron networks, if no physical network has been "
|
||||||
"specified")),
|
"specified")),
|
||||||
|
cfg.ListOpt('switching_profiles',
|
||||||
|
help=_("(Optional) list switching profiles uuids that will be "
|
||||||
|
"attached to all neutron created nsx ports.")),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Register the configuration options
|
# Register the configuration options
|
||||||
|
@ -19,7 +19,7 @@ from vmware_nsx._i18n import _
|
|||||||
from vmware_nsx.common import availability_zones as common_az
|
from vmware_nsx.common import availability_zones as common_az
|
||||||
from vmware_nsx.common import config
|
from vmware_nsx.common import config
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
from vmware_nsx.common import exceptions as nsx_exc
|
||||||
|
from vmware_nsxlib.v3 import core_resources
|
||||||
|
|
||||||
DEFAULT_NAME = common_az.DEFAULT_NAME
|
DEFAULT_NAME = common_az.DEFAULT_NAME
|
||||||
|
|
||||||
@ -74,6 +74,10 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone):
|
|||||||
if self.default_vlan_tz is None:
|
if self.default_vlan_tz is None:
|
||||||
self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz
|
self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz
|
||||||
|
|
||||||
|
self.switching_profiles = az_info.get('switching_profiles')
|
||||||
|
if self.switching_profiles is None:
|
||||||
|
self.switching_profiles = cfg.CONF.nsx_v3.switching_profiles
|
||||||
|
|
||||||
def init_default_az(self):
|
def init_default_az(self):
|
||||||
# use the default configuration
|
# use the default configuration
|
||||||
self.metadata_proxy = cfg.CONF.nsx_v3.metadata_proxy
|
self.metadata_proxy = cfg.CONF.nsx_v3.metadata_proxy
|
||||||
@ -83,6 +87,7 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone):
|
|||||||
self.nameservers = cfg.CONF.nsx_v3.nameservers
|
self.nameservers = cfg.CONF.nsx_v3.nameservers
|
||||||
self.default_overlay_tz = cfg.CONF.nsx_v3.default_overlay_tz
|
self.default_overlay_tz = cfg.CONF.nsx_v3.default_overlay_tz
|
||||||
self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz
|
self.default_vlan_tz = cfg.CONF.nsx_v3.default_vlan_tz
|
||||||
|
self.switching_profiles = cfg.CONF.nsx_v3.switching_profiles
|
||||||
|
|
||||||
def translate_configured_names_to_uuids(self, nsxlib):
|
def translate_configured_names_to_uuids(self, nsxlib):
|
||||||
# Mandatory configurations (in AZ or inherited from global values)
|
# Mandatory configurations (in AZ or inherited from global values)
|
||||||
@ -154,6 +159,18 @@ class NsxV3AvailabilityZone(common_az.ConfiguredAvailabilityZone):
|
|||||||
else:
|
else:
|
||||||
self._default_vlan_tz_uuid = None
|
self._default_vlan_tz_uuid = None
|
||||||
|
|
||||||
|
# switching profiles are already uuids, but we need to translate
|
||||||
|
# those to objects
|
||||||
|
profiles = []
|
||||||
|
if self.switching_profiles:
|
||||||
|
for profile in self.switching_profiles:
|
||||||
|
nsx_profile = nsxlib.switching_profile.get(profile)
|
||||||
|
# TODO(asarfaty): skip or alert on unsupported types
|
||||||
|
profiles.append(core_resources.SwitchingProfileTypeId(
|
||||||
|
nsx_profile.get('resource_type'),
|
||||||
|
nsx_profile.get('id')))
|
||||||
|
self.switching_profiles_objs = profiles
|
||||||
|
|
||||||
|
|
||||||
class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones):
|
class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones):
|
||||||
|
|
||||||
|
@ -1626,6 +1626,14 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
vif_uuid = port_data['id']
|
vif_uuid = port_data['id']
|
||||||
|
|
||||||
profiles = []
|
profiles = []
|
||||||
|
|
||||||
|
# Add availability zone profiles first (so that specific profiles will
|
||||||
|
# override them)
|
||||||
|
port_az = self.get_network_az_by_net_id(context,
|
||||||
|
port_data['network_id'])
|
||||||
|
if port_az.switching_profiles_objs:
|
||||||
|
profiles.extend(port_az.switching_profiles_objs)
|
||||||
|
|
||||||
mac_learning_profile_set = False
|
mac_learning_profile_set = False
|
||||||
if psec_is_on:
|
if psec_is_on:
|
||||||
address_pairs = port_data.get(addr_pair.ADDRESS_PAIRS)
|
address_pairs = port_data.get(addr_pair.ADDRESS_PAIRS)
|
||||||
@ -2420,6 +2428,14 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||||
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
||||||
|
|
||||||
|
# Add availability zone profiles first (so that specific profiles will
|
||||||
|
# override them)
|
||||||
|
port_az = self.get_network_az_by_net_id(context,
|
||||||
|
updated_port['network_id'])
|
||||||
|
if port_az.switching_profiles_objs:
|
||||||
|
switch_profile_ids = (port_az.switching_profiles_objs +
|
||||||
|
switch_profile_ids)
|
||||||
|
|
||||||
# Update the DHCP profile
|
# Update the DHCP profile
|
||||||
if updated_device_owner == const.DEVICE_OWNER_DHCP:
|
if updated_device_owner == const.DEVICE_OWNER_DHCP:
|
||||||
switch_profile_ids.append(self._dhcp_profile)
|
switch_profile_ids.append(self._dhcp_profile)
|
||||||
|
@ -40,6 +40,7 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase):
|
|||||||
"native_metadata_route", "1.1.1.1", group="nsx_v3")
|
"native_metadata_route", "1.1.1.1", group="nsx_v3")
|
||||||
cfg.CONF.set_override("dns_domain", "xxx.com", group="nsx_v3")
|
cfg.CONF.set_override("dns_domain", "xxx.com", group="nsx_v3")
|
||||||
cfg.CONF.set_override("nameservers", ["10.1.1.1"], group="nsx_v3")
|
cfg.CONF.set_override("nameservers", ["10.1.1.1"], group="nsx_v3")
|
||||||
|
cfg.CONF.set_override("switching_profiles", ["uuid1"], group="nsx_v3")
|
||||||
|
|
||||||
def _config_az(self,
|
def _config_az(self,
|
||||||
metadata_proxy="metadata_proxy1",
|
metadata_proxy="metadata_proxy1",
|
||||||
@ -48,7 +49,8 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase):
|
|||||||
dns_domain="aaa.com",
|
dns_domain="aaa.com",
|
||||||
nameservers=["20.1.1.1"],
|
nameservers=["20.1.1.1"],
|
||||||
default_overlay_tz='otz',
|
default_overlay_tz='otz',
|
||||||
default_vlan_tz='vtz'):
|
default_vlan_tz='vtz',
|
||||||
|
switching_profiles=["uuid2"]):
|
||||||
if metadata_proxy is not None:
|
if metadata_proxy is not None:
|
||||||
cfg.CONF.set_override("metadata_proxy", metadata_proxy,
|
cfg.CONF.set_override("metadata_proxy", metadata_proxy,
|
||||||
group=self.group_name)
|
group=self.group_name)
|
||||||
@ -71,6 +73,9 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase):
|
|||||||
if default_vlan_tz is not None:
|
if default_vlan_tz is not None:
|
||||||
cfg.CONF.set_override("default_vlan_tz", default_vlan_tz,
|
cfg.CONF.set_override("default_vlan_tz", default_vlan_tz,
|
||||||
group=self.group_name)
|
group=self.group_name)
|
||||||
|
if switching_profiles is not None:
|
||||||
|
cfg.CONF.set_override("switching_profiles", switching_profiles,
|
||||||
|
group=self.group_name)
|
||||||
|
|
||||||
def test_simple_availability_zone(self):
|
def test_simple_availability_zone(self):
|
||||||
self._config_az()
|
self._config_az()
|
||||||
@ -83,6 +88,7 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase):
|
|||||||
self.assertEqual(["20.1.1.1"], az.nameservers)
|
self.assertEqual(["20.1.1.1"], az.nameservers)
|
||||||
self.assertEqual("otz", az.default_overlay_tz)
|
self.assertEqual("otz", az.default_overlay_tz)
|
||||||
self.assertEqual("vtz", az.default_vlan_tz)
|
self.assertEqual("vtz", az.default_vlan_tz)
|
||||||
|
self.assertEqual(["uuid2"], az.switching_profiles)
|
||||||
|
|
||||||
def test_missing_group_section(self):
|
def test_missing_group_section(self):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
@ -120,3 +126,8 @@ class Nsxv3AvailabilityZonesTestCase(base.BaseTestCase):
|
|||||||
self._config_az(nameservers=None)
|
self._config_az(nameservers=None)
|
||||||
az = nsx_az.NsxV3AvailabilityZone(self.az_name)
|
az = nsx_az.NsxV3AvailabilityZone(self.az_name)
|
||||||
self.assertEqual(["10.1.1.1"], az.nameservers)
|
self.assertEqual(["10.1.1.1"], az.nameservers)
|
||||||
|
|
||||||
|
def test_availability_zone_missing_profiles(self):
|
||||||
|
self._config_az(switching_profiles=None)
|
||||||
|
az = nsx_az.NsxV3AvailabilityZone(self.az_name)
|
||||||
|
self.assertEqual(["uuid1"], az.switching_profiles)
|
||||||
|
@ -61,6 +61,7 @@ PLUGIN_NAME = 'vmware_nsx.plugin.NsxV3Plugin'
|
|||||||
NSX_TZ_NAME = 'default transport zone'
|
NSX_TZ_NAME = 'default transport zone'
|
||||||
NSX_DHCP_PROFILE_ID = 'default dhcp profile'
|
NSX_DHCP_PROFILE_ID = 'default dhcp profile'
|
||||||
NSX_METADATA_PROXY_ID = 'default metadata proxy'
|
NSX_METADATA_PROXY_ID = 'default metadata proxy'
|
||||||
|
NSX_SWITCH_PROFILE = 'dummy switch profile'
|
||||||
|
|
||||||
|
|
||||||
def _mock_create_firewall_rules(*args):
|
def _mock_create_firewall_rules(*args):
|
||||||
@ -298,6 +299,8 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
|
|||||||
HAS_PORT_FILTER = True
|
HAS_PORT_FILTER = True
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override('switching_profiles', [NSX_SWITCH_PROFILE],
|
||||||
|
'nsx_v3')
|
||||||
super(TestPortsV2, self).setUp()
|
super(TestPortsV2, self).setUp()
|
||||||
self.plugin = directory.get_plugin()
|
self.plugin = directory.get_plugin()
|
||||||
self.ctx = context.get_admin_context()
|
self.ctx = context.get_admin_context()
|
||||||
@ -537,6 +540,30 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
|
|||||||
self.assertEqual(exc.HTTPBadRequest.code,
|
self.assertEqual(exc.HTTPBadRequest.code,
|
||||||
res.status_int)
|
res.status_int)
|
||||||
|
|
||||||
|
def test_create_port_with_switching_profiles(self):
|
||||||
|
"""Tests that nsx ports get the configures switching profiles"""
|
||||||
|
self.plugin = directory.get_plugin()
|
||||||
|
with self.network() as network:
|
||||||
|
data = {'port': {
|
||||||
|
'network_id': network['network']['id'],
|
||||||
|
'tenant_id': self._tenant_id,
|
||||||
|
'name': 'p1',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'device_id': 'fake_device',
|
||||||
|
'device_owner': 'fake_owner',
|
||||||
|
'fixed_ips': [],
|
||||||
|
'mac_address': '00:00:00:00:00:01'}
|
||||||
|
}
|
||||||
|
with mock.patch.object(self.plugin.nsxlib.logical_port, 'create',
|
||||||
|
return_value={'id': 'fake'}) as nsx_create:
|
||||||
|
self.plugin.create_port(self.ctx, data)
|
||||||
|
expected_prof = self.plugin.get_default_az().\
|
||||||
|
switching_profiles_objs[0]
|
||||||
|
actual_profs = nsx_create.call_args[1]['switch_profile_ids']
|
||||||
|
# the ports switching profiles should start with the
|
||||||
|
# configured one
|
||||||
|
self.assertEqual(expected_prof, actual_profs[0])
|
||||||
|
|
||||||
def test_update_port_update_ip_address_only(self):
|
def test_update_port_update_ip_address_only(self):
|
||||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user