A set of Neutron drivers for the VMware NSX.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

3252 lines
151 KiB

# Copyright (c) 2015 OpenStack Foundation.
#
# 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 mock
import netaddr
from neutron.db import l3_db
from neutron.db import models_v2
from neutron.db import securitygroups_db as sg_db
from neutron.extensions import address_scope
from neutron.extensions import l3
from neutron.extensions import securitygroup as secgrp
from neutron.tests.unit import _test_extension_portbindings as test_bindings
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
from neutron.tests.unit.extensions import test_address_scope
from neutron.tests.unit.extensions import test_extra_dhcp_opt as test_dhcpopts
from neutron.tests.unit.extensions import test_extraroute as test_ext_route
from neutron.tests.unit.extensions import test_l3 as test_l3_plugin
from neutron.tests.unit.extensions \
import test_l3_ext_gw_mode as test_ext_gw_mode
from neutron.tests.unit.scheduler \
import test_dhcp_agent_scheduler as test_dhcpagent
from neutron.tests.unit import testlib_api
from neutron_lib.api.definitions import external_net as extnet_apidef
from neutron_lib.api.definitions import extraroute as xroute_apidef
from neutron_lib.api.definitions import l3_ext_gw_mode as l3_egm_apidef
from neutron_lib.api.definitions import port_security as psec
from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import provider_net as pnet
from neutron_lib.api.definitions import vlantransparent as vlan_apidef
from neutron_lib.callbacks import events
from neutron_lib.callbacks import exceptions as nc_exc
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants
from neutron_lib import context
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import directory
from neutron_lib.plugins import utils as plugin_utils
from oslo_config import cfg
from oslo_db import exception as db_exc
from oslo_utils import uuidutils
from webob import exc
from vmware_nsx.api_client import exception as api_exc
from vmware_nsx.common import utils
from vmware_nsx.db import db as nsx_db
from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin
from vmware_nsx.services.lbaas.nsx_v3.implementation import loadbalancer_mgr
from vmware_nsx.services.lbaas.octavia import octavia_listener
from vmware_nsx.tests import unit as vmware
from vmware_nsx.tests.unit.common_plugin import common_v3
from vmware_nsx.tests.unit.extensions import test_metadata
from vmware_nsxlib.tests.unit.v3 import mocks as nsx_v3_mocks
from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase
from vmware_nsxlib.v3 import exceptions as nsxlib_exc
from vmware_nsxlib.v3 import nsx_constants
PLUGIN_NAME = 'vmware_nsx.plugin.NsxV3Plugin'
NSX_TZ_NAME = 'default transport zone'
NSX_DHCP_PROFILE_ID = 'default dhcp profile'
NSX_METADATA_PROXY_ID = 'default metadata proxy'
NSX_SWITCH_PROFILE = 'dummy switch profile'
NSX_DHCP_RELAY_SRV = 'dhcp relay srv'
NSX_EDGE_CLUSTER_UUID = 'dummy edge cluster'
def _mock_create_firewall_rules(*args):
# NOTE(arosen): the code in the neutron plugin expects the
# neutron rule id as the display_name.
rules = args[4]
return {
'rules': [
{'display_name': rule['id'], 'id': uuidutils.generate_uuid()}
for rule in rules
]}
def _return_id_key(*args, **kwargs):
return {'id': uuidutils.generate_uuid()}
def _return_id_key_list(*args, **kwargs):
return [{'id': uuidutils.generate_uuid()}]
def _mock_add_rules_in_section(*args):
# NOTE(arosen): the code in the neutron plugin expects the
# neutron rule id as the display_name.
rules = args[0]
return {
'rules': [
{'display_name': rule['display_name'],
'id': uuidutils.generate_uuid()}
for rule in rules
]}
def _mock_nsx_backend_calls():
mock.patch("vmware_nsxlib.v3.client.NSX3Client").start()
fake_profile = {'key': 'FakeKey',
'resource_type': 'FakeResource',
'id': uuidutils.generate_uuid()}
def _return_id(*args, **kwargs):
return uuidutils.generate_uuid()
def _return_same(key, *args, **kwargs):
return key
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibSwitchingProfile."
"find_by_display_name",
return_value=[fake_profile]
).start()
mock.patch(
"vmware_nsxlib.v3.router.RouterLib.validate_tier0").start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibSwitchingProfile."
"create_port_mirror_profile",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibBridgeEndpoint.create",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.security.NsxLibNsGroup.find_by_display_name",
side_effect=_return_id_key_list).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.create",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibDhcpProfile."
"get_id_by_name_or_id",
return_value=NSX_DHCP_PROFILE_ID).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibDhcpRelayService."
"get_id_by_name_or_id",
return_value=NSX_DHCP_RELAY_SRV).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibMetadataProxy."
"get_id_by_name_or_id",
side_effect=_return_same).start()
mock.patch(
"vmware_nsxlib.v3.resources.LogicalPort.create",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter.create",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.resources.LogicalDhcpServer.create",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.resources.LogicalDhcpServer.create_binding",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter."
"get_firewall_section_id",
side_effect=_return_id_key).start()
mock.patch(
"vmware_nsxlib.v3.NsxLib.get_version",
return_value='3.1.0').start()
mock.patch(
"vmware_nsxlib.v3.load_balancer.Service.get_router_lb_service",
return_value=None).start()
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='OVERLAY').start()
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibEdgeCluster."
"get_transport_nodes", return_value=['dummy']).start()
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportNode."
"get_transport_zones",
return_value=[NSX_TZ_NAME, mock.ANY]).start()
mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection.add_rules",
side_effect=_mock_add_rules_in_section).start()
class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase,
nsxlib_testcase.NsxClientTestCase):
def setup_conf_overrides(self):
cfg.CONF.set_override('default_overlay_tz', NSX_TZ_NAME, 'nsx_v3')
cfg.CONF.set_override('native_dhcp_metadata', False, 'nsx_v3')
cfg.CONF.set_override('dhcp_profile',
NSX_DHCP_PROFILE_ID, 'nsx_v3')
cfg.CONF.set_override('metadata_proxy',
NSX_METADATA_PROXY_ID, 'nsx_v3')
cfg.CONF.set_override(
'network_scheduler_driver',
'neutron.scheduler.dhcp_agent_scheduler.AZAwareWeightScheduler')
def mock_plugin_methods(self):
# need to mock the global placeholder. This is due to the fact that
# the generic security group tests assume that there is just one
# security group.
mock_ensure_global_sg_placeholder = mock.patch.object(
nsx_plugin.NsxV3Plugin, '_ensure_global_sg_placeholder')
mock_ensure_global_sg_placeholder.start()
mock.patch(
'neutron_lib.rpc.Connection.consume_in_threads',
return_value=[]).start()
mock.patch.object(nsx_plugin.NsxV3Plugin,
'_cleanup_duplicates').start()
def setUp(self, plugin=PLUGIN_NAME,
ext_mgr=None,
service_plugins=None, **kwargs):
self._patchers = []
_mock_nsx_backend_calls()
self.setup_conf_overrides()
self.mock_get_edge_cluster = mock.patch.object(
nsx_plugin.NsxV3Plugin, '_get_edge_cluster',
return_value=NSX_EDGE_CLUSTER_UUID)
self.mock_get_edge_cluster.start()
self.mock_plugin_methods()
# ignoring the given plugin and use the nsx-v3 one
if not plugin.endswith('NsxTVDPlugin'):
plugin = PLUGIN_NAME
super(NsxV3PluginTestCaseMixin, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
self.maxDiff = None
def tearDown(self):
for patcher in self._patchers:
patcher.stop()
super(NsxV3PluginTestCaseMixin, self).tearDown()
def _create_network(self, fmt, name, admin_state_up,
arg_list=None, providernet_args=None,
set_context=False, tenant_id=None,
**kwargs):
tenant_id = tenant_id or self._tenant_id
data = {'network': {'name': name,
'admin_state_up': admin_state_up,
'tenant_id': tenant_id}}
# Fix to allow the router:external attribute and any other
# attributes containing a colon to be passed with
# a double underscore instead
kwargs = dict((k.replace('__', ':'), v) for k, v in kwargs.items())
if extnet_apidef.EXTERNAL in kwargs:
arg_list = (extnet_apidef.EXTERNAL, ) + (arg_list or ())
if providernet_args:
kwargs.update(providernet_args)
for arg in (('admin_state_up', 'tenant_id', 'shared',
'availability_zone_hints') + (arg_list or ())):
# Arg must be present
if arg in kwargs:
data['network'][arg] = kwargs[arg]
network_req = self.new_create_request('networks', data, fmt)
if set_context and tenant_id:
# create a specific auth context for this request
network_req.environ['neutron.context'] = context.Context(
'', tenant_id)
return network_req.get_response(self.api)
def _create_l3_ext_network(
self, physical_network=nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID):
name = 'l3_ext_net'
net_type = utils.NetworkTypes.L3_EXT
providernet_args = {pnet.NETWORK_TYPE: net_type,
pnet.PHYSICAL_NETWORK: physical_network}
return self.network(name=name,
router__external=True,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK))
def _save_networks(self, networks):
ctx = context.get_admin_context()
for network_id in networks:
with ctx.session.begin(subtransactions=True):
ctx.session.add(models_v2.Network(id=network_id))
def _initialize_azs(self):
self.plugin.init_availability_zones()
self.plugin._translate_configured_names_to_uuids()
def _enable_native_dhcp_md(self):
cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
cfg.CONF.set_override('dhcp_agent_notification', False)
self.plugin._init_dhcp_metadata()
def _enable_dhcp_relay(self):
# Add the relay service to the config and availability zones
cfg.CONF.set_override('dhcp_relay_service', NSX_DHCP_RELAY_SRV,
'nsx_v3')
mock_nsx_version = mock.patch.object(
self.plugin.nsxlib, 'feature_supported', return_value=True)
mock_nsx_version.start()
self._initialize_azs()
self._enable_native_dhcp_md()
class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin):
def setUp(self, plugin=PLUGIN_NAME,
ext_mgr=None,
service_plugins=None):
# add vlan transparent to the configuration
cfg.CONF.set_override('vlan_transparent', True)
super(TestNetworksV2, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
def tearDown(self):
super(TestNetworksV2, self).tearDown()
@mock.patch.object(nsx_plugin.NsxV3Plugin, 'validate_availability_zones')
def test_create_network_with_availability_zone(self, mock_validate_az):
name = 'net-with-zone'
zone = ['zone1']
mock_validate_az.return_value = None
with self.network(name=name, availability_zone_hints=zone) as net:
az_hints = net['network']['availability_zone_hints']
self.assertListEqual(az_hints, zone)
def test_network_failure_rollback(self):
self._enable_native_dhcp_md()
self.plugin = directory.get_plugin()
with mock.patch.object(self.plugin.nsxlib.logical_port, 'create',
side_effect=api_exc.NsxApiException):
self.network()
ctx = context.get_admin_context()
networks = self.plugin.get_networks(ctx)
self.assertListEqual([], networks)
def test_create_provider_flat_network(self):
providernet_args = {pnet.NETWORK_TYPE: 'flat'}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'create', side_effect=_return_id_key) as nsx_create, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'delete') as nsx_delete, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'),\
self.network(name='flat_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE, )) as net:
self.assertEqual('flat', net['network'].get(pnet.NETWORK_TYPE))
# make sure the network is created at the backend
nsx_create.assert_called_once()
# Delete the network and make sure it is deleted from the backend
req = self.new_delete_request('networks', net['network']['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
nsx_delete.assert_called_once()
def test_create_provider_flat_network_with_physical_net(self):
physical_network = nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID
providernet_args = {pnet.NETWORK_TYPE: 'flat',
pnet.PHYSICAL_NETWORK: physical_network}
with mock.patch(
'vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'),\
self.network(name='flat_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK)) as net:
self.assertEqual('flat', net['network'].get(pnet.NETWORK_TYPE))
def test_create_provider_flat_network_with_vlan(self):
providernet_args = {pnet.NETWORK_TYPE: 'flat',
pnet.SEGMENTATION_ID: 11}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'):
result = self._create_network(fmt='json', name='bad_flat_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.SEGMENTATION_ID))
data = self.deserialize('json', result)
# should fail
self.assertEqual('InvalidInput', data['NeutronError']['type'])
def test_create_provider_geneve_network(self):
providernet_args = {pnet.NETWORK_TYPE: 'geneve'}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'create', side_effect=_return_id_key) as nsx_create, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'delete') as nsx_delete, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='OVERLAY'),\
self.network(name='geneve_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE, )) as net:
self.assertEqual('geneve', net['network'].get(pnet.NETWORK_TYPE))
# make sure the network is created at the backend
nsx_create.assert_called_once()
# Delete the network and make sure it is deleted from the backend
req = self.new_delete_request('networks', net['network']['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
nsx_delete.assert_called_once()
def test_create_provider_geneve_network_with_physical_net(self):
physical_network = nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID
providernet_args = {pnet.NETWORK_TYPE: 'geneve',
pnet.PHYSICAL_NETWORK: physical_network}
with mock.patch(
'vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='OVERLAY'),\
self.network(name='geneve_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE, )) as net:
self.assertEqual('geneve', net['network'].get(pnet.NETWORK_TYPE))
def test_create_provider_geneve_network_with_vlan(self):
providernet_args = {pnet.NETWORK_TYPE: 'geneve',
pnet.SEGMENTATION_ID: 11}
with mock.patch(
'vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='OVERLAY'):
result = self._create_network(fmt='json', name='bad_geneve_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.SEGMENTATION_ID))
data = self.deserialize('json', result)
# should fail
self.assertEqual('InvalidInput', data['NeutronError']['type'])
def test_create_provider_vlan_network(self):
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
pnet.SEGMENTATION_ID: 11}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'create', side_effect=_return_id_key) as nsx_create, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'delete') as nsx_delete, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'),\
self.network(name='vlan_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.SEGMENTATION_ID)) as net:
self.assertEqual('vlan', net['network'].get(pnet.NETWORK_TYPE))
# make sure the network is created at the backend
nsx_create.assert_called_once()
# Delete the network and make sure it is deleted from the backend
req = self.new_delete_request('networks', net['network']['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
nsx_delete.assert_called_once()
def test_create_provider_nsx_network(self):
physical_network = 'Fake logical switch'
providernet_args = {pnet.NETWORK_TYPE: 'nsx-net',
pnet.PHYSICAL_NETWORK: physical_network}
with mock.patch(
'vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.create',
side_effect=nsxlib_exc.ResourceNotFound) as nsx_create, \
mock.patch('vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.'
'delete') as nsx_delete, \
self.network(name='nsx_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK)) as net:
self.assertEqual('nsx-net', net['network'].get(pnet.NETWORK_TYPE))
self.assertEqual(physical_network,
net['network'].get(pnet.PHYSICAL_NETWORK))
# make sure the network is NOT created at the backend
nsx_create.assert_not_called()
# Delete the network. It should NOT deleted from the backend
req = self.new_delete_request('networks', net['network']['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPNoContent.code, res.status_int)
nsx_delete.assert_not_called()
def test_create_provider_bad_nsx_network(self):
physical_network = 'Bad logical switch'
providernet_args = {pnet.NETWORK_TYPE: 'nsx-net',
pnet.PHYSICAL_NETWORK: physical_network}
with mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.get",
side_effect=nsxlib_exc.ResourceNotFound):
result = self._create_network(fmt='json', name='bad_nsx_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK))
data = self.deserialize('json', result)
# should fail
self.assertEqual('InvalidInput', data['NeutronError']['type'])
def test_create_ens_network_with_no_port_sec(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
providernet_args = {psec.PORTSECURITY: False}
with mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.get",
return_value={'transport_zone_id': 'xxx'}):
result = self._create_network(fmt='json', name='ens_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(psec.PORTSECURITY,))
res = self.deserialize('json', result)
# should succeed, and net should have port security disabled
self.assertFalse(res['network']['port_security_enabled'])
def test_create_ens_network_with_port_sec_supported(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
providernet_args = {psec.PORTSECURITY: True}
with mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch."
"get", return_value={'transport_zone_id': 'xxx'}):
result = self._create_network(fmt='json', name='ens_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(psec.PORTSECURITY,))
res = self.deserialize('json', result)
# should succeed
self.assertTrue(res['network'][psec.PORTSECURITY])
def test_create_ens_network_disable_default_port_security(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
cfg.CONF.set_override('disable_port_security_for_ens', True, 'nsx_v3')
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode', return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibLogicalSwitch.get',
return_value={'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type', return_value='VLAN')
data = {'network': {
'name': 'portsec_net',
'admin_state_up': True,
'shared': False,
'tenant_id': 'some_tenant',
'provider:network_type': 'flat',
'provider:physical_network': 'xxx',
'port_security_enabled': True}}
with mock_ens, mock_tz, mock_tt:
self.plugin.create_network(context.get_admin_context(), data)
def test_create_ens_network_with_qos(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode', return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibLogicalSwitch.get',
return_value={'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type', return_value='VLAN')
mock_ver = mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.4.0')
policy_id = uuidutils.generate_uuid()
data = {'network': {
'name': 'qos_net',
'tenant_id': 'some_tenant',
'provider:network_type': 'flat',
'provider:physical_network': 'xxx',
'qos_policy_id': policy_id,
'port_security_enabled': False}}
with mock_ens, mock_tz, mock_tt, mock_ver, mock.patch.object(
self.plugin, '_validate_qos_policy_id'):
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_network,
context.get_admin_context(), data)
def test_update_ens_network_with_qos(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode', return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibLogicalSwitch.get',
return_value={'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type', return_value='VLAN')
mock_ver = mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.4.0')
data = {'network': {
'name': 'qos_net',
'tenant_id': 'some_tenant',
'provider:network_type': 'flat',
'provider:physical_network': 'xxx',
'admin_state_up': True,
'shared': False,
'port_security_enabled': False}}
with mock_ens, mock_tz, mock_tt, mock_ver,\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
network = self.plugin.create_network(context.get_admin_context(),
data)
policy_id = uuidutils.generate_uuid()
data = {'network': {
'id': network['id'],
'admin_state_up': True,
'shared': False,
'port_security_enabled': False,
'tenant_id': 'some_tenant',
'qos_policy_id': policy_id}}
self.assertRaises(n_exc.InvalidInput,
self.plugin.update_network,
context.get_admin_context(),
network['id'], data)
def test_update_ens_network_psec_supported(self):
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
providernet_args = {psec.PORTSECURITY: False}
with mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.get",
return_value={'transport_zone_id': 'xxx'}):
result = self._create_network(fmt='json', name='ens_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(psec.PORTSECURITY,))
net = self.deserialize('json', result)
net_id = net['network']['id']
args = {'network': {psec.PORTSECURITY: True}}
req = self.new_update_request('networks', args,
net_id, fmt='json')
res = self.deserialize('json', req.get_response(self.api))
# should succeed
self.assertTrue(res['network'][psec.PORTSECURITY])
def test_create_transparent_vlan_network(self):
providernet_args = {vlan_apidef.VLANTRANSPARENT: True}
with mock.patch(
'vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='OVERLAY'),\
self.network(name='vt_net',
providernet_args=providernet_args,
arg_list=(vlan_apidef.VLANTRANSPARENT, )) as net:
self.assertTrue(net['network'].get(vlan_apidef.VLANTRANSPARENT))
def test_create_provider_vlan_network_with_transparent(self):
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
vlan_apidef.VLANTRANSPARENT: True}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'):
result = self._create_network(fmt='json', name='badvlan_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(
pnet.NETWORK_TYPE,
pnet.SEGMENTATION_ID,
vlan_apidef.VLANTRANSPARENT))
data = self.deserialize('json', result)
self.assertEqual('vlan', data['network'].get(pnet.NETWORK_TYPE))
def _test_generate_tag(self, vlan_id):
net_type = 'vlan'
name = 'phys_net'
plugin = directory.get_plugin()
plugin._network_vlans = plugin_utils.parse_network_vlan_ranges(
cfg.CONF.nsx_v3.network_vlan_ranges)
expected = [('subnets', []), ('name', name),
('admin_state_up', True),
('status', 'ACTIVE'),
('shared', False),
(pnet.NETWORK_TYPE, net_type),
(pnet.PHYSICAL_NETWORK,
'fb69d878-958e-4f32-84e4-50286f26226b'),
(pnet.SEGMENTATION_ID, vlan_id)]
providernet_args = {pnet.NETWORK_TYPE: net_type,
pnet.PHYSICAL_NETWORK:
'fb69d878-958e-4f32-84e4-50286f26226b'}
gtt_path = "vmware_nsxlib.v3.core_resources." \
"NsxLibTransportZone.get_transport_type"
with mock.patch(gtt_path, return_value='VLAN'):
with self.network(name=name, providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK)) as net:
for k, v in expected:
self.assertEqual(net['network'][k], v)
def test_create_phys_vlan_generate(self):
cfg.CONF.set_override('network_vlan_ranges',
'fb69d878-958e-4f32-84e4-50286f26226b',
'nsx_v3')
self._test_generate_tag(1)
def test_create_phys_vlan_generate_range(self):
cfg.CONF.set_override('network_vlan_ranges',
'fb69d878-958e-4f32-84e4-'
'50286f26226b:100:110',
'nsx_v3')
self._test_generate_tag(100)
def test_create_phys_vlan_network_outofrange_returns_503(self):
cfg.CONF.set_override('network_vlan_ranges',
'fb69d878-958e-4f32-84e4-'
'50286f26226b:9:10',
'nsx_v3')
self._test_generate_tag(9)
self._test_generate_tag(10)
with testlib_api.ExpectedException(exc.HTTPClientError) as ctx_manager:
self._test_generate_tag(11)
self.assertEqual(ctx_manager.exception.code, 503)
def test_update_external_flag_on_net(self):
with self.network() as net:
# should fail to update the network to external
args = {'network': {'router:external': 'True'}}
req = self.new_update_request('networks', args,
net['network']['id'], fmt='json')
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual('InvalidInput',
res['NeutronError']['type'])
def test_network_update_external(self):
# This plugin does not support updating the external flag of a network
self.skipTest("UnSupported")
def test_network_update_external_failure(self):
data = {'network': {'name': 'net1',
'router:external': 'True',
'tenant_id': 'tenant_one',
'provider:physical_network': 'stam'}}
network_req = self.new_create_request('networks', data)
network = self.deserialize(self.fmt,
network_req.get_response(self.api))
ext_net_id = network['network']['id']
# should fail to update the network to non-external
args = {'network': {'router:external': 'False'}}
req = self.new_update_request('networks', args,
ext_net_id, fmt='json')
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual('InvalidInput',
res['NeutronError']['type'])
def test_update_network_rollback(self):
with self.network() as net:
# Fail the backend update
with mock.patch("vmware_nsxlib.v3.core_resources."
"NsxLibLogicalSwitch.update",
side_effect=nsxlib_exc.InvalidInput):
args = {'network': {'description': 'test rollback'}}
req = self.new_update_request('networks', args,
net['network']['id'], fmt='json')
res = self.deserialize('json', req.get_response(self.api))
# should fail with the nsxlib error (meaning that the rollback
# did not fail)
self.assertEqual('InvalidInput',
res['NeutronError']['type'])
def test_update_network_port_sec(self):
data = {'network': {
'name': 'psec_net',
'tenant_id': 'some_tenant',
'admin_state_up': True,
'shared': False,
'port_security_enabled': True}}
network = self.plugin.create_network(context.get_admin_context(),
data)
self.assertEqual(True, network['port_security_enabled'])
data = {'network': {
'id': network['id'],
'admin_state_up': True,
'shared': False,
'port_security_enabled': False,
'tenant_id': 'some_tenant'}}
res = self.plugin.update_network(context.get_admin_context(),
network['id'], data)
self.assertEqual(False, res['port_security_enabled'])
class TestSubnetsV2(common_v3.NsxV3TestSubnets, NsxV3PluginTestCaseMixin):
def setUp(self, plugin=PLUGIN_NAME, ext_mgr=None):
super(TestSubnetsV2, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
def test_create_subnet_with_shared_address_space(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '100.64.0.0/16',
'name': 'sub1',
'enable_dhcp': False,
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'host_routes': None,
'ip_version': 4}}
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def _create_external_network(self):
data = {'network': {'name': 'net1',
'router:external': 'True',
'tenant_id': 'tenant_one',
'provider:physical_network': 'stam'}}
network_req = self.new_create_request('networks', data)
network = self.deserialize(self.fmt,
network_req.get_response(self.api))
return network
def test_create_subnet_with_conflicting_t0_address(self):
network = self._create_external_network()
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'enable_dhcp': False,
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'host_routes': None,
'ip_version': 4}}
ports = [{'subnets': [{'ip_addresses': [u'172.20.1.60'],
'prefix_length': 24}],
'resource_type': 'LogicalRouterUpLinkPort'}]
with mock.patch.object(self.plugin.nsxlib.logical_router_port,
'get_by_router_id',
return_value=ports):
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_subnet_native_dhcp_subnet_enabled(self):
self._enable_native_dhcp_md()
with self.network() as network:
with mock.patch.object(self.plugin,
'_enable_native_dhcp') as enable_dhcp,\
self.subnet(network=network, enable_dhcp=True):
# Native dhcp should be set for this subnet
self.assertTrue(enable_dhcp.called)
def test_subnet_native_dhcp_subnet_disabled(self):
self._enable_native_dhcp_md()
with self.network() as network:
with mock.patch.object(self.plugin,
'_enable_native_dhcp') as enable_dhcp,\
self.subnet(network=network, enable_dhcp=False):
# Native dhcp should not be set for this subnet
self.assertFalse(enable_dhcp.called)
def test_subnet_native_dhcp_with_relay(self):
"""Verify that the relay service is added to the router interface"""
self._enable_dhcp_relay()
with self.network() as network:
with mock.patch.object(self.plugin,
'_enable_native_dhcp') as enable_dhcp,\
self.subnet(network=network, enable_dhcp=True):
# Native dhcp should not be set for this subnet
self.assertFalse(enable_dhcp.called)
def test_subnet_native_dhcp_flat_subnet_disabled(self):
self._enable_native_dhcp_md()
providernet_args = {pnet.NETWORK_TYPE: 'flat'}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'):
with self.network(name='flat_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE, )) as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'enable_dhcp': False,
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'host_routes': None,
'ip_version': 4}}
self.plugin.create_subnet(
context.get_admin_context(), data)
def test_subnet_native_dhcp_flat_subnet_enabled(self):
self._enable_native_dhcp_md()
providernet_args = {pnet.NETWORK_TYPE: 'flat'}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'):
with self.network(name='flat_net',
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE, )) as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'enable_dhcp': True,
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'host_routes': None,
'ip_version': 4}}
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_fail_create_static_routes_per_subnet_over_limit(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '10.0.0.0/16',
'name': 'sub1',
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'enable_dhcp': False,
'ip_version': 4}}
count = 1
host_routes = []
while count < nsx_constants.MAX_STATIC_ROUTES:
host_routes.append("'host_routes': [{'destination': "
"'135.207.0.0/%s', 'nexthop': "
"'1.2.3.%s'}]" % (count, count))
count += 1
data['subnet']['host_routes'] = host_routes
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_create_subnet_disable_dhcp_with_host_route_fails(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'enable_dhcp': False,
'host_routes': [{
'destination': '135.207.0.0/16',
'nexthop': '1.2.3.4'}],
'ip_version': 4}}
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_update_subnet_disable_dhcp_with_host_route_fails(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'enable_dhcp': True,
'host_routes': [{
'destination': '135.207.0.0/16',
'nexthop': '1.2.3.4'}],
'ip_version': 4}}
subnet = self.plugin.create_subnet(
context.get_admin_context(), data)
data['subnet']['enable_dhcp'] = False
self.assertRaises(n_exc.InvalidInput,
self.plugin.update_subnet,
context.get_admin_context(), subnet['id'], data)
def test_create_subnet_ipv6_gw_is_nw_start_addr(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_gw_is_nw_start_addr_canonicalize(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_gw_is_nw_end_addr(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_first_ip_owned_by_router(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_first_ip_owned_by_non_router(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_with_v6_pd_allocation_pool(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_with_v6_allocation_pool(self):
self.skipTest('No DHCP v6 Support yet')
def test_update_subnet_ipv6_ra_mode_fails(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_slaac_with_ip_already_allocated(self):
self.skipTest('No DHCP v6 Support yet')
def test_create_subnet_ipv6_slaac_with_db_reference_error(self):
self.skipTest('No DHCP v6 Support yet')
class TestPortsV2(common_v3.NsxV3SubnetMixin,
common_v3.NsxV3TestPorts, NsxV3PluginTestCaseMixin,
test_bindings.PortBindingsTestCase,
test_bindings.PortBindingsHostTestCaseMixin,
test_bindings.PortBindingsVnicTestCaseMixin):
VIF_TYPE = portbindings.VIF_TYPE_OVS
HAS_PORT_FILTER = True
def setUp(self):
cfg.CONF.set_override('switching_profiles', [NSX_SWITCH_PROFILE],
'nsx_v3')
# add vlan transparent to the configuration
cfg.CONF.set_override('vlan_transparent', True)
super(TestPortsV2, self).setUp()
self.plugin = directory.get_plugin()
self.ctx = context.get_admin_context()
def test_update_port_delete_ip(self):
# This test case overrides the default because the nsx plugin
# implements port_security/security groups and it is not allowed
# to remove an ip address from a port unless the security group
# is first removed.
with self.subnet() as subnet:
with self.port(subnet=subnet) as port:
data = {'port': {'admin_state_up': False,
'fixed_ips': [],
secgrp.SECURITYGROUPS: []}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual(res['port']['admin_state_up'],
data['port']['admin_state_up'])
self.assertEqual(res['port']['fixed_ips'],
data['port']['fixed_ips'])
def test_delete_dhcp_port(self):
self._enable_native_dhcp_md()
with self.subnet():
pl = directory.get_plugin()
ctx = context.Context(user_id=None, tenant_id=self._tenant_id,
is_admin=False)
ports = pl.get_ports(
ctx, filters={'device_owner': [constants.DEVICE_OWNER_DHCP]})
req = self.new_delete_request('ports', ports[0]['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
def test_fail_create_port_with_ext_net(self):
expected_error = 'InvalidInput'
with self._create_l3_ext_network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'):
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
res = self._create_port(self.fmt,
network['network']['id'],
exc.HTTPBadRequest.code,
device_owner=device_owner)
data = self.deserialize(self.fmt, res)
self.assertEqual(expected_error, data['NeutronError']['type'])
def test_fail_update_port_with_ext_net(self):
with self._create_l3_ext_network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24') as subnet:
with self.port(subnet=subnet) as port:
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
data = {'port': {'device_owner': device_owner}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = req.get_response(self.api)
self.assertEqual(exc.HTTPBadRequest.code,
res.status_int)
def test_fail_update_lb_port_with_allowed_address_pairs(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'pair_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': constants.DEVICE_OWNER_LOADBALANCERV2,
'fixed_ips': []}
}
port = self.plugin.create_port(self.ctx, data)
data['port']['allowed_address_pairs'] = '10.0.0.1'
self.assertRaises(
n_exc.InvalidInput,
self.plugin.update_port, self.ctx, port['id'], data)
def test_fail_create_allowed_address_pairs_over_limit(self):
with self.network() as network, self.subnet(
network=network, enable_dhcp=True) as s1:
data = {
'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'pair_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [{'subnet_id': s1['subnet']['id']}]
}
}
count = 1
address_pairs = []
while count < 129:
address_pairs.append({'ip_address': '10.0.0.%s' % count})
count += 1
data['port']['allowed_address_pairs'] = address_pairs
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_port, self.ctx, data)
def test_fail_update_lb_port_with_fixed_ip(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'pair_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': constants.DEVICE_OWNER_LOADBALANCERV2,
'fixed_ips': []}
}
port = self.plugin.create_port(self.ctx, data)
data['port']['fixed_ips'] = [{'ip_address': '10.0.0.1'}]
self.assertRaises(
n_exc.InvalidInput,
self.plugin.update_port, self.ctx, port['id'], data)
def test_create_port_with_qos(self):
with self.network() as network:
policy_id = uuidutils.generate_uuid()
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'qos_policy_id': policy_id,
'name': 'qos_port',
'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, '_get_qos_profile_id'),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
port = self.plugin.create_port(self.ctx, data)
self.assertEqual(policy_id, port['qos_policy_id'])
# Get port should also return the qos policy id
with mock.patch('vmware_nsx.services.qos.common.utils.'
'get_port_policy_id',
return_value=policy_id):
port = self.plugin.get_port(self.ctx, port['id'])
self.assertEqual(policy_id, port['qos_policy_id'])
def test_update_port_with_qos(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'mac_address': '00:00:00:00:00:01'}
}
port = self.plugin.create_port(self.ctx, data)
policy_id = uuidutils.generate_uuid()
data['port']['qos_policy_id'] = policy_id
with mock.patch.object(self.plugin, '_get_qos_profile_id'),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
res = self.plugin.update_port(self.ctx, port['id'], data)
self.assertEqual(policy_id, res['qos_policy_id'])
# Get port should also return the qos policy id
with mock.patch('vmware_nsx.services.qos.common.utils.'
'get_port_policy_id',
return_value=policy_id):
res = self.plugin.get_port(self.ctx, port['id'])
self.assertEqual(policy_id, res['qos_policy_id'])
# now remove the qos from the port
data['port']['qos_policy_id'] = None
res = self.plugin.update_port(self.ctx, port['id'], data)
self.assertIsNone(res['qos_policy_id'])
def test_create_ext_port_with_qos_fail(self):
with self._create_l3_ext_network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
policy_id = uuidutils.generate_uuid()
data = {'port': {'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'qos_policy_id': policy_id}}
# Cannot add qos policy to a router port
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_port, self.ctx, data)
def _test_create_illegal_port_with_qos_fail(self, device_owner):
with self.network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
policy_id = uuidutils.generate_uuid()
data = {'port': {'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'device_owner': device_owner,
'qos_policy_id': policy_id}}
# Cannot add qos policy to this type of port
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_port, self.ctx, data)
def test_create_port_ens_with_qos_fail(self):
with self.network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'):
policy_id = uuidutils.generate_uuid()
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode',
return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources'
'.NsxLibLogicalSwitch.get',
return_value={
'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type',
return_value='VLAN')
mock_ver = mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.4.0')
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01',
'qos_policy_id': policy_id}
}
# Cannot add qos policy to this type of port
with mock_ens, mock_tz, mock_tt, mock_ver,\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_port, self.ctx, data)
def test_create_port_ens_with_sg(self):
cfg.CONF.set_override('disable_port_security_for_ens', True, 'nsx_v3')
with self.network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'):
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode',
return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources'
'.NsxLibLogicalSwitch.get',
return_value={
'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type',
return_value='VLAN')
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'sg_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'mac_address': '00:00:00:00:00:01',
'port_security_enabled': True}
}
with mock_ens, mock_tz, mock_tt:
self.plugin.create_port(self.ctx, data)
def test_update_port_ens_with_qos_fail(self):
with self.network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'):
policy_id = uuidutils.generate_uuid()
mock_ens = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_host_switch_mode',
return_value='ENS')
mock_tz = mock.patch('vmware_nsxlib.v3'
'.core_resources'
'.NsxLibLogicalSwitch.get',
return_value={
'transport_zone_id': 'xxx'})
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type',
return_value='VLAN')
mock_ver = mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value='2.4.0')
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01'}
}
with mock_ens, mock_tz, mock_tt, mock_ver,\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
port = self.plugin.create_port(self.ctx, data)
data['port'] = {'qos_policy_id': policy_id}
self.assertRaises(n_exc.InvalidInput,
self.plugin.update_port,
self.ctx, port['id'], data)
def test_create_port_with_mac_learning_true(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01',
'mac_learning_enabled': True}
}
port = self.plugin.create_port(self.ctx, data)
self.assertTrue(port['mac_learning_enabled'])
def test_create_port_with_mac_learning_false(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01',
'mac_learning_enabled': False}
}
port = self.plugin.create_port(self.ctx, data)
self.assertFalse(port['mac_learning_enabled'])
def test_update_port_with_mac_learning_true(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01'}
}
port = self.plugin.create_port(self.ctx, data)
data['port']['mac_learning_enabled'] = True
update_res = self.plugin.update_port(self.ctx, port['id'], data)
self.assertTrue(update_res['mac_learning_enabled'])
def test_update_port_with_mac_learning_false(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01'}
}
port = self.plugin.create_port(self.ctx, data)
data['port']['mac_learning_enabled'] = False
update_res = self.plugin.update_port(self.ctx, port['id'], data)
self.assertFalse(update_res['mac_learning_enabled'])
def test_update_port_with_mac_learning_failes(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': constants.DEVICE_OWNER_FLOATINGIP,
'fixed_ips': [],
'port_security_enabled': False,
'mac_address': '00:00:00:00:00:01'}
}
port = self.plugin.create_port(self.ctx, data)
data['port']['mac_learning_enabled'] = True
self.assertRaises(
n_exc.InvalidInput,
self.plugin.update_port, self.ctx, port['id'], data)
def test_create_router_port_with_qos_fail(self):
self._test_create_illegal_port_with_qos_fail(
'network:router_interface')
def test_create_dhcp_port_with_qos_fail(self):
self._test_create_illegal_port_with_qos_fail('network:dhcp')
def _test_update_illegal_port_with_qos_fail(self, device_owner):
with self.network() as network:
with self.subnet(network=network, cidr='10.0.0.0/24'),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
policy_id = uuidutils.generate_uuid()
data = {'port': {'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'fixed_ips': [],
'mac_address': '00:00:00:00:00:01',
'device_id': 'dummy',
'device_owner': ''}}
port = self.plugin.create_port(self.ctx, data)
policy_id = uuidutils.generate_uuid()
data['port'] = {'qos_policy_id': policy_id,
'device_owner': device_owner}
# Cannot add qos policy to a router interface port
self.assertRaises(n_exc.InvalidInput,
self.plugin.update_port, self.ctx, port['id'], data)
def test_update_router_port_with_qos_fail(self):
self._test_update_illegal_port_with_qos_fail(
'network:router_interface')
def test_update_dhcp_port_with_qos_fail(self):
self._test_update_illegal_port_with_qos_fail('network:dhcp')
def test_create_port_with_qos_on_net(self):
with self.network() as network:
policy_id = uuidutils.generate_uuid()
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': device_owner,
'fixed_ips': [],
'mac_address': '00:00:00:00:00:01'}
}
with mock.patch.object(self.plugin,
'_get_qos_profile_id') as get_profile,\
mock.patch('vmware_nsx.services.qos.common.utils.'
'get_network_policy_id', return_value=policy_id),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
self.plugin.create_port(self.ctx, data)
get_profile.assert_called_once_with(self.ctx, policy_id)
def test_update_port_with_qos_on_net(self):
with self.network() as network:
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'qos_port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': 'fake_owner',
'fixed_ips': [],
'mac_address': '00:00:00:00:00:01'}
}
port = self.plugin.create_port(self.ctx, data)
policy_id = uuidutils.generate_uuid()
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
data['port']['device_owner'] = device_owner
with mock.patch.object(self.plugin,
'_get_qos_profile_id') as get_profile,\
mock.patch('vmware_nsx.services.qos.common.utils.'
'get_network_policy_id', return_value=policy_id),\
mock.patch.object(self.plugin, '_validate_qos_policy_id'):
self.plugin.update_port(self.ctx, port['id'], data)
get_profile.assert_called_once_with(self.ctx, policy_id)
def _get_ports_with_fields(self, tenid, fields, expected_count):
pl = directory.get_plugin()
ctx = context.Context(user_id=None, tenant_id=tenid,
is_admin=False)
ports = pl.get_ports(ctx, filters={'tenant_id': [tenid]},
fields=fields)
self.assertEqual(expected_count, len(ports))
def test_get_ports_with_fields(self):
with self.port(), self.port(), self.port(), self.port() as p:
tenid = p['port']['tenant_id']
# get all fields:
self._get_ports_with_fields(tenid, None, 4)
# get specific fields:
self._get_ports_with_fields(tenid, 'mac_address', 4)
self._get_ports_with_fields(tenid, 'network_id', 4)
def test_list_ports_filtered_by_security_groups(self):
ctx = context.get_admin_context()
with self.port() as port1, self.port() as port2:
query_params = "security_groups=%s" % (
port1['port']['security_groups'][0])
ports_data = self._list('ports', query_params=query_params)
self.assertEqual(set([port1['port']['id'], port2['port']['id']]),
set([port['id'] for port in ports_data['ports']]))
query_params = "security_groups=%s&id=%s" % (
port1['port']['security_groups'][0],
port1['port']['id'])
ports_data = self._list('ports', query_params=query_params)
self.assertEqual(port1['port']['id'], ports_data['ports'][0]['id'])
self.assertEqual(1, len(ports_data['ports']))
temp_sg = {'security_group': {'tenant_id': 'some_tenant',
'name': '', 'description': 's'}}
sg_dbMixin = sg_db.SecurityGroupDbMixin()
sg = sg_dbMixin.create_security_group(ctx, temp_sg)
sg_dbMixin._delete_port_security_group_bindings(
ctx, port2['port']['id'])
sg_dbMixin._create_port_security_group_binding(
ctx, port2['port']['id'], sg['id'])
port2['port']['security_groups'][0] = sg['id']
query_params = "security_groups=%s" % (
port1['port']['security_groups'][0])
ports_data = self._list('ports', query_params=query_params)
self.assertEqual(port1['port']['id'], ports_data['ports'][0]['id'])
self.assertEqual(1, len(ports_data['ports']))
query_params = "security_groups=%s" % (
(port2['port']['security_groups'][0]))
ports_data = self._list('ports', query_params=query_params)
self.assertEqual(port2['port']['id'], ports_data['ports'][0]['id'])
def test_port_failure_rollback_dhcp_exception(self):
self._enable_native_dhcp_md()
self.plugin = directory.get_plugin()
with mock.patch.object(self.plugin, '_add_port_mp_dhcp_binding',
side_effect=nsxlib_exc.ManagerError):
self.port()
ctx = context.get_admin_context()
networks = self.plugin.get_ports(ctx)
self.assertListEqual([], networks)
def test_port_DB_failure_rollback_dhcp_exception(self):
self._enable_native_dhcp_md()
self.plugin = directory.get_plugin()
with mock.patch('vmware_nsx.db.db.add_neutron_nsx_dhcp_binding',
side_effect=db_exc.DBError),\
mock.patch.object(self.plugin, '_enable_native_dhcp'),\
mock.patch('vmware_nsx.db.db.get_nsx_service_binding'),\
self.network() as network,\
self.subnet(network, cidr='10.0.1.0/24') as subnet:
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': [{'subnet_id':
subnet['subnet']['id'],
'ip_address': '10.0.1.2'}],
'mac_address': '00:00:00:00:00:01'}
}
# making sure the port creation succeeded anyway
created_port = self.plugin.create_port(self.ctx, data)
self.assertEqual('fake_device', created_port['device_id'])
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_create_ens_port_with_no_port_sec(self):
with self.subnet() as subnet,\
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.get",
return_value={'transport_zone_id': 'xxx'}):
args = {'port': {'network_id': subnet['subnet']['network_id'],
'tenant_id': subnet['subnet']['tenant_id'],
'fixed_ips': [{'subnet_id':
subnet['subnet']['id']}],
psec.PORTSECURITY: False}}
port_req = self.new_create_request('ports', args)
port = self.deserialize(self.fmt, port_req.get_response(self.api))
self.assertFalse(port['port']['port_security_enabled'])
def test_create_ens_port_with_port_sec_supported(self):
with self.subnet() as subnet,\
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch(
"vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch.get",
return_value={'transport_zone_id': 'xxx'}):
args = {'port': {'network_id': subnet['subnet']['network_id'],
'tenant_id': subnet['subnet']['tenant_id'],
'fixed_ips': [{'subnet_id':
subnet['subnet']['id']}],
psec.PORTSECURITY: True}}
port_req = self.new_create_request('ports', args)
res = self.deserialize('json', port_req.get_response(self.api))
# should succeed
self.assertTrue(res['port'][psec.PORTSECURITY])
def test_update_ens_port_psec_supported(self):
with self.subnet() as subnet,\
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibTransportZone."
"get_host_switch_mode", return_value="ENS"),\
mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalSwitch."
"get", return_value={'transport_zone_id': 'xxx'}):
args = {'port': {'network_id': subnet['subnet']['network_id'],
'tenant_id': subnet['subnet']['tenant_id'],
'fixed_ips': [{'subnet_id':
subnet['subnet']['id']}],
psec.PORTSECURITY: False}}
port_req = self.new_create_request('ports', args)
port = self.deserialize(self.fmt, port_req.get_response(self.api))
port_id = port['port']['id']
args = {'port': {psec.PORTSECURITY: True}}
req = self.new_update_request('ports', args, port_id)
res = self.deserialize('json', req.get_response(self.api))
# should succeed
self.assertTrue(res['port'][psec.PORTSECURITY])
def test_update_dhcp_port_device_owner(self):
self._enable_native_dhcp_md()
with self.subnet():
pl = directory.get_plugin()
ctx = context.Context(user_id=None, tenant_id=self._tenant_id,
is_admin=False)
ports = pl.get_ports(
ctx, filters={'device_owner': [constants.DEVICE_OWNER_DHCP]})
port_id = ports[0]['id']
args = {'port': {'admin_state_up': False,
'fixed_ips': [],
'device_owner': 'abcd'}}
req = self.new_update_request('ports', args, port_id)
res = self.deserialize('json', req.get_response(self.api))
# should fail
self.assertEqual('InvalidInput',
res['NeutronError']['type'])
def test_create_compute_port_with_relay_no_router(self):
"""Compute port creation should fail
if a network with dhcp relay is not connected to a router
"""
self._enable_dhcp_relay()
with self.network() as network, \
self.subnet(network=network, enable_dhcp=True) as s1:
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': device_owner,
'fixed_ips': [{'subnet_id': s1['subnet']['id']}],
'mac_address': '00:00:00:00:00:01'}
}
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_port,
self.ctx, data)
def test_create_compute_port_with_relay_and_router(self):
self._enable_dhcp_relay()
with self.network() as network, \
self.subnet(network=network, enable_dhcp=True) as s1,\
mock.patch.object(self.plugin, '_get_router',
return_value={'name': 'dummy'}):
# first create a router interface to simulate a router
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'port',
'admin_state_up': True,
'device_id': 'dummy',
'device_owner': l3_db.DEVICE_OWNER_ROUTER_INTF,
'fixed_ips': [{'subnet_id': s1['subnet']['id']}],
'mac_address': '00:00:00:00:00:02'}
}
port1 = self.plugin.create_port(self.ctx, data)
self.assertIn('id', port1)
# Now create a compute port
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'X'
data = {'port': {
'network_id': network['network']['id'],
'tenant_id': self._tenant_id,
'name': 'port',
'admin_state_up': True,
'device_id': 'fake_device',
'device_owner': device_owner,
'fixed_ips': [{'subnet_id': s1['subnet']['id']}],
'mac_address': '00:00:00:00:00:01'}
}
port2 = self.plugin.create_port(self.ctx, data)
self.assertIn('id', port2)
def _test_create_direct_network(self, vlan_id=0):
net_type = vlan_id and 'vlan' or 'flat'
name = 'direct_net'
providernet_args = {pnet.NETWORK_TYPE: net_type,
pnet.PHYSICAL_NETWORK: 'tzuuid'}
if vlan_id:
providernet_args[pnet.SEGMENTATION_ID] = vlan_id
mock_tt = mock.patch('vmware_nsxlib.v3'
'.core_resources.NsxLibTransportZone'
'.get_transport_type',
return_value='VLAN')
mock_tt.start()
return self.network(name=name,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK,
pnet.SEGMENTATION_ID))
def _test_create_port_vnic_direct(self, vlan_id):
with self._test_create_direct_network(vlan_id=vlan_id) as network:
# Check that port security conflicts
kwargs = {portbindings.VNIC_TYPE: portbindings.VNIC_DIRECT,
psec.PORTSECURITY: True}
net_id = network['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,
psec.PORTSECURITY),
**kwargs)
self.assertEqual(res.status_int, exc.HTTPBadRequest.code)
# Check that security group conflicts
kwargs = {portbindings.VNIC_TYPE: portbindings.VNIC_DIRECT,
'security_groups': [
'4cd70774-cc67-4a87-9b39-7d1db38eb087'],
psec.PORTSECURITY: False}
net_id = network['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,
psec.PORTSECURITY),
**kwargs)
self.assertEqual(res.status_int, exc.HTTPBadRequest.code)
# All is kosher so we can create the port
kwargs = {portbindings.VNIC_TYPE: portbindings.VNIC_DIRECT}
net_id = network['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,),
**kwargs)
port = self.deserialize('json', res)
self.assertEqual("direct", port['port'][portbindings.VNIC_TYPE])
self.assertEqual("dvs", port['port'][portbindings.VIF_TYPE])
self.assertEqual(
vlan_id,
port['port'][portbindings.VIF_DETAILS]['segmentation-id'])
# try to get the same port
req = self.new_show_request('ports', port['port']['id'], self.fmt)
sport = self.deserialize(self.fmt, req.get_response(self.api))
self.assertEqual("dvs", sport['port'][portbindings.VIF_TYPE])
self.assertEqual("direct", sport['port'][portbindings.VNIC_TYPE])
self.assertEqual(
vlan_id,
sport['port'][portbindings.VIF_DETAILS]['segmentation-id'])
self.assertFalse(
sport['port'][portbindings.VIF_DETAILS]['vlan-transparent'])
def test_create_port_vnic_direct_flat(self):
self._test_create_port_vnic_direct(0)
def test_create_port_vnic_direct_vlan(self):
self._test_create_port_vnic_direct(10)
def test_create_port_vnic_direct_invalid_network(self):
with self.network(name='not vlan/flat') as net:
kwargs = {portbindings.VNIC_TYPE: portbindings.VNIC_DIRECT,
psec.PORTSECURITY: False}
net_id = net['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,
psec.PORTSECURITY),
**kwargs)
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
def test_update_vnic_direct(self):
with self._test_create_direct_network(vlan_id=7) as network:
with self.subnet(network=network) as subnet:
with self.port(subnet=subnet) as port:
# need to do two updates as the update for port security
# disabled requires that it can only change 2 items
data = {'port': {psec.PORTSECURITY: False,
'security_groups': []}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual(portbindings.VNIC_NORMAL,
res['port'][portbindings.VNIC_TYPE])
data = {'port': {portbindings.VNIC_TYPE:
portbindings.VNIC_DIRECT}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual(portbindings.VNIC_DIRECT,
res['port'][portbindings.VNIC_TYPE])
def test_port_invalid_vnic_type(self):
with self._test_create_direct_network(vlan_id=7) as network:
kwargs = {portbindings.VNIC_TYPE: 'invalid',
psec.PORTSECURITY: False}
net_id = network['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,
psec.PORTSECURITY),
**kwargs)
self.assertEqual(res.status_int, exc.HTTPBadRequest.code)
def test_create_transparent_vlan_port(self):
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
vlan_apidef.VLANTRANSPARENT: True}
with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
'get_transport_type', return_value='VLAN'):
result = self._create_network(fmt='json', name='vlan_net',
admin_state_up=True,
providernet_args=providernet_args,
arg_list=(
pnet.NETWORK_TYPE,
pnet.SEGMENTATION_ID,
vlan_apidef.VLANTRANSPARENT))
network = self.deserialize('json', result)
net_id = network['network']['id']
with self.subnet(network=network):
kwargs = {portbindings.VNIC_TYPE: portbindings.VNIC_DIRECT}
net_id = network['network']['id']
res = self._create_port(self.fmt, net_id=net_id,
arg_list=(portbindings.VNIC_TYPE,),
**kwargs)
port = self.deserialize('json', res)
self.assertTrue(
port['port'][portbindings.VIF_DETAILS]['vlan-transparent'])
@common_v3.with_disable_dhcp
def test_requested_subnet_id_v4_and_v6(self):
return super(TestPortsV2, self).test_requested_subnet_id_v4_and_v6()
def test_port_binding_host(self):
with self.port() as port:
# add host
data = {'port': {portbindings.HOST_ID: 'abc'}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual('abc', res['port'][portbindings.HOST_ID])
# remove host
data = {'port': {portbindings.HOST_ID: None}}
req = self.new_update_request('ports',
data, port['port']['id'])
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual('', res['port'][portbindings.HOST_ID])
class DHCPOptsTestCase(test_dhcpopts.TestExtraDhcpOpt,
NsxV3PluginTestCaseMixin):
def setUp(self, plugin=None):
super(test_dhcpopts.ExtraDhcpOptDBTestCase, self).setUp(
plugin=PLUGIN_NAME)
class NSXv3DHCPAgentAZAwareWeightSchedulerTestCase(
test_dhcpagent.DHCPAgentAZAwareWeightSchedulerTestCase,
NsxV3PluginTestCaseMixin):
def setUp(self):
super(NSXv3DHCPAgentAZAwareWeightSchedulerTestCase, self).setUp()
self.plugin = directory.get_plugin()
self.ctx = context.get_admin_context()
def setup_coreplugin(self, core_plugin=None, load_plugins=True):
super(NSXv3DHCPAgentAZAwareWeightSchedulerTestCase,
self).setup_coreplugin(core_plugin=PLUGIN_NAME,
load_plugins=load_plugins)
class TestL3ExtensionManager(object):
def get_resources(self):
# Simulate extension of L3 attribute map
l3.L3().update_attributes_map(
l3_egm_apidef.RESOURCE_ATTRIBUTE_MAP)
l3.L3().update_attributes_map(
xroute_apidef.RESOURCE_ATTRIBUTE_MAP)
return (l3.L3.get_resources() +
address_scope.Address_scope.get_resources())
def get_actions(self):
return []
def get_request_extensions(self):
return []
class L3NatTest(test_l3_plugin.L3BaseForIntTests,
NsxV3PluginTestCaseMixin,
common_v3.FixExternalNetBaseTest,
common_v3.NsxV3SubnetMixin,
test_address_scope.AddressScopeTestCase):
def setUp(self, plugin=PLUGIN_NAME, ext_mgr=None,
service_plugins=None):
cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH)
cfg.CONF.set_default('max_routes', 3)
ext_mgr = ext_mgr or TestL3ExtensionManager()
mock_nsx_version = mock.patch.object(nsx_plugin.utils,
'is_nsx_version_2_0_0',
new=lambda v: True)
mock_nsx_version.start()
# Make sure the LB callback is not called on router deletion
self.lb_mock1 = mock.patch(
"vmware_nsx.services.lbaas.octavia.octavia_listener."
"NSXOctaviaListenerEndpoint._check_lb_service_on_router")
self.lb_mock1.start()
self.lb_mock2 = mock.patch(
"vmware_nsx.services.lbaas.octavia.octavia_listener."
"NSXOctaviaListenerEndpoint._check_lb_service_on_router_interface")
self.lb_mock2.start()
super(L3NatTest, self).setUp(
plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins)
self.plugin_instance = directory.get_plugin()
self._plugin_name = "%s.%s" % (
self.plugin_instance.__module__,
self.plugin_instance.__class__.__name__)
self._plugin_class = self.plugin_instance.__class__
self.plugin_instance.fwaas_callbacks = None
self.original_subnet = self.subnet
self.original_network = self.network
def _set_net_external(self, net_id):
# This action is not supported by the V3 plugin
pass
def external_network(self, name='net1',
admin_state_up=True,
fmt=None, **kwargs):
if not name:
name = 'l3_ext_net'
physical_network = nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID
net_type = utils.NetworkTypes.L3_EXT
providernet_args = {pnet.NETWORK_TYPE: net_type,
pnet.PHYSICAL_NETWORK: physical_network}
return self.original_network(name=name,
admin_state_up=admin_state_up,
fmt=fmt,
router__external=True,
providernet_args=providernet_args,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK))
def test_floatingip_create_different_fixed_ip_same_port(self):
self.skipTest('Multiple fixed ips on a port are not supported')
def test_router_add_interface_multiple_ipv4_subnet_port_returns_400(self):
self.skipTest('Multiple fixed ips on a port are not supported')
def test_router_add_interface_multiple_ipv6_subnet_port(self):
self.skipTest('Multiple fixed ips on a port are not supported')
def test_floatingip_update_different_fixed_ip_same_port(self):
self.skipTest('Multiple fixed ips on a port are not supported')
def test_create_multiple_floatingips_same_fixed_ip_same_port(self):
self.skipTest('Multiple fixed ips on a port are not supported')
class TestL3NatTestCase(L3NatTest,
test_l3_plugin.L3NatDBIntTestCase,
test_ext_route.ExtraRouteDBTestCaseBase,
test_metadata.MetaDataTestCase):
block_dhcp_notifier = False
def setUp(self, plugin=PLUGIN_NAME,
ext_mgr=None,
service_plugins=None):
super(TestL3NatTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
cfg.CONF.set_override('metadata_mode', None, 'nsx_v3')
cfg.CONF.set_override('metadata_on_demand', False, 'nsx_v3')
self.subnet_calls = []
def _test_create_l3_ext_network(
self, physical_network=nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID):
name = 'l3_ext_net'
net_type = utils.NetworkTypes.L3_EXT
expected = [('subnets', []), ('name', name), ('admin_state_up', True),
('status', 'ACTIVE'), ('shared', False),
(extnet_apidef.EXTERNAL, True),
(pnet.NETWORK_TYPE, net_type),
(pnet.PHYSICAL_NETWORK, physical_network)]
with self._create_l3_ext_network(physical_network) as net:
for k, v in expected:
self.assertEqual(net['network'][k], v)
@common_v3.with_external_subnet
def test_router_update_gateway_with_external_ip_used_by_gw(self):
super(TestL3NatTestCase,
self).test_router_update_gateway_with_external_ip_used_by_gw()
@common_v3.with_external_subnet
def test_router_update_gateway_with_invalid_external_ip(self):
super(TestL3NatTestCase,
self).test_router_update_gateway_with_invalid_external_ip()
@common_v3.with_external_subnet
def test_router_update_gateway_with_invalid_external_subnet(self):
super(TestL3NatTestCase,
self).test_router_update_gateway_with_invalid_external_subnet()
@common_v3.with_external_network
def test_router_update_gateway_with_different_external_subnet(self):
super(TestL3NatTestCase,
self).test_router_update_gateway_with_different_external_subnet()
@common_v3.with_disable_dhcp
def test_create_floatingip_ipv6_only_network_returns_400(self):
super(TestL3NatTestCase,
self).test_create_floatingip_ipv6_only_network_returns_400()
@common_v3.with_disable_dhcp
def test_create_floatingip_with_assoc_to_ipv4_and_ipv6_port(self):
super(L3NatTest,
self).test_create_floatingip_with_assoc_to_ipv4_and_ipv6_port()
@common_v3.with_external_subnet_once
def test_router_update_gateway_with_existed_floatingip(self):
with self.subnet(cidr='20.0.0.0/24') as subnet: