NSXv3: Support network creation options
Handle admin state and provider network options during NSXv3 network creation. Change-Id: I13a848f943d0e983542d16f26a821bd9a3899442
This commit is contained in:
parent
865fccf9ab
commit
fedfa5962f
@ -85,11 +85,14 @@ function neutron_plugin_configure_plugin_agent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function neutron_plugin_configure_service {
|
function neutron_plugin_configure_service {
|
||||||
if [[ "$DEFAULT_TZ_UUID" != "" ]]; then
|
if [[ "$DEFAULT_OVERLAY_TZ_UUID" != "" ]]; then
|
||||||
iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_tz_uuid $DEFAULT_TZ_UUID
|
iniset /$Q_PLUGIN_CONF_FILE nsx_v3 default_overlay_tz_uuid $DEFAULT_OVERLAY_TZ_UUID
|
||||||
else
|
else
|
||||||
die $LINENO "The VMware NSX plugin won't work without a default transport zone."
|
die $LINENO "The VMware NSX plugin won't work without a default transport zone."
|
||||||
fi
|
fi
|
||||||
|
if [[ "$DEFAULT_VLAN_TZ_UUID" != "" ]]; then
|
||||||
|
iniset /$Q_PLUGIN_CONF_FILE nsx_v3 default_vlan_tz_uuid $DEFAULT_VLAN_TZ_UUID
|
||||||
|
fi
|
||||||
if [[ "$DEFAULT_EDGE_CLUSTER_UUID" != "" ]]; then
|
if [[ "$DEFAULT_EDGE_CLUSTER_UUID" != "" ]]; then
|
||||||
iniset /$Q_PLUGIN_CONF_FILE nsx_v3 default_edge_cluster_uuid $DEFAULT_EDGE_CLUSTER_UUID
|
iniset /$Q_PLUGIN_CONF_FILE nsx_v3 default_edge_cluster_uuid $DEFAULT_EDGE_CLUSTER_UUID
|
||||||
Q_L3_ENABLED=True
|
Q_L3_ENABLED=True
|
||||||
|
@ -172,9 +172,23 @@ nsx_v3_opts = [
|
|||||||
help=_('IP address of the NSX manager')),
|
help=_('IP address of the NSX manager')),
|
||||||
cfg.StrOpt('default_edge_cluster_uuid',
|
cfg.StrOpt('default_edge_cluster_uuid',
|
||||||
help=_("Default edge cluster identifier")),
|
help=_("Default edge cluster identifier")),
|
||||||
|
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',
|
||||||
|
help=_("This is the UUID of the default NSX VLAN transport "
|
||||||
|
"zone that will be used for bridging between Neutron "
|
||||||
|
"networks. It needs to be created in NSX before "
|
||||||
|
"starting Neutron with the NSX plugin.")),
|
||||||
|
cfg.StrOpt('default_edge_cluster_uuid',
|
||||||
|
help=_("Default edge cluster identifier")),
|
||||||
cfg.IntOpt('retries',
|
cfg.IntOpt('retries',
|
||||||
default=10,
|
default=10,
|
||||||
help=_('Maximum number of times to retry API request'))]
|
help=_('Maximum number of times to retry API request'))
|
||||||
|
]
|
||||||
|
|
||||||
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
||||||
DEFAULT_MINIMUM_POOLED_EDGES = 1
|
DEFAULT_MINIMUM_POOLED_EDGES = 1
|
||||||
|
@ -47,6 +47,14 @@ class NsxVNetworkTypes:
|
|||||||
PORTGROUP = 'portgroup'
|
PORTGROUP = 'portgroup'
|
||||||
|
|
||||||
|
|
||||||
|
# Allowed network types for the NSXv3 Plugin
|
||||||
|
class NsxV3NetworkTypes:
|
||||||
|
"""Allowed provider network types for the NSXv3 Plugin."""
|
||||||
|
FLAT = 'flat'
|
||||||
|
VLAN = 'vlan'
|
||||||
|
VXLAN = 'vxlan'
|
||||||
|
|
||||||
|
|
||||||
def get_tags(**kwargs):
|
def get_tags(**kwargs):
|
||||||
tags = ([dict(tag=value, scope=key)
|
tags = ([dict(tag=value, scope=key)
|
||||||
for key, value in six.iteritems(kwargs)])
|
for key, value in six.iteritems(kwargs)])
|
||||||
|
@ -26,7 +26,7 @@ LOG = log.getLogger(__name__)
|
|||||||
|
|
||||||
def create_logical_switch(display_name, transport_zone_id, tags,
|
def create_logical_switch(display_name, transport_zone_id, tags,
|
||||||
replication_mode=nsx_constants.MTEP,
|
replication_mode=nsx_constants.MTEP,
|
||||||
admin_state=nsx_constants.ADMIN_STATE_UP):
|
admin_state=True, vlan_id=None):
|
||||||
# TODO(salv-orlando): Validate Replication mode and admin_state
|
# TODO(salv-orlando): Validate Replication mode and admin_state
|
||||||
# NOTE: These checks might be moved to the API client library if one that
|
# NOTE: These checks might be moved to the API client library if one that
|
||||||
# performs such checks in the client is available
|
# performs such checks in the client is available
|
||||||
@ -34,10 +34,17 @@ def create_logical_switch(display_name, transport_zone_id, tags,
|
|||||||
resource = 'logical-switches'
|
resource = 'logical-switches'
|
||||||
body = {'transport_zone_id': transport_zone_id,
|
body = {'transport_zone_id': transport_zone_id,
|
||||||
'replication_mode': replication_mode,
|
'replication_mode': replication_mode,
|
||||||
'admin_state': admin_state,
|
|
||||||
'display_name': display_name,
|
'display_name': display_name,
|
||||||
'tags': tags}
|
'tags': tags}
|
||||||
|
|
||||||
|
if admin_state:
|
||||||
|
body['admin_state'] = nsx_constants.ADMIN_STATE_UP
|
||||||
|
else:
|
||||||
|
body['admin_state'] = nsx_constants.ADMIN_STATE_DOWN
|
||||||
|
|
||||||
|
if vlan_id:
|
||||||
|
body['vlan'] = vlan_id
|
||||||
|
|
||||||
return client.create_resource(resource, body)
|
return client.create_resource(resource, body)
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,8 +28,10 @@ from neutron.api.rpc.handlers import metadata_rpc
|
|||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
from neutron.extensions import l3
|
from neutron.extensions import l3
|
||||||
from neutron.extensions import portbindings as pbin
|
from neutron.extensions import portbindings as pbin
|
||||||
|
from neutron.extensions import providernet as pnet
|
||||||
|
|
||||||
from neutron.common import constants as const
|
from neutron.common import constants as const
|
||||||
|
from neutron.common import exceptions as n_exc
|
||||||
from neutron.common import rpc as n_rpc
|
from neutron.common import rpc as n_rpc
|
||||||
from neutron.common import topics
|
from neutron.common import topics
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
@ -40,6 +42,8 @@ from neutron.db import models_v2
|
|||||||
from neutron.db import portbindings_db
|
from neutron.db import portbindings_db
|
||||||
from neutron.db import securitygroups_db
|
from neutron.db import securitygroups_db
|
||||||
from neutron.i18n import _LE, _LW
|
from neutron.i18n import _LE, _LW
|
||||||
|
from neutron.plugins.common import constants as plugin_const
|
||||||
|
from neutron.plugins.common import utils as n_utils
|
||||||
|
|
||||||
from vmware_nsx.neutron.plugins.vmware.common import config # noqa
|
from vmware_nsx.neutron.plugins.vmware.common import config # noqa
|
||||||
from vmware_nsx.neutron.plugins.vmware.common import exceptions as nsx_exc
|
from vmware_nsx.neutron.plugins.vmware.common import exceptions as nsx_exc
|
||||||
@ -65,7 +69,8 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
supported_extension_aliases = ["quotas",
|
supported_extension_aliases = ["quotas",
|
||||||
"binding",
|
"binding",
|
||||||
"security-group",
|
"security-group",
|
||||||
"router"]
|
"router",
|
||||||
|
"provider"]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(NsxV3Plugin, self).__init__()
|
super(NsxV3Plugin, self).__init__()
|
||||||
@ -95,17 +100,130 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
self.supported_extension_aliases.extend(
|
self.supported_extension_aliases.extend(
|
||||||
['agent', 'dhcp_agent_scheduler'])
|
['agent', 'dhcp_agent_scheduler'])
|
||||||
|
|
||||||
|
def _validate_provider_create(self, context, network_data):
|
||||||
|
physical_net = network_data.get(pnet.PHYSICAL_NETWORK)
|
||||||
|
if not attributes.is_attr_set(physical_net):
|
||||||
|
physical_net = None
|
||||||
|
|
||||||
|
vlan_id = network_data.get(pnet.SEGMENTATION_ID)
|
||||||
|
if not attributes.is_attr_set(vlan_id):
|
||||||
|
vlan_id = None
|
||||||
|
|
||||||
|
err_msg = None
|
||||||
|
net_type = network_data.get(pnet.NETWORK_TYPE)
|
||||||
|
if attributes.is_attr_set(net_type):
|
||||||
|
if net_type == utils.NsxV3NetworkTypes.FLAT:
|
||||||
|
if vlan_id is not None:
|
||||||
|
err_msg = (_("Segmentation ID cannot be specified with "
|
||||||
|
"%s network type") %
|
||||||
|
utils.NsxV3NetworkTypes.FLAT)
|
||||||
|
else:
|
||||||
|
# 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
|
||||||
|
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
|
||||||
|
|
||||||
|
# Validate VLAN id
|
||||||
|
if not vlan_id:
|
||||||
|
err_msg = (_('Segmentation ID must be specified with %s '
|
||||||
|
'network type') %
|
||||||
|
utils.NsxV3NetworkTypes.VLAN)
|
||||||
|
elif not n_utils.is_valid_vlan_tag(vlan_id):
|
||||||
|
err_msg = (_('Segmentation ID %(segmentation_id)s out of '
|
||||||
|
'range (%(min_id)s through %(max_id)s)') %
|
||||||
|
{'segmentation_id': vlan_id,
|
||||||
|
'min_id': plugin_const.MIN_VLAN_TAG,
|
||||||
|
'max_id': plugin_const.MAX_VLAN_TAG})
|
||||||
|
else:
|
||||||
|
# Verify VLAN id is not already allocated
|
||||||
|
bindings = (
|
||||||
|
nsx_db.get_network_bindings_by_vlanid_and_physical_net(
|
||||||
|
context.session, vlan_id, physical_net)
|
||||||
|
)
|
||||||
|
if bindings:
|
||||||
|
raise n_exc.VlanIdInUse(
|
||||||
|
vlan_id=vlan_id, physical_network=physical_net)
|
||||||
|
elif net_type == utils.NsxV3NetworkTypes.VXLAN:
|
||||||
|
if vlan_id:
|
||||||
|
err_msg = (_("Segmentation ID cannot be specified with "
|
||||||
|
"%s network type") %
|
||||||
|
utils.NsxV3NetworkTypes.VXLAN)
|
||||||
|
else:
|
||||||
|
err_msg = (_('%(net_type_param)s %(net_type_value)s not '
|
||||||
|
'supported') %
|
||||||
|
{'net_type_param': pnet.NETWORK_TYPE,
|
||||||
|
'net_type_value': net_type})
|
||||||
|
else:
|
||||||
|
net_type = None
|
||||||
|
|
||||||
|
if err_msg:
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
|
||||||
|
if physical_net is None:
|
||||||
|
# Default to transport type overlay
|
||||||
|
physical_net = cfg.CONF.nsx_v3.default_overlay_tz_uuid
|
||||||
|
|
||||||
|
return net_type, physical_net, vlan_id
|
||||||
|
|
||||||
|
def _extend_network_dict_provider(self, context, network, bindings=None):
|
||||||
|
if not bindings:
|
||||||
|
bindings = nsx_db.get_network_bindings(context.session,
|
||||||
|
network['id'])
|
||||||
|
# With NSX plugin, "normal" overlay networks will have no binding
|
||||||
|
if bindings:
|
||||||
|
# Network came in through provider networks API
|
||||||
|
network[pnet.NETWORK_TYPE] = bindings[0].binding_type
|
||||||
|
network[pnet.PHYSICAL_NETWORK] = bindings[0].phy_uuid
|
||||||
|
network[pnet.SEGMENTATION_ID] = bindings[0].vlan_id
|
||||||
|
|
||||||
def create_network(self, context, network):
|
def create_network(self, context, network):
|
||||||
|
# TODO(jwy): Handle creating external network (--router:external)
|
||||||
|
is_provider_net = any(attributes.is_attr_set(network['network'].get(f))
|
||||||
|
for f in (pnet.NETWORK_TYPE,
|
||||||
|
pnet.PHYSICAL_NETWORK,
|
||||||
|
pnet.SEGMENTATION_ID))
|
||||||
|
net_type, physical_net, vlan_id = self._validate_provider_create(
|
||||||
|
context, network['network'])
|
||||||
|
net_name = network['network']['name']
|
||||||
tags = utils.build_v3_tags_payload(network['network'])
|
tags = utils.build_v3_tags_payload(network['network'])
|
||||||
result = nsxlib.create_logical_switch(
|
admin_state = network['network'].get('admin_state_up', True)
|
||||||
network['network']['name'],
|
|
||||||
cfg.CONF.default_tz_uuid, tags)
|
# Create network on the backend
|
||||||
network['network']['id'] = result['id']
|
LOG.debug('create_network: %(net_name)s, %(physical_net)s, %(tags)s, '
|
||||||
|
'%(admin_state)s, %(vlan_id)s',
|
||||||
|
{'net_name': net_name,
|
||||||
|
'physical_net': physical_net,
|
||||||
|
'tags': tags,
|
||||||
|
'admin_state': admin_state,
|
||||||
|
'vlan_id': vlan_id})
|
||||||
|
result = nsxlib.create_logical_switch(net_name, physical_net, tags,
|
||||||
|
admin_state=admin_state,
|
||||||
|
vlan_id=vlan_id)
|
||||||
|
net_id = result['id']
|
||||||
|
network['network']['id'] = net_id
|
||||||
tenant_id = self._get_tenant_id_for_create(context, network['network'])
|
tenant_id = self._get_tenant_id_for_create(context, network['network'])
|
||||||
|
|
||||||
self._ensure_default_security_group(context, tenant_id)
|
self._ensure_default_security_group(context, tenant_id)
|
||||||
network = super(NsxV3Plugin, self).create_network(context, network)
|
with context.session.begin(subtransactions=True):
|
||||||
# TODO(salv-orlando): Undo logical switch creation on failure
|
# Create network in Neutron
|
||||||
|
try:
|
||||||
|
network = super(NsxV3Plugin, self).create_network(context,
|
||||||
|
network)
|
||||||
|
except Exception:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
# Undo creation on the backend
|
||||||
|
LOG.exception(_LE('Failed to create network %s'), net_id)
|
||||||
|
nsxlib.delete_logical_switch(net_id)
|
||||||
|
|
||||||
|
if is_provider_net:
|
||||||
|
# Save provider network fields, needed by get_network()
|
||||||
|
nsx_db.add_network_binding(context.session, net_id, net_type,
|
||||||
|
physical_net, vlan_id)
|
||||||
|
|
||||||
return network
|
return network
|
||||||
|
|
||||||
def delete_network(self, context, network_id):
|
def delete_network(self, context, network_id):
|
||||||
@ -136,6 +254,31 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
'ip_address': fixed_ip['ip_address']})
|
'ip_address': fixed_ip['ip_address']})
|
||||||
return address_bindings
|
return address_bindings
|
||||||
|
|
||||||
|
def get_network(self, context, id, fields=None):
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
|
# Get network from Neutron database
|
||||||
|
network = self._get_network(context, id)
|
||||||
|
# Don't do field selection here otherwise we won't be able to add
|
||||||
|
# provider networks fields
|
||||||
|
net = self._make_network_dict(network, context=context)
|
||||||
|
self._extend_network_dict_provider(context, net)
|
||||||
|
return self._fields(net, fields)
|
||||||
|
|
||||||
|
def get_networks(self, context, filters=None, fields=None,
|
||||||
|
sorts=None, limit=None, marker=None,
|
||||||
|
page_reverse=False):
|
||||||
|
# Get networks from Neutron database
|
||||||
|
filters = filters or {}
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
|
networks = (
|
||||||
|
super(NsxV3Plugin, self).get_networks(
|
||||||
|
context, filters, fields, sorts,
|
||||||
|
limit, marker, page_reverse))
|
||||||
|
# Add provider network fields
|
||||||
|
for net in networks:
|
||||||
|
self._extend_network_dict_provider(context, net)
|
||||||
|
return [self._fields(network, fields) for network in networks]
|
||||||
|
|
||||||
def create_port(self, context, port):
|
def create_port(self, context, port):
|
||||||
port_id = uuidutils.generate_uuid()
|
port_id = uuidutils.generate_uuid()
|
||||||
tags = utils.build_v3_tags_payload(port['port'])
|
tags = utils.build_v3_tags_payload(port['port'])
|
||||||
|
@ -22,18 +22,18 @@ from vmware_nsx.neutron.plugins.vmware.common import nsx_constants
|
|||||||
FAKE_NAME = "fake_name"
|
FAKE_NAME = "fake_name"
|
||||||
|
|
||||||
|
|
||||||
def create_logical_switch(display_name, transport_zone_id, tags,
|
def make_fake_switch(switch_uuid=None, tz_uuid=None, name=FAKE_NAME):
|
||||||
replication_mode=nsx_constants.MTEP,
|
if not switch_uuid:
|
||||||
admin_state=nsx_constants.ADMIN_STATE_UP):
|
switch_uuid = uuidutils.generate_uuid()
|
||||||
FAKE_TZ_UUID = uuidutils.generate_uuid()
|
if not tz_uuid:
|
||||||
FAKE_SWITCH_UUID = uuidutils.generate_uuid()
|
tz_uuid = uuidutils.generate_uuid()
|
||||||
|
|
||||||
FAKE_SWITCH = {
|
fake_switch = {
|
||||||
"id": FAKE_SWITCH_UUID,
|
"id": switch_uuid,
|
||||||
"display_name": FAKE_NAME,
|
"display_name": name,
|
||||||
"resource_type": "LogicalSwitch",
|
"resource_type": "LogicalSwitch",
|
||||||
"address_bindings": [],
|
"address_bindings": [],
|
||||||
"transport_zone_id": FAKE_TZ_UUID,
|
"transport_zone_id": tz_uuid,
|
||||||
"replication_mode": nsx_constants.MTEP,
|
"replication_mode": nsx_constants.MTEP,
|
||||||
"admin_state": nsx_constants.ADMIN_STATE_UP,
|
"admin_state": nsx_constants.ADMIN_STATE_UP,
|
||||||
"vni": 50056,
|
"vni": 50056,
|
||||||
@ -60,7 +60,13 @@ def create_logical_switch(display_name, transport_zone_id, tags,
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
return FAKE_SWITCH
|
return fake_switch
|
||||||
|
|
||||||
|
|
||||||
|
def create_logical_switch(display_name, transport_zone_id, tags,
|
||||||
|
replication_mode=nsx_constants.MTEP,
|
||||||
|
admin_state=True, vlan_id=None):
|
||||||
|
return make_fake_switch()
|
||||||
|
|
||||||
|
|
||||||
def create_logical_port(lswitch_id, vif_uuid, tags,
|
def create_logical_port(lswitch_id, vif_uuid, tags,
|
||||||
|
@ -17,10 +17,12 @@
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from vmware_nsx.neutron.plugins.vmware.common import nsx_constants
|
||||||
from vmware_nsx.neutron.plugins.vmware.nsxlib import v3 as nsxlib
|
from vmware_nsx.neutron.plugins.vmware.nsxlib import v3 as nsxlib
|
||||||
|
from vmware_nsx.neutron.tests.unit.vmware import nsx_v3_mocks
|
||||||
from vmware_nsx.neutron.tests.unit.vmware.nsxlib.v3 import nsxlib_testcase
|
from vmware_nsx.neutron.tests.unit.vmware.nsxlib.v3 import nsxlib_testcase
|
||||||
from vmware_nsx.neutron.tests.unit.vmware import test_constants_v3
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -33,9 +35,52 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxLibTestCase):
|
|||||||
"""
|
"""
|
||||||
Test creating a switch returns the correct response and 200 status
|
Test creating a switch returns the correct response and 200 status
|
||||||
"""
|
"""
|
||||||
mock_create_resource.return_value = test_constants_v3.FAKE_SWITCH
|
tz_uuid = uuidutils.generate_uuid()
|
||||||
|
fake_switch = nsx_v3_mocks.make_fake_switch(tz_uuid=tz_uuid)
|
||||||
|
mock_create_resource.return_value = fake_switch
|
||||||
|
|
||||||
result = nsxlib.create_logical_switch(test_constants_v3.FAKE_NAME,
|
result = nsxlib.create_logical_switch(nsx_v3_mocks.FAKE_NAME, tz_uuid,
|
||||||
test_constants_v3.FAKE_TZ_UUID,
|
[])
|
||||||
tags={})
|
self.assertEqual(fake_switch, result)
|
||||||
self.assertEqual(test_constants_v3.FAKE_SWITCH, result)
|
|
||||||
|
@mock.patch("vmware_nsx.neutron.plugins.vmware.nsxlib.v3"
|
||||||
|
".client.create_resource")
|
||||||
|
def test_create_logical_switch_admin_down(self, mock_create_resource):
|
||||||
|
"""
|
||||||
|
Test creating switch with admin_state down
|
||||||
|
"""
|
||||||
|
tz_uuid = uuidutils.generate_uuid()
|
||||||
|
fake_switch = nsx_v3_mocks.make_fake_switch(tz_uuid=tz_uuid)
|
||||||
|
fake_switch['admin_state'] = nsx_constants.ADMIN_STATE_DOWN
|
||||||
|
mock_create_resource.return_value = fake_switch
|
||||||
|
|
||||||
|
result = nsxlib.create_logical_switch(nsx_v3_mocks.FAKE_NAME, tz_uuid,
|
||||||
|
[], admin_state=False)
|
||||||
|
self.assertEqual(fake_switch, result)
|
||||||
|
|
||||||
|
@mock.patch("vmware_nsx.neutron.plugins.vmware.nsxlib.v3"
|
||||||
|
".client.create_resource")
|
||||||
|
def test_create_logical_switch_vlan(self, mock_create_resource):
|
||||||
|
"""
|
||||||
|
Test creating switch with provider:network_type VLAN
|
||||||
|
"""
|
||||||
|
tz_uuid = uuidutils.generate_uuid()
|
||||||
|
fake_switch = nsx_v3_mocks.make_fake_switch()
|
||||||
|
fake_switch['vlan_id'] = '123'
|
||||||
|
mock_create_resource.return_value = fake_switch
|
||||||
|
|
||||||
|
result = nsxlib.create_logical_switch(nsx_v3_mocks.FAKE_NAME, tz_uuid,
|
||||||
|
[])
|
||||||
|
self.assertEqual(fake_switch, result)
|
||||||
|
|
||||||
|
@mock.patch("vmware_nsx.neutron.plugins.vmware.nsxlib.v3"
|
||||||
|
".client.delete_resource")
|
||||||
|
def test_delete_logical_switch(self, mock_delete_resource):
|
||||||
|
"""
|
||||||
|
Test deleting switch
|
||||||
|
"""
|
||||||
|
mock_delete_resource.return_value = None
|
||||||
|
|
||||||
|
fake_switch = nsx_v3_mocks.make_fake_switch()
|
||||||
|
result = nsxlib.delete_logical_switch(fake_switch['id'])
|
||||||
|
self.assertIsNone(result)
|
||||||
|
@ -17,42 +17,8 @@
|
|||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
FAKE_NAME = "fake_name"
|
FAKE_NAME = "fake_name"
|
||||||
FAKE_TZ_UUID = uuidutils.generate_uuid()
|
|
||||||
FAKE_SWITCH_UUID = uuidutils.generate_uuid()
|
FAKE_SWITCH_UUID = uuidutils.generate_uuid()
|
||||||
|
|
||||||
FAKE_SWITCH = {
|
|
||||||
"id": FAKE_SWITCH_UUID,
|
|
||||||
"display_name": FAKE_NAME,
|
|
||||||
"resource_type": "LogicalSwitch",
|
|
||||||
"address_bindings": [],
|
|
||||||
"transport_zone_id": FAKE_TZ_UUID,
|
|
||||||
"replication_mode": "MTEP",
|
|
||||||
"admin_state": "UP",
|
|
||||||
"vni": 50056,
|
|
||||||
"switching_profile_ids": [
|
|
||||||
{
|
|
||||||
"value": "64814784-7896-3901-9741-badeff705639",
|
|
||||||
"key": "IpDiscoverySwitchingProfile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
|
||||||
"key": "SpoofGuardSwitchingProfile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
|
||||||
"key": "PortMirroringSwitchingProfile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
|
||||||
"key": "SwitchSecuritySwitchingProfile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
|
||||||
"key": "QosSwitchingProfile"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
FAKE_PORT_UUID = uuidutils.generate_uuid()
|
FAKE_PORT_UUID = uuidutils.generate_uuid()
|
||||||
FAKE_PORT = {
|
FAKE_PORT = {
|
||||||
"id": FAKE_PORT_UUID,
|
"id": FAKE_PORT_UUID,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user