from neutron.plugins.nicira.extensions import maclearning as mac_ext
from neutron.plugins.nicira.extensions import nvp_networkgw as networkgw
from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
+from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib
from neutron.plugins.nicira.nsxlib import queue as queuelib
from neutron.plugins.nicira.nsxlib import router as routerlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
from neutron.plugins.nicira import NvpApiClient
from neutron.plugins.nicira import nvplib
def _nvp_create_port_helper(self, cluster, ls_uuid, port_data,
do_port_security=True):
- return nvplib.create_lport(cluster, ls_uuid, port_data['tenant_id'],
- port_data['id'], port_data['name'],
- port_data['device_id'],
- port_data['admin_state_up'],
- port_data['mac_address'],
- port_data['fixed_ips'],
- port_data[psec.PORTSECURITY],
- port_data[ext_sg.SECURITYGROUPS],
- port_data.get(ext_qos.QUEUE),
- port_data.get(mac_ext.MAC_LEARNING),
- port_data.get(addr_pair.ADDRESS_PAIRS))
+ return switchlib.create_lport(cluster, ls_uuid, port_data['tenant_id'],
+ port_data['id'], port_data['name'],
+ port_data['device_id'],
+ port_data['admin_state_up'],
+ port_data['mac_address'],
+ port_data['fixed_ips'],
+ port_data[psec.PORTSECURITY],
+ port_data[ext_sg.SECURITYGROUPS],
+ port_data.get(ext_qos.QUEUE),
+ port_data.get(mac_ext.MAC_LEARNING),
+ port_data.get(addr_pair.ADDRESS_PAIRS))
def _handle_create_port_exception(self, context, port_id,
ls_uuid, lp_uuid):
# created on NVP. Should this command fail the original
# exception will be raised.
if lp_uuid:
- # Remove orphaned port from NVP
- nvplib.delete_port(self.cluster, ls_uuid, lp_uuid)
+ # Remove orphaned port from NSX
+ switchlib.delete_port(self.cluster, ls_uuid, lp_uuid)
# rollback the neutron-nvp port mapping
nicira_db.delete_neutron_nsx_port_mapping(context.session,
port_id)
context.session, port_data['id'],
selected_lswitch['uuid'], lport['uuid'])
if port_data['device_owner'] not in self.port_special_owners:
- nvplib.plug_interface(self.cluster, selected_lswitch['uuid'],
- lport['uuid'], "VifAttachment",
- port_data['id'])
+ switchlib.plug_interface(
+ self.cluster, selected_lswitch['uuid'],
+ lport['uuid'], "VifAttachment", port_data['id'])
LOG.debug(_("_nvp_create_port completed for port %(name)s "
"on network %(network_id)s. The new port id is "
"%(id)s."), port_data)
LOG.warning(msg)
if selected_lswitch and lport:
try:
- nvplib.delete_port(self.cluster,
- selected_lswitch['uuid'],
- lport['uuid'])
+ switchlib.delete_port(self.cluster,
+ selected_lswitch['uuid'],
+ lport['uuid'])
except q_exc.NotFound:
LOG.debug(_("NSX Port %s already gone"), lport['uuid'])
"external networks. Port %s will be down."),
port_data['network_id'])
return
- nvp_switch_id, nvp_port_id = nsx_utils.get_nsx_switch_and_port_id(
+ nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
context.session, self.cluster, port_data['id'])
- if not nvp_port_id:
+ if not nsx_port_id:
LOG.debug(_("Port '%s' was already deleted on NVP platform"), id)
return
# TODO(bgh): if this is a bridged network and the lswitch we just got
# back will have zero ports after the delete we should garbage collect
# the lswitch.
try:
- nvplib.delete_port(self.cluster,
- nvp_switch_id,
- nvp_port_id)
+ switchlib.delete_port(self.cluster, nsx_switch_id, nsx_port_id)
LOG.debug(_("_nvp_delete_port completed for port %(port_id)s "
"on network %(net_id)s"),
{'port_id': port_data['id'],
nicira_db.add_neutron_nsx_port_mapping(
context.session, port_data['id'],
selected_lswitch['uuid'], lport['uuid'])
- nvplib.plug_l2_gw_service(
+ l2gwlib.plug_l2_gw_service(
self.cluster,
port_data['network_id'],
lport['uuid'],
except Exception:
with excutils.save_and_reraise_exception():
if lport:
- nvplib.delete_port(self.cluster,
- selected_lswitch['uuid'],
- lport['uuid'])
+ switchlib.delete_port(self.cluster,
+ selected_lswitch['uuid'],
+ lport['uuid'])
LOG.debug(_("_nvp_create_l2_gw_port completed for port %(name)s "
"on network %(network_id)s. The new port id "
"is %(id)s."), port_data)
# The tag must therefore be added.
tags = main_ls['tags']
tags.append({'tag': 'True', 'scope': 'multi_lswitch'})
- nvplib.update_lswitch(cluster,
- main_ls['uuid'],
- main_ls['display_name'],
- network['tenant_id'],
- tags=tags)
+ switchlib.update_lswitch(cluster,
+ main_ls['uuid'],
+ main_ls['display_name'],
+ network['tenant_id'],
+ tags=tags)
transport_zone_config = self._convert_to_nvp_transport_zones(
cluster, network, bindings=network_bindings)
- selected_lswitch = nvplib.create_lswitch(
+ selected_lswitch = switchlib.create_lswitch(
cluster, network.id, network.tenant_id,
"%s-ext-%s" % (network.name, len(lswitches)),
transport_zone_config)
net_data['id'] = str(uuid.uuid4())
if (not attr.is_attr_set(external) or
attr.is_attr_set(external) and not external):
- lswitch = nvplib.create_lswitch(
+ lswitch = switchlib.create_lswitch(
self.cluster, net_data['id'],
tenant_id, net_data.get('name'),
transport_zone_config,
# Do not go to NVP for external networks
if not external:
try:
- nvplib.delete_networks(self.cluster, id, lswitch_ids)
+ switchlib.delete_networks(self.cluster, id, lswitch_ids)
LOG.debug(_("delete_network completed for tenant: %s"),
context.tenant_id)
except q_exc.NotFound:
self._process_port_queue_mapping(context, ret_port,
port_queue_id)
LOG.warn(_("Update port request: %s"), port)
- nvp_switch_id, nvp_port_id = nsx_utils.get_nsx_switch_and_port_id(
+ nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
context.session, self.cluster, id)
- if nvp_port_id:
+ if nsx_port_id:
try:
- nvplib.update_port(self.cluster,
- nvp_switch_id,
- nvp_port_id, id, tenant_id,
- ret_port['name'], ret_port['device_id'],
- ret_port['admin_state_up'],
- ret_port['mac_address'],
- ret_port['fixed_ips'],
- ret_port[psec.PORTSECURITY],
- ret_port[ext_sg.SECURITYGROUPS],
- ret_port[ext_qos.QUEUE],
- ret_port.get(mac_ext.MAC_LEARNING),
- ret_port.get(addr_pair.ADDRESS_PAIRS))
+ switchlib.update_port(
+ self.cluster,
+ nsx_switch_id, nsx_port_id, id, tenant_id,
+ ret_port['name'],
+ ret_port['device_id'],
+ ret_port['admin_state_up'],
+ ret_port['mac_address'],
+ ret_port['fixed_ips'],
+ ret_port[psec.PORTSECURITY],
+ ret_port[ext_sg.SECURITYGROUPS],
+ ret_port[ext_qos.QUEUE],
+ ret_port.get(mac_ext.MAC_LEARNING),
+ ret_port.get(addr_pair.ADDRESS_PAIRS))
# Update the port status from nvp. If we fail here hide it
# since the port was successfully updated but we were not
# able to retrieve the status.
- ret_port['status'] = nvplib.get_port_status(
+ ret_port['status'] = switchlib.get_port_status(
self.cluster, ret_port['network_id'],
- nvp_port_id)
+ nsx_port_id)
# FIXME(arosen) improve exception handling.
except Exception:
ret_port['status'] = constants.PORT_STATUS_ERROR
LOG.exception(_("Unable to update port id: %s."),
- nvp_port_id)
+ nsx_port_id)
# If nvp_port_id is not in database or in nvp put in error state.
else:
context.session, self.cluster, router_id)
if port_id:
port_data = self._get_port(context, port_id)
- nvp_switch_id, nvp_port_id = nsx_utils.get_nsx_switch_and_port_id(
+ nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
context.session, self.cluster, port_id)
# Unplug current attachment from lswitch port
- nvplib.plug_interface(self.cluster, nvp_switch_id,
- nvp_port_id, "NoAttachment")
+ switchlib.plug_interface(self.cluster, nsx_switch_id,
+ nsx_port_id, "NoAttachment")
# Create logical router port and plug patch attachment
self._create_and_attach_router_port(
self.cluster, context, nsx_router_id, port_data,
- "PatchAttachment", nvp_port_id, subnet_ids=[subnet_id])
+ "PatchAttachment", nsx_port_id, subnet_ids=[subnet_id])
subnet = self._get_subnet(context, subnet_id)
# If there is an external gateway we need to configure the SNAT rule.
# Fetch router from DB
if not device.get('interface_name'):
device['interface_name'] = self.cluster.default_interface_name
try:
- nvp_res = nvplib.create_l2_gw_service(self.cluster, tenant_id,
- gw_data['name'], devices)
- nvp_uuid = nvp_res.get('uuid')
+ nsx_res = l2gwlib.create_l2_gw_service(
+ self.cluster, tenant_id, gw_data['name'], devices)
+ nsx_uuid = nsx_res.get('uuid')
except NvpApiClient.Conflict:
raise nvp_exc.NvpL2GatewayAlreadyInUse(gateway=gw_data['name'])
except NvpApiClient.NvpApiException:
err_msg = _("Unable to create l2_gw_service for: %s") % gw_data
LOG.exception(err_msg)
raise nvp_exc.NvpPluginException(err_msg=err_msg)
- gw_data['id'] = nvp_uuid
+ gw_data['id'] = nsx_uuid
return super(NvpPluginV2, self).create_network_gateway(context,
network_gateway)
- def delete_network_gateway(self, context, id):
+ def delete_network_gateway(self, context, gateway_id):
"""Remove a layer-2 network gateway.
Remove the gateway service from NVP platform and corresponding data
self._ensure_default_network_gateway()
with context.session.begin(subtransactions=True):
try:
- super(NvpPluginV2, self).delete_network_gateway(context, id)
- nvplib.delete_l2_gw_service(self.cluster, id)
+ super(NvpPluginV2, self).delete_network_gateway(
+ context, gateway_id)
+ l2gwlib.delete_l2_gw_service(self.cluster, gateway_id)
except NvpApiClient.ResourceNotFound:
# Do not cause a 500 to be returned to the user if
# the corresponding NVP resource does not exist
name = network_gateway[networkgw.RESOURCE_NAME].get('name')
if name:
try:
- nvplib.update_l2_gw_service(self.cluster, id, name)
+ l2gwlib.update_l2_gw_service(self.cluster, id, name)
except NvpApiClient.NvpApiException:
# Consider backend failures as non-fatal, but still warn
# because this might indicate something dodgy is going on
from neutron.plugins.nicira.extensions import servicerouter as sr
from neutron.plugins.nicira import NeutronPlugin
from neutron.plugins.nicira.nsxlib import router as routerlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
from neutron.plugins.nicira import NvpApiClient
from neutron.plugins.nicira import nvplib
from neutron.plugins.nicira.vshield.common import (
# load the vCNS driver
self._load_vcns_drivers()
- # nvplib's create_lswitch needs to be replaced in order to proxy
+ # switchlib's create_lswitch needs to be replaced in order to proxy
# logical switch create requests to vcns
self._set_create_lswitch_proxy()
def _set_create_lswitch_proxy(self):
- NeutronPlugin.nvplib.create_lswitch = self._proxy_create_lswitch
+ NeutronPlugin.switchlib.create_lswitch = self._proxy_create_lswitch
def _proxy_create_lswitch(self, *args, **kwargs):
name, tz_config, tags = (
lrouter, lswitch):
# create logic switch port
try:
- ls_port = nvplib.create_lport(
+ ls_port = switchlib.create_lport(
self.cluster, lswitch['uuid'], tenant_id,
'', '', lrouter['uuid'], True)
except NvpApiClient.NvpApiException:
except NvpApiClient.NvpApiException:
msg = (_("Unable to create port on NVP logical router %s") % name)
LOG.exception(msg)
- nvplib.delete_port(self.cluster, lswitch['uuid'], ls_port['uuid'])
+ switchlib.delete_port(
+ self.cluster, lswitch['uuid'], ls_port['uuid'])
raise q_exc.NeutronException(message=msg)
# attach logic router port to switch port
'PatchAttachment', ls_port['uuid'], None)
except NvpApiClient.NvpApiException as e:
# lr_port should have been deleted
- nvplib.delete_port(self.cluster, lswitch['uuid'], ls_port['uuid'])
+ switchlib.delete_port(
+ self.cluster, lswitch['uuid'], ls_port['uuid'])
raise e
def _create_lrouter(self, context, router, nexthop):
from neutron.plugins.nicira.dbexts import nicira_db
from neutron.plugins.nicira import nsx_cluster
from neutron.plugins.nicira.nsxlib import router as routerlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
from neutron.plugins.nicira import NvpApiClient
-from neutron.plugins.nicira import nvplib
LOG = log.getLogger(__name__)
"""
nsx_switch_ids = get_nsx_switch_ids(session, cluster, neutron_net_id)
if len(nsx_switch_ids) > 1:
- lswitches = nvplib.get_lswitches(cluster, neutron_net_id)
+ lswitches = switchlib.get_lswitches(cluster, neutron_net_id)
else:
- lswitches = [nvplib.get_lswitch_by_id(
+ lswitches = [switchlib.get_lswitch_by_id(
cluster, nsx_switch_ids[0])]
return lswitches
# Find logical switches from backend.
# This is a rather expensive query, but it won't be executed
# more than once for each network in Neutron's lifetime
- nsx_switches = nvplib.get_lswitches(cluster, neutron_network_id)
+ nsx_switches = switchlib.get_lswitches(cluster, neutron_network_id)
if not nsx_switches:
LOG.warn(_("Unable to find NSX switches for Neutron network %s"),
neutron_network_id)
the backend logical switch identifier is equal to the neutron
network identifier.
"""
- nvp_switch_id, nvp_port_id = nicira_db.get_nsx_switch_and_port_id(
+ nsx_switch_id, nsx_port_id = nicira_db.get_nsx_switch_and_port_id(
session, neutron_port_id)
- if not nvp_switch_id:
+ if not nsx_switch_id:
# Find logical switch for port from backend
# This is a rather expensive query, but it won't be executed
# more than once for each port in Neutron's lifetime
- nvp_ports = nvplib.query_lswitch_lports(
+ nsx_ports = switchlib.query_lswitch_lports(
cluster, '*', relations='LogicalSwitchConfig',
filters={'tag': neutron_port_id,
'tag_scope': 'q_port_id'})
# Only one result expected
# NOTE(salv-orlando): Not handling the case where more than one
# port is found with the same neutron port tag
- if not nvp_ports:
- LOG.warn(_("Unable to find NVP port for Neutron port %s"),
+ if not nsx_ports:
+ LOG.warn(_("Unable to find NSX port for Neutron port %s"),
neutron_port_id)
# This method is supposed to return a tuple
return None, None
- nvp_port = nvp_ports[0]
- nvp_switch_id = (nvp_port['_relations']
+ nsx_port = nsx_ports[0]
+ nsx_switch_id = (nsx_port['_relations']
['LogicalSwitchConfig']['uuid'])
- if nvp_port_id:
+ if nsx_port_id:
# Mapping already exists. Delete before recreating
nicira_db.delete_neutron_nsx_port_mapping(
session, neutron_port_id)
else:
- nvp_port_id = nvp_port['uuid']
+ nsx_port_id = nsx_port['uuid']
# (re)Create DB mapping
nicira_db.add_neutron_nsx_port_mapping(
session, neutron_port_id,
- nvp_switch_id, nvp_port_id)
- return nvp_switch_id, nvp_port_id
+ nsx_switch_id, nsx_port_id)
+ return nsx_switch_id, nsx_port_id
def create_nsx_cluster(cluster_opts, concurrent_connections, nsx_gen_timeout):
from neutron.plugins.nicira.common import exceptions as nvp_exc
from neutron.plugins.nicira.common import nsx_utils
from neutron.plugins.nicira.nsxlib import router as routerlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
from neutron.plugins.nicira import NvpApiClient
from neutron.plugins.nicira import nvplib
ls_uuid, lp_uuid = nsx_utils.get_nsx_switch_and_port_id(
context.session, self._cluster, neutron_port_data['id'])
if lp_uuid:
- lswitchport = nvplib.get_port(
+ lswitchport = switchlib.get_port(
self._cluster, ls_uuid, lp_uuid,
relations='LogicalPortStatus')
except (exceptions.PortNotFoundOnNetwork):
# License for the specific language governing permissions and limitations
# under the License.
+import hashlib
+
from neutron.api.v2.attributes import is_attr_set
from neutron.openstack.common import log
from neutron.version import version_info
return tags
+def device_id_to_vm_id(device_id, obfuscate=False):
+ # device_id can be longer than 40 characters, for example
+ # a device_id for a dhcp port is like the following:
+ #
+ # dhcp83b5fdeb-e3b4-5e18-ac5f-55161...80747326-47d7-46c2-a87a-cf6d5194877c
+ #
+ # To fit it into an NSX tag we need to hash it, however device_id
+ # used for ports associated to VM's are small enough so let's skip the
+ # hashing
+ if len(device_id) > MAX_DISPLAY_NAME_LEN or obfuscate:
+ return hashlib.sha1(device_id).hexdigest()
+ else:
+ return device_id
+
+
def check_and_truncate(display_name):
if is_attr_set(display_name) and len(display_name) > MAX_DISPLAY_NAME_LEN:
LOG.debug(_("Specified name:'%s' exceeds maximum length. "
- "It will be truncated on NVP"), display_name)
+ "It will be truncated on NSX"), display_name)
return display_name[:MAX_DISPLAY_NAME_LEN]
return display_name or ''
from neutron.plugins.nicira.dbexts import lsn_db
from neutron.plugins.nicira.dhcp_meta import constants as const
from neutron.plugins.nicira.nsxlib import lsn as lsn_api
+from neutron.plugins.nicira.nsxlib import switch as switch_api
from neutron.plugins.nicira import nvplib as nsxlib
LOG = logging.getLogger(__name__)
self.lsn_port_delete(context, lsn_id, lsn_port_id)
if mac_address == const.METADATA_MAC:
try:
- lswitch_port_id = nsxlib.get_port_by_neutron_tag(
+ lswitch_port_id = switch_api.get_port_by_neutron_tag(
self.cluster, network_id,
const.METADATA_PORT_ID)['uuid']
- nsxlib.delete_port(
+ switch_api.delete_port(
self.cluster, network_id, lswitch_port_id)
except (n_exc.PortNotFoundOnNetwork,
- nsxlib.NvpApiClient.NvpApiException):
+ switch_api.NvpApiClient.NvpApiException):
LOG.warn(_("Metadata port not found while attempting "
"to delete it from network %s"), network_id)
else:
"""Connect network to LSN via specified port and port_data."""
try:
lsn_id = None
- lswitch_port_id = nsxlib.get_port_by_neutron_tag(
+ lswitch_port_id = switch_api.get_port_by_neutron_tag(
self.cluster, network_id, port_id)['uuid']
lsn_id = self.lsn_get(context, network_id)
lsn_port_id = self.lsn_port_create(context, lsn_id, port_data)
tenant_id = subnet['tenant_id']
lswitch_port_id = None
try:
- lswitch_port_id = nsxlib.create_lport(
+ lswitch_port_id = switch_api.create_lport(
self.cluster, network_id, tenant_id,
const.METADATA_PORT_ID, const.METADATA_PORT_NAME,
const.METADATA_DEVICE_ID, True)['uuid']
self.cluster, lsn_id, lsn_port_id, lswitch_port_id)
except p_exc.LsnConfigurationConflict:
self.lsn_port_delete(self.cluster, lsn_id, lsn_port_id)
- nsxlib.delete_port(self.cluster, network_id, lswitch_port_id)
+ switch_api.delete_port(
+ self.cluster, network_id, lswitch_port_id)
raise p_exc.PortConfigurationError(
net_id=network_id, lsn_id=lsn_id, port_id=lsn_port_id)
--- /dev/null
+# Copyright 2014 VMware, Inc.
+# All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import json
+
+from neutron.openstack.common import log
+from neutron.plugins.nicira.common import utils
+from neutron.plugins.nicira.nvplib import _build_uri_path
+from neutron.plugins.nicira.nvplib import _plug_interface
+from neutron.plugins.nicira.nvplib import do_request
+from neutron.plugins.nicira.nvplib import get_all_query_pages
+
+HTTP_GET = "GET"
+HTTP_POST = "POST"
+HTTP_DELETE = "DELETE"
+HTTP_PUT = "PUT"
+
+GWSERVICE_RESOURCE = "gateway-service"
+
+LOG = log.getLogger(__name__)
+
+
+def create_l2_gw_service(cluster, tenant_id, display_name, devices):
+ """Create a NSX Layer-2 Network Gateway Service.
+
+ :param cluster: The target NSX cluster
+ :param tenant_id: Identifier of the Openstack tenant for which
+ the gateway service.
+ :param display_name: Descriptive name of this gateway service
+ :param devices: List of transport node uuids (and network
+ interfaces on them) to use for the network gateway service
+ :raise NvpApiException: if there is a problem while communicating
+ with the NSX controller
+ """
+ # NOTE(salvatore-orlando): This is a little confusing, but device_id in
+ # NSX is actually the identifier a physical interface on the gateway
+ # device, which in the Neutron API is referred as interface_name
+ gateways = [{"transport_node_uuid": device['id'],
+ "device_id": device['interface_name'],
+ "type": "L2Gateway"} for device in devices]
+ gwservice_obj = {
+ "display_name": utils.check_and_truncate(display_name),
+ "tags": utils.get_tags(os_tid=tenant_id),
+ "gateways": gateways,
+ "type": "L2GatewayServiceConfig"
+ }
+ return do_request(
+ "POST", _build_uri_path(GWSERVICE_RESOURCE),
+ json.dumps(gwservice_obj), cluster=cluster)
+
+
+def plug_l2_gw_service(cluster, lswitch_id, lport_id,
+ gateway_id, vlan_id=None):
+ """Plug a Layer-2 Gateway Attachment object in a logical port."""
+ att_obj = {'type': 'L2GatewayAttachment',
+ 'l2_gateway_service_uuid': gateway_id}
+ if vlan_id:
+ att_obj['vlan_id'] = vlan_id
+ return _plug_interface(cluster, lswitch_id, lport_id, att_obj)
+
+
+def get_l2_gw_service(cluster, gateway_id):
+ return do_request(
+ "GET", _build_uri_path(GWSERVICE_RESOURCE,
+ resource_id=gateway_id),
+ cluster=cluster)
+
+
+def get_l2_gw_services(cluster, tenant_id=None,
+ fields=None, filters=None):
+ actual_filters = dict(filters or {})
+ if tenant_id:
+ actual_filters['tag'] = tenant_id
+ actual_filters['tag_scope'] = 'os_tid'
+ return get_all_query_pages(
+ _build_uri_path(GWSERVICE_RESOURCE,
+ filters=actual_filters),
+ cluster)
+
+
+def update_l2_gw_service(cluster, gateway_id, display_name):
+ # TODO(salvatore-orlando): Allow updates for gateways too
+ gwservice_obj = get_l2_gw_service(cluster, gateway_id)
+ if not display_name:
+ # Nothing to update
+ return gwservice_obj
+ gwservice_obj["display_name"] = utils.check_and_truncate(display_name)
+ return do_request("PUT", _build_uri_path(GWSERVICE_RESOURCE,
+ resource_id=gateway_id),
+ json.dumps(gwservice_obj), cluster=cluster)
+
+
+def delete_l2_gw_service(cluster, gateway_id):
+ do_request("DELETE", _build_uri_path(GWSERVICE_RESOURCE,
+ resource_id=gateway_id),
+ cluster=cluster)
from neutron.openstack.common import log
from neutron.plugins.nicira.common import exceptions as nvp_exc
from neutron.plugins.nicira.common import utils
+from neutron.plugins.nicira.nsxlib.switch import get_port
from neutron.plugins.nicira.nsxlib.versioning import DEFAULT_VERSION
from neutron.plugins.nicira.nsxlib.versioning import versioned
from neutron.plugins.nicira import NvpApiClient
from neutron.plugins.nicira.nvplib import _build_uri_path
from neutron.plugins.nicira.nvplib import do_request
from neutron.plugins.nicira.nvplib import get_all_query_pages
-from neutron.plugins.nicira.nvplib import get_port
HTTP_GET = "GET"
HTTP_POST = "POST"
--- /dev/null
+# Copyright 2014 VMware, Inc.
+# All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+import json
+
+from neutron.common import constants
+from neutron.common import exceptions as exception
+from neutron.openstack.common import log
+from neutron.plugins.nicira.common import exceptions as nvp_exc
+from neutron.plugins.nicira.common import utils
+from neutron.plugins.nicira import NvpApiClient
+from neutron.plugins.nicira.nvplib import _build_uri_path
+from neutron.plugins.nicira.nvplib import _plug_interface
+from neutron.plugins.nicira.nvplib import do_request
+from neutron.plugins.nicira.nvplib import get_all_query_pages
+
+HTTP_GET = "GET"
+HTTP_POST = "POST"
+HTTP_DELETE = "DELETE"
+HTTP_PUT = "PUT"
+
+LSWITCH_RESOURCE = "lswitch"
+LSWITCHPORT_RESOURCE = "lport/%s" % LSWITCH_RESOURCE
+
+LOG = log.getLogger(__name__)
+
+
+def _configure_extensions(lport_obj, mac_address, fixed_ips,
+ port_security_enabled, security_profiles,
+ queue_id, mac_learning_enabled,
+ allowed_address_pairs):
+ lport_obj['allowed_address_pairs'] = []
+ if port_security_enabled:
+ for fixed_ip in fixed_ips:
+ ip_address = fixed_ip.get('ip_address')
+ if ip_address:
+ lport_obj['allowed_address_pairs'].append(
+ {'mac_address': mac_address, 'ip_address': ip_address})
+ # add address pair allowing src_ip 0.0.0.0 to leave
+ # this is required for outgoing dhcp request
+ lport_obj["allowed_address_pairs"].append(
+ {"mac_address": mac_address,
+ "ip_address": "0.0.0.0"})
+ lport_obj['security_profiles'] = list(security_profiles or [])
+ lport_obj['queue_uuid'] = queue_id
+ if mac_learning_enabled is not None:
+ lport_obj["mac_learning"] = mac_learning_enabled
+ lport_obj["type"] = "LogicalSwitchPortConfig"
+ for address_pair in list(allowed_address_pairs or []):
+ lport_obj['allowed_address_pairs'].append(
+ {'mac_address': address_pair['mac_address'],
+ 'ip_address': address_pair['ip_address']})
+
+
+def get_lswitch_by_id(cluster, lswitch_id):
+ try:
+ lswitch_uri_path = _build_uri_path(
+ LSWITCH_RESOURCE, lswitch_id,
+ relations="LogicalSwitchStatus")
+ return do_request(HTTP_GET, lswitch_uri_path, cluster=cluster)
+ except exception.NotFound:
+ # FIXME(salv-orlando): this should not raise a neutron exception
+ raise exception.NetworkNotFound(net_id=lswitch_id)
+
+
+def get_lswitches(cluster, neutron_net_id):
+
+ def lookup_switches_by_tag():
+ # Fetch extra logical switches
+ lswitch_query_path = _build_uri_path(
+ LSWITCH_RESOURCE,
+ fields="uuid,display_name,tags,lport_count",
+ relations="LogicalSwitchStatus",
+ filters={'tag': neutron_net_id,
+ 'tag_scope': 'quantum_net_id'})
+ return get_all_query_pages(lswitch_query_path, cluster)
+
+ lswitch_uri_path = _build_uri_path(LSWITCH_RESOURCE, neutron_net_id,
+ relations="LogicalSwitchStatus")
+ results = []
+ try:
+ ls = do_request(HTTP_GET, lswitch_uri_path, cluster=cluster)
+ results.append(ls)
+ for tag in ls['tags']:
+ if (tag['scope'] == "multi_lswitch" and
+ tag['tag'] == "True"):
+ results.extend(lookup_switches_by_tag())
+ except exception.NotFound:
+ # This is legit if the neutron network was created using
+ # a post-Havana version of the plugin
+ results.extend(lookup_switches_by_tag())
+ if results:
+ return results
+ else:
+ raise exception.NetworkNotFound(net_id=neutron_net_id)
+
+
+def create_lswitch(cluster, neutron_net_id, tenant_id, display_name,
+ transport_zones_config,
+ shared=None,
+ **kwargs):
+ # The tag scope adopts a slightly different naming convention for
+ # historical reasons
+ lswitch_obj = {"display_name": utils.check_and_truncate(display_name),
+ "transport_zones": transport_zones_config,
+ "tags": utils.get_tags(os_tid=tenant_id,
+ quantum_net_id=neutron_net_id)}
+ # TODO(salv-orlando): Now that we have async status synchronization
+ # this tag is perhaps not needed anymore
+ if shared:
+ lswitch_obj["tags"].append({"tag": "true",
+ "scope": "shared"})
+ if "tags" in kwargs:
+ lswitch_obj["tags"].extend(kwargs["tags"])
+ uri = _build_uri_path(LSWITCH_RESOURCE)
+ lswitch = do_request(HTTP_POST, uri, json.dumps(lswitch_obj),
+ cluster=cluster)
+ LOG.debug(_("Created logical switch: %s"), lswitch['uuid'])
+ return lswitch
+
+
+def update_lswitch(cluster, lswitch_id, display_name,
+ tenant_id=None, **kwargs):
+ uri = _build_uri_path(LSWITCH_RESOURCE, resource_id=lswitch_id)
+ lswitch_obj = {"display_name": utils.check_and_truncate(display_name),
+ "tags": utils.get_tags(os_tid=tenant_id)}
+ if "tags" in kwargs:
+ lswitch_obj["tags"].extend(kwargs["tags"])
+ try:
+ return do_request(HTTP_PUT, uri, json.dumps(lswitch_obj),
+ cluster=cluster)
+ except exception.NotFound as e:
+ LOG.error(_("Network not found, Error: %s"), str(e))
+ raise exception.NetworkNotFound(net_id=lswitch_id)
+
+
+def delete_network(cluster, net_id, lswitch_id):
+ delete_networks(cluster, net_id, [lswitch_id])
+
+
+#TODO(salvatore-orlando): Simplify and harmonize
+def delete_networks(cluster, net_id, lswitch_ids):
+ for ls_id in lswitch_ids:
+ path = "/ws.v1/lswitch/%s" % ls_id
+ try:
+ do_request(HTTP_DELETE, path, cluster=cluster)
+ except exception.NotFound as e:
+ LOG.error(_("Network not found, Error: %s"), str(e))
+ raise exception.NetworkNotFound(net_id=ls_id)
+
+
+def query_lswitch_lports(cluster, ls_uuid, fields="*",
+ filters=None, relations=None):
+ # Fix filter for attachments
+ if filters and "attachment" in filters:
+ filters['attachment_vif_uuid'] = filters["attachment"]
+ del filters['attachment']
+ uri = _build_uri_path(LSWITCHPORT_RESOURCE, parent_resource_id=ls_uuid,
+ fields=fields, filters=filters, relations=relations)
+ return do_request(HTTP_GET, uri, cluster=cluster)['results']
+
+
+def delete_port(cluster, switch, port):
+ uri = "/ws.v1/lswitch/" + switch + "/lport/" + port
+ try:
+ do_request(HTTP_DELETE, uri, cluster=cluster)
+ except exception.NotFound:
+ LOG.exception(_("Port or Network not found"))
+ raise exception.PortNotFoundOnNetwork(
+ net_id=switch, port_id=port)
+ except NvpApiClient.NvpApiException:
+ raise exception.NeutronException()
+
+
+def get_ports(cluster, networks=None, devices=None, tenants=None):
+ vm_filter_obsolete = ""
+ vm_filter = ""
+ tenant_filter = ""
+ # This is used when calling delete_network. Neutron checks to see if
+ # the network has any ports.
+ if networks:
+ # FIXME (Aaron) If we get more than one network_id this won't work
+ lswitch = networks[0]
+ else:
+ lswitch = "*"
+ if devices:
+ for device_id in devices:
+ vm_filter_obsolete = '&'.join(
+ ["tag_scope=vm_id",
+ "tag=%s" % utils.device_id_to_vm_id(device_id,
+ obfuscate=True),
+ vm_filter_obsolete])
+ vm_filter = '&'.join(
+ ["tag_scope=vm_id",
+ "tag=%s" % utils.device_id_to_vm_id(device_id),
+ vm_filter])
+ if tenants:
+ for tenant in tenants:
+ tenant_filter = '&'.join(
+ ["tag_scope=os_tid",
+ "tag=%s" % tenant,
+ tenant_filter])
+
+ nsx_lports = {}
+ lport_fields_str = ("tags,admin_status_enabled,display_name,"
+ "fabric_status_up")
+ try:
+ lport_query_path_obsolete = (
+ "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id"
+ "&relations=LogicalPortStatus" %
+ (lswitch, lport_fields_str, vm_filter_obsolete, tenant_filter))
+ lport_query_path = (
+ "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id"
+ "&relations=LogicalPortStatus" %
+ (lswitch, lport_fields_str, vm_filter, tenant_filter))
+ try:
+ # NOTE(armando-migliaccio): by querying with obsolete tag first
+ # current deployments won't take the performance hit of a double
+ # call. In release L-** or M-**, we might want to swap the calls
+ # as it's likely that ports with the new tag would outnumber the
+ # ones with the old tag
+ ports = get_all_query_pages(lport_query_path_obsolete, cluster)
+ if not ports:
+ ports = get_all_query_pages(lport_query_path, cluster)
+ except exception.NotFound:
+ LOG.warn(_("Lswitch %s not found in NSX"), lswitch)
+ ports = None
+
+ if ports:
+ for port in ports:
+ for tag in port["tags"]:
+ if tag["scope"] == "q_port_id":
+ nsx_lports[tag["tag"]] = port
+ except Exception:
+ err_msg = _("Unable to get ports")
+ LOG.exception(err_msg)
+ raise nvp_exc.NvpPluginException(err_msg=err_msg)
+ return nsx_lports
+
+
+def get_port_by_neutron_tag(cluster, lswitch_uuid, neutron_port_id):
+ """Get port by neutron tag.
+
+ Returns the NSX UUID of the logical port with tag q_port_id equal to
+ neutron_port_id or None if the port is not Found.
+ """
+ uri = _build_uri_path(LSWITCHPORT_RESOURCE,
+ parent_resource_id=lswitch_uuid,
+ fields='uuid',
+ filters={'tag': neutron_port_id,
+ 'tag_scope': 'q_port_id'})
+ LOG.debug(_("Looking for port with q_port_id tag '%(neutron_port_id)s' "
+ "on: '%(lswitch_uuid)s'"),
+ {'neutron_port_id': neutron_port_id,
+ 'lswitch_uuid': lswitch_uuid})
+ res = do_request(HTTP_GET, uri, cluster=cluster)
+ num_results = len(res["results"])
+ if num_results >= 1:
+ if num_results > 1:
+ LOG.warn(_("Found '%(num_ports)d' ports with "
+ "q_port_id tag: '%(neutron_port_id)s'. "
+ "Only 1 was expected."),
+ {'num_ports': num_results,
+ 'neutron_port_id': neutron_port_id})
+ return res["results"][0]
+
+
+def get_port(cluster, network, port, relations=None):
+ LOG.info(_("get_port() %(network)s %(port)s"),
+ {'network': network, 'port': port})
+ uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "?"
+ if relations:
+ uri += "relations=%s" % relations
+ try:
+ return do_request(HTTP_GET, uri, cluster=cluster)
+ except exception.NotFound as e:
+ LOG.error(_("Port or Network not found, Error: %s"), str(e))
+ raise exception.PortNotFoundOnNetwork(
+ port_id=port, net_id=network)
+
+
+def update_port(cluster, lswitch_uuid, lport_uuid, neutron_port_id, tenant_id,
+ display_name, device_id, admin_status_enabled,
+ mac_address=None, fixed_ips=None, port_security_enabled=None,
+ security_profiles=None, queue_id=None,
+ mac_learning_enabled=None, allowed_address_pairs=None):
+ lport_obj = dict(
+ admin_status_enabled=admin_status_enabled,
+ display_name=utils.check_and_truncate(display_name),
+ tags=utils.get_tags(os_tid=tenant_id,
+ q_port_id=neutron_port_id,
+ vm_id=utils.device_id_to_vm_id(device_id)))
+
+ _configure_extensions(lport_obj, mac_address, fixed_ips,
+ port_security_enabled, security_profiles,
+ queue_id, mac_learning_enabled,
+ allowed_address_pairs)
+
+ path = "/ws.v1/lswitch/" + lswitch_uuid + "/lport/" + lport_uuid
+ try:
+ result = do_request(HTTP_PUT, path, json.dumps(lport_obj),
+ cluster=cluster)
+ LOG.debug(_("Updated logical port %(result)s "
+ "on logical switch %(uuid)s"),
+ {'result': result['uuid'], 'uuid': lswitch_uuid})
+ return result
+ except exception.NotFound as e:
+ LOG.error(_("Port or Network not found, Error: %s"), str(e))
+ raise exception.PortNotFoundOnNetwork(
+ port_id=lport_uuid, net_id=lswitch_uuid)
+
+
+def create_lport(cluster, lswitch_uuid, tenant_id, neutron_port_id,
+ display_name, device_id, admin_status_enabled,
+ mac_address=None, fixed_ips=None, port_security_enabled=None,
+ security_profiles=None, queue_id=None,
+ mac_learning_enabled=None, allowed_address_pairs=None):
+ """Creates a logical port on the assigned logical switch."""
+ display_name = utils.check_and_truncate(display_name)
+ lport_obj = dict(
+ admin_status_enabled=admin_status_enabled,
+ display_name=display_name,
+ tags=utils.get_tags(os_tid=tenant_id,
+ q_port_id=neutron_port_id,
+ vm_id=utils.device_id_to_vm_id(device_id))
+ )
+
+ _configure_extensions(lport_obj, mac_address, fixed_ips,
+ port_security_enabled, security_profiles,
+ queue_id, mac_learning_enabled,
+ allowed_address_pairs)
+
+ path = _build_uri_path(LSWITCHPORT_RESOURCE,
+ parent_resource_id=lswitch_uuid)
+ result = do_request(HTTP_POST, path, json.dumps(lport_obj),
+ cluster=cluster)
+
+ LOG.debug(_("Created logical port %(result)s on logical switch %(uuid)s"),
+ {'result': result['uuid'], 'uuid': lswitch_uuid})
+ return result
+
+
+def get_port_status(cluster, lswitch_id, port_id):
+ """Retrieve the operational status of the port."""
+ try:
+ r = do_request(HTTP_GET,
+ "/ws.v1/lswitch/%s/lport/%s/status" %
+ (lswitch_id, port_id), cluster=cluster)
+ except exception.NotFound as e:
+ LOG.error(_("Port not found, Error: %s"), str(e))
+ raise exception.PortNotFoundOnNetwork(
+ port_id=port_id, net_id=lswitch_id)
+ if r['link_status_up'] is True:
+ return constants.PORT_STATUS_ACTIVE
+ else:
+ return constants.PORT_STATUS_DOWN
+
+
+def plug_interface(cluster, lswitch_id, port, port_type, attachment=None):
+ """Plug a VIF Attachment object in a logical port."""
+ lport_obj = {}
+ if attachment:
+ lport_obj["vif_uuid"] = attachment
+
+ lport_obj["type"] = port_type
+ return _plug_interface(cluster, lswitch_id, port, lport_obj)
# @author: Aaron Rosen, Nicira Networks, Inc.
-import hashlib
import json
#FIXME(danwent): I'd like this file to get to the point where it has
HTTP_PUT = "PUT"
# Prefix to be used for all NVP API calls
URI_PREFIX = "/ws.v1"
-# Resources exposed by NVP API
+
LSWITCH_RESOURCE = "lswitch"
LSWITCHPORT_RESOURCE = "lport/%s" % LSWITCH_RESOURCE
-GWSERVICE_RESOURCE = "gateway-service"
+
# Current neutron version
NEUTRON_VERSION = version_info.release_string()
# limit be raised in future versions
MAX_PAGE_SIZE = 5000
-# TODO(bgh): it would be more efficient to use a bitmap
-taken_context_ids = []
-
-# XXX Only cache default for now
-_lqueue_cache = {}
-
-
-def device_id_to_vm_id(device_id, obfuscate=False):
- # device_id can be longer than 40 characters, for example
- # a device_id for a dhcp port is like the following:
- #
- # dhcp83b5fdeb-e3b4-5e18-ac5f-55161...80747326-47d7-46c2-a87a-cf6d5194877c
- #
- # To fit it into an NVP tag we need to hash it, however device_id
- # used for ports associated to VM's are small enough so let's skip the
- # hashing
- if len(device_id) > utils.MAX_DISPLAY_NAME_LEN or obfuscate:
- return hashlib.sha1(device_id).hexdigest()
- else:
- return device_id
-
def _build_uri_path(resource,
resource_id=None,
return result_list
-# -------------------------------------------------------------------
-# Network functions
-# -------------------------------------------------------------------
-def get_lswitch_by_id(cluster, lswitch_id):
- try:
- lswitch_uri_path = _build_uri_path(
- LSWITCH_RESOURCE, lswitch_id,
- relations="LogicalSwitchStatus")
- return do_request(HTTP_GET, lswitch_uri_path, cluster=cluster)
- except exception.NotFound:
- # FIXME(salv-orlando): this should not raise a neutron exception
- raise exception.NetworkNotFound(net_id=lswitch_id)
-
-
-def get_lswitches(cluster, neutron_net_id):
-
- def lookup_switches_by_tag():
- # Fetch extra logical switches
- lswitch_query_path = _build_uri_path(
- LSWITCH_RESOURCE,
- fields="uuid,display_name,tags,lport_count",
- relations="LogicalSwitchStatus",
- filters={'tag': neutron_net_id,
- 'tag_scope': 'quantum_net_id'})
- return get_all_query_pages(lswitch_query_path, cluster)
-
- lswitch_uri_path = _build_uri_path(LSWITCH_RESOURCE, neutron_net_id,
- relations="LogicalSwitchStatus")
- results = []
- try:
- ls = do_request(HTTP_GET, lswitch_uri_path, cluster=cluster)
- results.append(ls)
- for tag in ls['tags']:
- if (tag['scope'] == "multi_lswitch" and
- tag['tag'] == "True"):
- results.extend(lookup_switches_by_tag())
- except exception.NotFound:
- # This is legit if the neutron network was created using
- # a post-Havana version of the plugin
- results.extend(lookup_switches_by_tag())
- if results:
- return results
- else:
- raise exception.NetworkNotFound(net_id=neutron_net_id)
-
-
-def create_lswitch(cluster, neutron_net_id, tenant_id, display_name,
- transport_zones_config,
- shared=None,
- **kwargs):
- # The tag scope adopts a slightly different naming convention for
- # historical reasons
- lswitch_obj = {"display_name": utils.check_and_truncate(display_name),
- "transport_zones": transport_zones_config,
- "tags": [{"tag": tenant_id, "scope": "os_tid"},
- {"tag": neutron_net_id, "scope": "quantum_net_id"},
- {"tag": NEUTRON_VERSION, "scope": "quantum"}]}
- # TODO(salv-orlando): Now that we have async status synchronization
- # this tag is perhaps not needed anymore
- if shared:
- lswitch_obj["tags"].append({"tag": "true",
- "scope": "shared"})
- if "tags" in kwargs:
- lswitch_obj["tags"].extend(kwargs["tags"])
- uri = _build_uri_path(LSWITCH_RESOURCE)
- lswitch = do_request(HTTP_POST, uri, json.dumps(lswitch_obj),
- cluster=cluster)
- LOG.debug(_("Created logical switch: %s"), lswitch['uuid'])
- return lswitch
-
-
-def update_lswitch(cluster, lswitch_id, display_name,
- tenant_id=None, **kwargs):
- uri = _build_uri_path(LSWITCH_RESOURCE, resource_id=lswitch_id)
- lswitch_obj = {"display_name": utils.check_and_truncate(display_name),
- "tags": [{"tag": tenant_id, "scope": "os_tid"},
- {"tag": NEUTRON_VERSION, "scope": "quantum"}]}
- if "tags" in kwargs:
- lswitch_obj["tags"].extend(kwargs["tags"])
- try:
- return do_request(HTTP_PUT, uri, json.dumps(lswitch_obj),
- cluster=cluster)
- except exception.NotFound as e:
- LOG.error(_("Network not found, Error: %s"), str(e))
- raise exception.NetworkNotFound(net_id=lswitch_id)
-
-
-def create_l2_gw_service(cluster, tenant_id, display_name, devices):
- """Create a NVP Layer-2 Network Gateway Service.
-
- :param cluster: The target NVP cluster
- :param tenant_id: Identifier of the Openstack tenant for which
- the gateway service.
- :param display_name: Descriptive name of this gateway service
- :param devices: List of transport node uuids (and network
- interfaces on them) to use for the network gateway service
- :raise NvpApiException: if there is a problem while communicating
- with the NVP controller
- """
- tags = [{"tag": tenant_id, "scope": "os_tid"},
- {"tag": NEUTRON_VERSION, "scope": "quantum"}]
- # NOTE(salvatore-orlando): This is a little confusing, but device_id in
- # NVP is actually the identifier a physical interface on the gateway
- # device, which in the Neutron API is referred as interface_name
- gateways = [{"transport_node_uuid": device['id'],
- "device_id": device['interface_name'],
- "type": "L2Gateway"} for device in devices]
- gwservice_obj = {
- "display_name": utils.check_and_truncate(display_name),
- "tags": tags,
- "gateways": gateways,
- "type": "L2GatewayServiceConfig"
- }
- return do_request(
- "POST", _build_uri_path(GWSERVICE_RESOURCE),
- json.dumps(gwservice_obj), cluster=cluster)
-
-
-def delete_l2_gw_service(cluster, gateway_id):
- do_request("DELETE", _build_uri_path(GWSERVICE_RESOURCE,
- resource_id=gateway_id),
- cluster=cluster)
-
-
-def get_l2_gw_service(cluster, gateway_id):
- return do_request(
- "GET", _build_uri_path(GWSERVICE_RESOURCE,
- resource_id=gateway_id),
- cluster=cluster)
-
-
-def get_l2_gw_services(cluster, tenant_id=None,
- fields=None, filters=None):
- actual_filters = dict(filters or {})
- if tenant_id:
- actual_filters['tag'] = tenant_id
- actual_filters['tag_scope'] = 'os_tid'
- return get_all_query_pages(
- _build_uri_path(GWSERVICE_RESOURCE,
- filters=actual_filters),
- cluster)
-
-
-def update_l2_gw_service(cluster, gateway_id, display_name):
- # TODO(salvatore-orlando): Allow updates for gateways too
- gwservice_obj = get_l2_gw_service(cluster, gateway_id)
- if not display_name:
- # Nothing to update
- return gwservice_obj
- gwservice_obj["display_name"] = utils.check_and_truncate(display_name)
- return do_request("PUT", _build_uri_path(GWSERVICE_RESOURCE,
- resource_id=gateway_id),
- json.dumps(gwservice_obj), cluster=cluster)
-
-
-def delete_network(cluster, net_id, lswitch_id):
- delete_networks(cluster, net_id, [lswitch_id])
-
-
-#TODO(salvatore-orlando): Simplify and harmonize
-def delete_networks(cluster, net_id, lswitch_ids):
- for ls_id in lswitch_ids:
- path = "/ws.v1/lswitch/%s" % ls_id
- try:
- do_request(HTTP_DELETE, path, cluster=cluster)
- except exception.NotFound as e:
- LOG.error(_("Network not found, Error: %s"), str(e))
- raise exception.NetworkNotFound(net_id=ls_id)
-
-
-def query_lswitch_lports(cluster, ls_uuid, fields="*",
- filters=None, relations=None):
- # Fix filter for attachments
- if filters and "attachment" in filters:
- filters['attachment_vif_uuid'] = filters["attachment"]
- del filters['attachment']
- uri = _build_uri_path(LSWITCHPORT_RESOURCE, parent_resource_id=ls_uuid,
- fields=fields, filters=filters, relations=relations)
- return do_request(HTTP_GET, uri, cluster=cluster)['results']
-
-
-def delete_port(cluster, switch, port):
- uri = "/ws.v1/lswitch/" + switch + "/lport/" + port
- try:
- do_request(HTTP_DELETE, uri, cluster=cluster)
- except exception.NotFound:
- LOG.exception(_("Port or Network not found"))
- raise exception.PortNotFoundOnNetwork(
- net_id=switch, port_id=port)
- except NvpApiClient.NvpApiException:
- raise exception.NeutronException()
-
-
-def get_ports(cluster, networks=None, devices=None, tenants=None):
- vm_filter_obsolete = ""
- vm_filter = ""
- tenant_filter = ""
- # This is used when calling delete_network. Neutron checks to see if
- # the network has any ports.
- if networks:
- # FIXME (Aaron) If we get more than one network_id this won't work
- lswitch = networks[0]
- else:
- lswitch = "*"
- if devices:
- for device_id in devices:
- vm_filter_obsolete = '&'.join(
- ["tag_scope=vm_id",
- "tag=%s" % device_id_to_vm_id(device_id, obfuscate=True),
- vm_filter_obsolete])
- vm_filter = '&'.join(
- ["tag_scope=vm_id",
- "tag=%s" % device_id_to_vm_id(device_id),
- vm_filter])
- if tenants:
- for tenant in tenants:
- tenant_filter = '&'.join(
- ["tag_scope=os_tid",
- "tag=%s" % tenant,
- tenant_filter])
-
- nvp_lports = {}
- lport_fields_str = ("tags,admin_status_enabled,display_name,"
- "fabric_status_up")
- try:
- lport_query_path_obsolete = (
- "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id"
- "&relations=LogicalPortStatus" %
- (lswitch, lport_fields_str, vm_filter_obsolete, tenant_filter))
- lport_query_path = (
- "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id"
- "&relations=LogicalPortStatus" %
- (lswitch, lport_fields_str, vm_filter, tenant_filter))
- try:
- # NOTE(armando-migliaccio): by querying with obsolete tag first
- # current deployments won't take the performance hit of a double
- # call. In release L-** or M-**, we might want to swap the calls
- # as it's likely that ports with the new tag would outnumber the
- # ones with the old tag
- ports = get_all_query_pages(lport_query_path_obsolete, cluster)
- if not ports:
- ports = get_all_query_pages(lport_query_path, cluster)
- except exception.NotFound:
- LOG.warn(_("Lswitch %s not found in NVP"), lswitch)
- ports = None
-
- if ports:
- for port in ports:
- for tag in port["tags"]:
- if tag["scope"] == "q_port_id":
- nvp_lports[tag["tag"]] = port
- except Exception:
- err_msg = _("Unable to get ports")
- LOG.exception(err_msg)
- raise nvp_exc.NvpPluginException(err_msg=err_msg)
- return nvp_lports
-
-
-def get_port_by_neutron_tag(cluster, lswitch_uuid, neutron_port_id):
- """Get port by neutron tag.
-
- Returns the NVP UUID of the logical port with tag q_port_id equal to
- neutron_port_id or None if the port is not Found.
- """
- uri = _build_uri_path(LSWITCHPORT_RESOURCE,
- parent_resource_id=lswitch_uuid,
- fields='uuid',
- filters={'tag': neutron_port_id,
- 'tag_scope': 'q_port_id'})
- LOG.debug(_("Looking for port with q_port_id tag '%(neutron_port_id)s' "
- "on: '%(lswitch_uuid)s'"),
- {'neutron_port_id': neutron_port_id,
- 'lswitch_uuid': lswitch_uuid})
- res = do_request(HTTP_GET, uri, cluster=cluster)
- num_results = len(res["results"])
- if num_results >= 1:
- if num_results > 1:
- LOG.warn(_("Found '%(num_ports)d' ports with "
- "q_port_id tag: '%(neutron_port_id)s'. "
- "Only 1 was expected."),
- {'num_ports': num_results,
- 'neutron_port_id': neutron_port_id})
- return res["results"][0]
-
-
-def get_port(cluster, network, port, relations=None):
- LOG.info(_("get_port() %(network)s %(port)s"),
- {'network': network, 'port': port})
- uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "?"
- if relations:
- uri += "relations=%s" % relations
- try:
- return do_request(HTTP_GET, uri, cluster=cluster)
- except exception.NotFound as e:
- LOG.error(_("Port or Network not found, Error: %s"), str(e))
- raise exception.PortNotFoundOnNetwork(
- port_id=port, net_id=network)
-
-
-def _configure_extensions(lport_obj, mac_address, fixed_ips,
- port_security_enabled, security_profiles,
- queue_id, mac_learning_enabled,
- allowed_address_pairs):
- lport_obj['allowed_address_pairs'] = []
- if port_security_enabled:
- for fixed_ip in fixed_ips:
- ip_address = fixed_ip.get('ip_address')
- if ip_address:
- lport_obj['allowed_address_pairs'].append(
- {'mac_address': mac_address, 'ip_address': ip_address})
- # add address pair allowing src_ip 0.0.0.0 to leave
- # this is required for outgoing dhcp request
- lport_obj["allowed_address_pairs"].append(
- {"mac_address": mac_address,
- "ip_address": "0.0.0.0"})
- lport_obj['security_profiles'] = list(security_profiles or [])
- lport_obj['queue_uuid'] = queue_id
- if mac_learning_enabled is not None:
- lport_obj["mac_learning"] = mac_learning_enabled
- lport_obj["type"] = "LogicalSwitchPortConfig"
- for address_pair in list(allowed_address_pairs or []):
- lport_obj['allowed_address_pairs'].append(
- {'mac_address': address_pair['mac_address'],
- 'ip_address': address_pair['ip_address']})
-
-
-def update_port(cluster, lswitch_uuid, lport_uuid, neutron_port_id, tenant_id,
- display_name, device_id, admin_status_enabled,
- mac_address=None, fixed_ips=None, port_security_enabled=None,
- security_profiles=None, queue_id=None,
- mac_learning_enabled=None, allowed_address_pairs=None):
- lport_obj = dict(
- admin_status_enabled=admin_status_enabled,
- display_name=utils.check_and_truncate(display_name),
- tags=[dict(scope='os_tid', tag=tenant_id),
- dict(scope='q_port_id', tag=neutron_port_id),
- dict(scope='vm_id', tag=device_id_to_vm_id(device_id)),
- dict(scope='quantum', tag=NEUTRON_VERSION)])
-
- _configure_extensions(lport_obj, mac_address, fixed_ips,
- port_security_enabled, security_profiles,
- queue_id, mac_learning_enabled,
- allowed_address_pairs)
-
- path = "/ws.v1/lswitch/" + lswitch_uuid + "/lport/" + lport_uuid
- try:
- result = do_request(HTTP_PUT, path, json.dumps(lport_obj),
- cluster=cluster)
- LOG.debug(_("Updated logical port %(result)s "
- "on logical switch %(uuid)s"),
- {'result': result['uuid'], 'uuid': lswitch_uuid})
- return result
- except exception.NotFound as e:
- LOG.error(_("Port or Network not found, Error: %s"), str(e))
- raise exception.PortNotFoundOnNetwork(
- port_id=lport_uuid, net_id=lswitch_uuid)
-
-
-def create_lport(cluster, lswitch_uuid, tenant_id, neutron_port_id,
- display_name, device_id, admin_status_enabled,
- mac_address=None, fixed_ips=None, port_security_enabled=None,
- security_profiles=None, queue_id=None,
- mac_learning_enabled=None, allowed_address_pairs=None):
- """Creates a logical port on the assigned logical switch."""
- display_name = utils.check_and_truncate(display_name)
- lport_obj = dict(
- admin_status_enabled=admin_status_enabled,
- display_name=display_name,
- tags=[dict(scope='os_tid', tag=tenant_id),
- dict(scope='q_port_id', tag=neutron_port_id),
- dict(scope='vm_id', tag=device_id_to_vm_id(device_id)),
- dict(scope='quantum', tag=NEUTRON_VERSION)],
- )
-
- _configure_extensions(lport_obj, mac_address, fixed_ips,
- port_security_enabled, security_profiles,
- queue_id, mac_learning_enabled,
- allowed_address_pairs)
-
- path = _build_uri_path(LSWITCHPORT_RESOURCE,
- parent_resource_id=lswitch_uuid)
- result = do_request(HTTP_POST, path, json.dumps(lport_obj),
- cluster=cluster)
-
- LOG.debug(_("Created logical port %(result)s on logical switch %(uuid)s"),
- {'result': result['uuid'], 'uuid': lswitch_uuid})
- return result
-
-
-def get_port_status(cluster, lswitch_id, port_id):
- """Retrieve the operational status of the port."""
- try:
- r = do_request(HTTP_GET,
- "/ws.v1/lswitch/%s/lport/%s/status" %
- (lswitch_id, port_id), cluster=cluster)
- except exception.NotFound as e:
- LOG.error(_("Port not found, Error: %s"), str(e))
- raise exception.PortNotFoundOnNetwork(
- port_id=port_id, net_id=lswitch_id)
- if r['link_status_up'] is True:
- return constants.PORT_STATUS_ACTIVE
- else:
- return constants.PORT_STATUS_DOWN
-
-
def _plug_interface(cluster, lswitch_id, lport_id, att_obj):
uri = _build_uri_path(LSWITCHPORT_RESOURCE, lport_id, lswitch_id,
is_attachment=True)
cluster=cluster)
-def plug_l2_gw_service(cluster, lswitch_id, lport_id,
- gateway_id, vlan_id=None):
- """Plug a Layer-2 Gateway Attachment object in a logical port."""
- att_obj = {'type': 'L2GatewayAttachment',
- 'l2_gateway_service_uuid': gateway_id}
- if vlan_id:
- att_obj['vlan_id'] = vlan_id
- return _plug_interface(cluster, lswitch_id, lport_id, att_obj)
-
-
-def plug_interface(cluster, lswitch_id, port, type, attachment=None):
- """Plug a VIF Attachment object in a logical port."""
- lport_obj = {}
- if attachment:
- lport_obj["vif_uuid"] = attachment
-
- lport_obj["type"] = type
- return _plug_interface(cluster, lswitch_id, port, lport_obj)
-
#------------------------------------------------------------------------------
# Security Profile convenience functions.
#------------------------------------------------------------------------------
--- /dev/null
+# Copyright (c) 2014 VMware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
+from neutron.plugins.nicira import nvplib
+from neutron.tests.unit.nicira.test_nvplib import NsxlibNegativeBaseTestCase
+from neutron.tests.unit.nicira.test_nvplib import NvplibTestCase
+from neutron.tests.unit import test_api_v2
+
+_uuid = test_api_v2._uuid
+
+
+class L2GatewayNegativeTestCase(NsxlibNegativeBaseTestCase):
+
+ def test_create_l2_gw_service_on_failure(self):
+ self.assertRaises(nvplib.NvpApiClient.NvpApiException,
+ l2gwlib.create_l2_gw_service,
+ self.fake_cluster,
+ 'fake-tenant',
+ 'fake-gateway',
+ [{'id': _uuid(),
+ 'interface_name': 'xxx'}])
+
+ def test_delete_l2_gw_service_on_failure(self):
+ self.assertRaises(nvplib.NvpApiClient.NvpApiException,
+ l2gwlib.delete_l2_gw_service,
+ self.fake_cluster,
+ 'fake-gateway')
+
+ def test_get_l2_gw_service_on_failure(self):
+ self.assertRaises(nvplib.NvpApiClient.NvpApiException,
+ l2gwlib.get_l2_gw_service,
+ self.fake_cluster,
+ 'fake-gateway')
+
+ def test_update_l2_gw_service_on_failure(self):
+ self.assertRaises(nvplib.NvpApiClient.NvpApiException,
+ l2gwlib.update_l2_gw_service,
+ self.fake_cluster,
+ 'fake-gateway',
+ 'pluto')
+
+
+class L2GatewayTestCase(NvplibTestCase):
+
+ def _create_gw_service(self, node_uuid, display_name,
+ tenant_id='fake_tenant'):
+ return l2gwlib.create_l2_gw_service(self.fake_cluster,
+ tenant_id,
+ display_name,
+ [{'id': node_uuid,
+ 'interface_name': 'xxx'}])
+
+ def test_create_l2_gw_service(self):
+ display_name = 'fake-gateway'
+ node_uuid = _uuid()
+ response = self._create_gw_service(node_uuid, display_name)
+ self.assertEqual(response.get('type'), 'L2GatewayServiceConfig')
+ self.assertEqual(response.get('display_name'), display_name)
+ gateways = response.get('gateways', [])
+ self.assertEqual(len(gateways), 1)
+ self.assertEqual(gateways[0]['type'], 'L2Gateway')
+ self.assertEqual(gateways[0]['device_id'], 'xxx')
+ self.assertEqual(gateways[0]['transport_node_uuid'], node_uuid)
+
+ def test_update_l2_gw_service(self):
+ display_name = 'fake-gateway'
+ new_display_name = 'still-fake-gateway'
+ node_uuid = _uuid()
+ res1 = self._create_gw_service(node_uuid, display_name)
+ gw_id = res1['uuid']
+ res2 = l2gwlib.update_l2_gw_service(
+ self.fake_cluster, gw_id, new_display_name)
+ self.assertEqual(res2['display_name'], new_display_name)
+
+ def test_get_l2_gw_service(self):
+ display_name = 'fake-gateway'
+ node_uuid = _uuid()
+ gw_id = self._create_gw_service(node_uuid, display_name)['uuid']
+ response = l2gwlib.get_l2_gw_service(self.fake_cluster, gw_id)
+ self.assertEqual(response.get('type'), 'L2GatewayServiceConfig')
+ self.assertEqual(response.get('display_name'), display_name)
+ self.assertEqual(response.get('uuid'), gw_id)
+
+ def test_list_l2_gw_service(self):
+ gw_ids = []
+ for name in ('fake-1', 'fake-2'):
+ gw_ids.append(self._create_gw_service(_uuid(), name)['uuid'])
+ results = l2gwlib.get_l2_gw_services(self.fake_cluster)
+ self.assertEqual(len(results), 2)
+ self.assertEqual(sorted(gw_ids), sorted([r['uuid'] for r in results]))
+
+ def test_list_l2_gw_service_by_tenant(self):
+ gw_ids = [self._create_gw_service(
+ _uuid(), name, tenant_id=name)['uuid']
+ for name in ('fake-1', 'fake-2')]
+ results = l2gwlib.get_l2_gw_services(self.fake_cluster,
+ tenant_id='fake-1')
+ self.assertEqual(len(results), 1)
+ self.assertEqual(results[0]['uuid'], gw_ids[0])
+
+ def test_delete_l2_gw_service(self):
+ display_name = 'fake-gateway'
+ node_uuid = _uuid()
+ gw_id = self._create_gw_service(node_uuid, display_name)['uuid']
+ l2gwlib.delete_l2_gw_service(self.fake_cluster, gw_id)
+ results = l2gwlib.get_l2_gw_services(self.fake_cluster)
+ self.assertEqual(len(results), 0)
+
+ def test_plug_l2_gw_port_attachment(self):
+ tenant_id = 'pippo'
+ node_uuid = _uuid()
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(
+ self.fake_cluster, _uuid(), tenant_id,
+ 'fake-switch', transport_zones_config)
+ gw_id = self._create_gw_service(node_uuid, 'fake-gw')['uuid']
+ lport = switchlib.create_lport(
+ self.fake_cluster, lswitch['uuid'], tenant_id, _uuid(),
+ 'fake-gw-port', gw_id, True)
+ l2gwlib.plug_l2_gw_service(
+ self.fake_cluster, lswitch['uuid'],
+ lport['uuid'], gw_id)
+ uri = nvplib._build_uri_path(nvplib.LSWITCHPORT_RESOURCE,
+ lport['uuid'],
+ lswitch['uuid'],
+ is_attachment=True)
+ resp_obj = nvplib.do_request("GET", uri,
+ cluster=self.fake_cluster)
+ self.assertIn('LogicalPortAttachment', resp_obj)
+ self.assertEqual(resp_obj['LogicalPortAttachment']['type'],
+ 'L2GatewayAttachment')
from neutron.openstack.common import uuidutils
from neutron.plugins.nicira.common import exceptions as nvp_exc
from neutron.plugins.nicira.nsxlib import router as routerlib
+from neutron.plugins.nicira.nsxlib import switch as switchlib
from neutron.plugins.nicira import NvpApiClient
from neutron.plugins.nicira import nvplib
from neutron.tests.unit.nicira.test_nvplib import NsxlibNegativeBaseTestCase
tenant_id = 'pippo'
transport_zones_config = [{'zone_uuid': _uuid(),
'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- _uuid(),
- tenant_id, 'fake-switch',
- transport_zones_config)
- lport = nvplib.create_lport(self.fake_cluster, lswitch['uuid'],
- tenant_id, 'xyz',
- 'name', 'device_id', True)
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ _uuid(),
+ tenant_id, 'fake-switch',
+ transport_zones_config)
+ lport = switchlib.create_lport(self.fake_cluster, lswitch['uuid'],
+ tenant_id, 'xyz',
+ 'name', 'device_id', True)
lrouter = routerlib.create_lrouter(self.fake_cluster,
uuidutils.generate_uuid(),
tenant_id,
--- /dev/null
+# Copyright (c) 2014 VMware, Inc.
+#
+# 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 hashlib
+import mock
+
+from neutron.common import constants
+from neutron.common import exceptions
+from neutron.plugins.nicira.common import utils
+from neutron.plugins.nicira.nsxlib import switch as switchlib
+from neutron.tests.unit.nicira.test_nvplib import NvplibTestCase
+from neutron.tests.unit import test_api_v2
+
+_uuid = test_api_v2._uuid
+
+
+class LogicalSwitchesTestCase(NvplibTestCase):
+
+ def test_create_and_get_lswitches_single(self):
+ tenant_id = 'pippo'
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ _uuid(),
+ tenant_id,
+ 'fake-switch',
+ transport_zones_config)
+ res_lswitch = switchlib.get_lswitches(self.fake_cluster,
+ lswitch['uuid'])
+ self.assertEqual(len(res_lswitch), 1)
+ self.assertEqual(res_lswitch[0]['uuid'],
+ lswitch['uuid'])
+
+ def test_create_and_get_lswitches_single_name_exceeds_40_chars(self):
+ tenant_id = 'pippo'
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ tenant_id,
+ _uuid(),
+ '*' * 50,
+ transport_zones_config)
+ res_lswitch = switchlib.get_lswitches(self.fake_cluster,
+ lswitch['uuid'])
+ self.assertEqual(len(res_lswitch), 1)
+ self.assertEqual(res_lswitch[0]['uuid'], lswitch['uuid'])
+ self.assertEqual(res_lswitch[0]['display_name'], '*' * 40)
+
+ def test_create_and_get_lswitches_multiple(self):
+ tenant_id = 'pippo'
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ network_id = _uuid()
+ main_lswitch = switchlib.create_lswitch(
+ self.fake_cluster, network_id,
+ tenant_id, 'fake-switch', transport_zones_config,
+ tags=[{'scope': 'multi_lswitch', 'tag': 'True'}])
+ # Create secondary lswitch
+ second_lswitch = switchlib.create_lswitch(
+ self.fake_cluster, network_id,
+ tenant_id, 'fake-switch-2', transport_zones_config)
+ res_lswitch = switchlib.get_lswitches(self.fake_cluster,
+ network_id)
+ self.assertEqual(len(res_lswitch), 2)
+ switch_uuids = [ls['uuid'] for ls in res_lswitch]
+ self.assertIn(main_lswitch['uuid'], switch_uuids)
+ self.assertIn(second_lswitch['uuid'], switch_uuids)
+ for ls in res_lswitch:
+ if ls['uuid'] == main_lswitch['uuid']:
+ main_ls = ls
+ else:
+ second_ls = ls
+ main_ls_tags = self._build_tag_dict(main_ls['tags'])
+ second_ls_tags = self._build_tag_dict(second_ls['tags'])
+ self.assertIn('multi_lswitch', main_ls_tags)
+ self.assertNotIn('multi_lswitch', second_ls_tags)
+ self.assertIn('quantum_net_id', main_ls_tags)
+ self.assertIn('quantum_net_id', second_ls_tags)
+ self.assertEqual(main_ls_tags['quantum_net_id'],
+ network_id)
+ self.assertEqual(second_ls_tags['quantum_net_id'],
+ network_id)
+
+ def test_update_lswitch(self):
+ new_name = 'new-name'
+ new_tags = [{'scope': 'new_tag', 'tag': 'xxx'}]
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ _uuid(),
+ 'pippo',
+ 'fake-switch',
+ transport_zones_config)
+ switchlib.update_lswitch(self.fake_cluster, lswitch['uuid'],
+ new_name, tags=new_tags)
+ res_lswitch = switchlib.get_lswitches(self.fake_cluster,
+ lswitch['uuid'])
+ self.assertEqual(len(res_lswitch), 1)
+ self.assertEqual(res_lswitch[0]['display_name'], new_name)
+ switch_tags = self._build_tag_dict(res_lswitch[0]['tags'])
+ self.assertIn('new_tag', switch_tags)
+ self.assertEqual(switch_tags['new_tag'], 'xxx')
+
+ def test_update_non_existing_lswitch_raises(self):
+ self.assertRaises(exceptions.NetworkNotFound,
+ switchlib.update_lswitch,
+ self.fake_cluster, 'whatever',
+ 'foo', 'bar')
+
+ def test_delete_networks(self):
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ _uuid(),
+ 'pippo',
+ 'fake-switch',
+ transport_zones_config)
+ switchlib.delete_networks(self.fake_cluster, lswitch['uuid'],
+ [lswitch['uuid']])
+ self.assertRaises(exceptions.NotFound,
+ switchlib.get_lswitches,
+ self.fake_cluster,
+ lswitch['uuid'])
+
+ def test_delete_non_existing_lswitch_raises(self):
+ self.assertRaises(exceptions.NetworkNotFound,
+ switchlib.delete_networks,
+ self.fake_cluster, 'whatever', ['whatever'])
+
+
+class LogicalPortsTestCase(NvplibTestCase):
+
+ def _create_switch_and_port(self, tenant_id='pippo',
+ neutron_port_id='whatever',
+ name='name', device_id='device_id'):
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(self.fake_cluster,
+ _uuid(), tenant_id, 'fake-switch',
+ transport_zones_config)
+ lport = switchlib.create_lport(self.fake_cluster, lswitch['uuid'],
+ tenant_id, neutron_port_id,
+ name, device_id, True)
+ return lswitch, lport
+
+ def test_create_and_get_port(self):
+ lswitch, lport = self._create_switch_and_port()
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ self.assertEqual(lport['uuid'], lport_res['uuid'])
+ # Try again with relation
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'],
+ relations='LogicalPortStatus')
+ self.assertEqual(lport['uuid'], lport_res['uuid'])
+
+ def test_plug_interface(self):
+ lswitch, lport = self._create_switch_and_port()
+ switchlib.plug_interface(self.fake_cluster, lswitch['uuid'],
+ lport['uuid'], 'VifAttachment', 'fake')
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ self.assertEqual(lport['uuid'], lport_res['uuid'])
+
+ def test_get_port_by_tag(self):
+ lswitch, lport = self._create_switch_and_port()
+ lport2 = switchlib.get_port_by_neutron_tag(self.fake_cluster,
+ lswitch['uuid'],
+ 'whatever')
+ self.assertIsNotNone(lport2)
+ self.assertEqual(lport['uuid'], lport2['uuid'])
+
+ def test_get_port_by_tag_not_found_returns_None(self):
+ tenant_id = 'pippo'
+ neutron_port_id = 'whatever'
+ transport_zones_config = [{'zone_uuid': _uuid(),
+ 'transport_type': 'stt'}]
+ lswitch = switchlib.create_lswitch(
+ self.fake_cluster, tenant_id, _uuid(),
+ 'fake-switch', transport_zones_config)
+ lport = switchlib.get_port_by_neutron_tag(
+ self.fake_cluster, lswitch['uuid'], neutron_port_id)
+ self.assertIsNone(lport)
+
+ def test_get_port_status(self):
+ lswitch, lport = self._create_switch_and_port()
+ status = switchlib.get_port_status(
+ self.fake_cluster, lswitch['uuid'], lport['uuid'])
+ self.assertEqual(constants.PORT_STATUS_ACTIVE, status)
+
+ def test_get_port_status_non_existent_raises(self):
+ self.assertRaises(exceptions.PortNotFoundOnNetwork,
+ switchlib.get_port_status,
+ self.fake_cluster,
+ 'boo', 'boo')
+
+ def test_update_port(self):
+ lswitch, lport = self._create_switch_and_port()
+ switchlib.update_port(
+ self.fake_cluster, lswitch['uuid'], lport['uuid'],
+ 'neutron_port_id', 'pippo2', 'new_name', 'device_id', False)
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ self.assertEqual(lport['uuid'], lport_res['uuid'])
+ self.assertEqual('new_name', lport_res['display_name'])
+ self.assertEqual('False', lport_res['admin_status_enabled'])
+ port_tags = self._build_tag_dict(lport_res['tags'])
+ self.assertIn('os_tid', port_tags)
+ self.assertIn('q_port_id', port_tags)
+ self.assertIn('vm_id', port_tags)
+
+ def test_create_port_device_id_less_than_40_chars(self):
+ lswitch, lport = self._create_switch_and_port()
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ port_tags = self._build_tag_dict(lport_res['tags'])
+ self.assertEqual('device_id', port_tags['vm_id'])
+
+ def test_create_port_device_id_more_than_40_chars(self):
+ dev_id = "this_is_a_very_long_device_id_with_lots_of_characters"
+ lswitch, lport = self._create_switch_and_port(device_id=dev_id)
+ lport_res = switchlib.get_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ port_tags = self._build_tag_dict(lport_res['tags'])
+ self.assertNotEqual(len(dev_id), len(port_tags['vm_id']))
+
+ def test_get_ports_with_obsolete_and_new_vm_id_tag(self):
+ def obsolete(device_id, obfuscate=False):
+ return hashlib.sha1(device_id).hexdigest()
+
+ with mock.patch.object(utils, 'device_id_to_vm_id', new=obsolete):
+ dev_id1 = "short-dev-id-1"
+ _, lport1 = self._create_switch_and_port(device_id=dev_id1)
+ dev_id2 = "short-dev-id-2"
+ _, lport2 = self._create_switch_and_port(device_id=dev_id2)
+
+ lports = switchlib.get_ports(self.fake_cluster, None, [dev_id1])
+ port_tags = self._build_tag_dict(lports['whatever']['tags'])
+ self.assertNotEqual(dev_id1, port_tags['vm_id'])
+
+ lports = switchlib.get_ports(self.fake_cluster, None, [dev_id2])
+ port_tags = self._build_tag_dict(lports['whatever']['tags'])
+ self.assertEqual(dev_id2, port_tags['vm_id'])
+
+ def test_update_non_existent_port_raises(self):
+ self.assertRaises(exceptions.PortNotFoundOnNetwork,
+ switchlib.update_port, self.fake_cluster,
+ 'boo', 'boo', 'boo', 'boo', 'boo', 'boo', False)
+
+ def test_delete_port(self):
+ lswitch, lport = self._create_switch_and_port()
+ switchlib.delete_port(self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+ self.assertRaises(exceptions.PortNotFoundOnNetwork,
+ switchlib.get_port, self.fake_cluster,
+ lswitch['uuid'], lport['uuid'])
+
+ def test_delete_non_existent_port_raises(self):
+ lswitch = self._create_switch_and_port()[0]
+ self.assertRaises(exceptions.PortNotFoundOnNetwork,
+ switchlib.delete_port, self.fake_cluster,
+ lswitch['uuid'], 'bad_port_uuid')
+
+ def test_query_lswitch_ports(self):
+ lswitch, lport = self._create_switch_and_port()
+ switch_port_uuids = [
+ switchlib.create_lport(
+ self.fake_cluster, lswitch['uuid'], 'pippo', 'qportid-%s' % k,
+ 'port-%s' % k, 'deviceid-%s' % k, True)['uuid']
+ for k in range(2)]
+ switch_port_uuids.append(lport['uuid'])
+ ports = switchlib.query_lswitch_lports(
+ self.fake_cluster, lswitch['uuid'])
+ self.assertEqual(len(ports), 3)
+ for res_port in ports:
+ self.assertIn(res_port['uuid'], switch_port_uuids)
self.mock_lsn_api.lsn_port_create.return_value = self.lsn_port_id
with mock.patch.object(
self.manager, 'lsn_get', return_value=self.lsn_id):
- with mock.patch.object(lsn_man.nsxlib, 'get_port_by_neutron_tag'):
+ with mock.patch.object(lsn_man.switch_api,
+ 'get_port_by_neutron_tag'):
expected = self.manager.lsn_port_dhcp_setup(
mock.ANY, mock.ANY, mock.ANY, mock.ANY, subnet_config=sub)
self.assertEqual(
self.assertEqual(1, f.call_count)
def test_lsn_port_dhcp_setup_with_not_found(self):
- with mock.patch.object(lsn_man.nsxlib, 'get_port_by_neutron_tag') as f:
+ with mock.patch.object(lsn_man.switch_api,
+ 'get_port_by_neutron_tag') as f:
f.side_effect = n_exc.NotFound
self.assertRaises(p_exc.PortConfigurationError,
self.manager.lsn_port_dhcp_setup,
def test_lsn_port_dhcp_setup_with_conflict(self):
self.mock_lsn_api.lsn_port_plug_network.side_effect = (
p_exc.LsnConfigurationConflict(lsn_id=self.lsn_id))
- with mock.patch.object(lsn_man.nsxlib, 'get_port_by_neutron_tag'):
+ with mock.patch.object(lsn_man.switch_api, 'get_port_by_neutron_tag'):
with mock.patch.object(self.manager, 'lsn_port_delete') as g:
self.assertRaises(p_exc.PortConfigurationError,
self.manager.lsn_port_dhcp_setup,
'network_id': self.net_id,
'tenant_id': self.tenant_id
}
- with mock.patch.object(lsn_man.nsxlib, 'create_lport') as f:
+ with mock.patch.object(lsn_man.switch_api, 'create_lport') as f:
f.return_value = {'uuid': self.port_id}
self.manager.lsn_port_metadata_setup(mock.ANY, self.lsn_id, subnet)
self.assertEqual(1, self.mock_lsn_api.lsn_port_create.call_count)
'network_id': self.net_id,
'tenant_id': self.tenant_id
}
- with mock.patch.object(lsn_man.nsxlib, 'create_lport') as f:
+ with mock.patch.object(lsn_man.switch_api, 'create_lport') as f:
f.side_effect = n_exc.NotFound
self.assertRaises(p_exc.PortConfigurationError,
self.manager.lsn_port_metadata_setup,
'network_id': self.net_id,
'tenant_id': self.tenant_id
}
- with mock.patch.object(lsn_man.nsxlib, 'create_lport') as f:
- with mock.patch.object(lsn_man.nsxlib, 'delete_port') as g:
+ with mock.patch.object(lsn_man.switch_api, 'create_lport') as f:
+ with mock.patch.object(lsn_man.switch_api, 'delete_port') as g:
f.return_value = {'uuid': self.port_id}
self.mock_lsn_api.lsn_port_plug_network.side_effect = (
p_exc.LsnConfigurationConflict(lsn_id=self.lsn_id))
def test_lsn_port_dispose_meta_mac(self):
self.mac = constants.METADATA_MAC
- with mock.patch.object(lsn_man.nsxlib, 'get_port_by_neutron_tag') as f:
- with mock.patch.object(lsn_man.nsxlib, 'delete_port') as g:
+ with mock.patch.object(lsn_man.switch_api,
+ 'get_port_by_neutron_tag') as f:
+ with mock.patch.object(lsn_man.switch_api, 'delete_port') as g:
f.return_value = {'uuid': self.port_id}
self._test_lsn_port_dispose_with_values(
self.lsn_id, self.lsn_port_id, 1)
with self.port(subnet=sub):
with self.port(subnet=sub):
plugin = manager.NeutronManager.get_plugin()
- ls = nvplib.get_lswitches(plugin.cluster,
- net['network']['id'])
+ ls = nsxlib.switch.get_lswitches(plugin.cluster,
+ net['network']['id'])
self.assertEqual(len(ls), 2)
def test_update_port_delete_ip(self):
self.assertFalse(self.fc._fake_lswitch_lport_dict)
def test_create_port_nvp_error_no_orphan_left(self):
- with mock.patch.object(nvplib, 'create_lport',
+ with mock.patch.object(nsxlib.switch, 'create_lport',
side_effect=NvpApiClient.NvpApiException):
with self.network() as net:
net_id = net['network']['id']
def test_update_network_gateway_with_name_calls_backend(self):
with mock.patch.object(
- nvplib, 'update_l2_gw_service') as mock_update_gw:
+ nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
with self._network_gateway(name='cavani') as nw_gw:
nw_gw_id = nw_gw[self.resource]['id']
self._update(nvp_networkgw.COLLECTION_NAME, nw_gw_id,
def test_update_network_gateway_without_name_does_not_call_backend(self):
with mock.patch.object(
- nvplib, 'update_l2_gw_service') as mock_update_gw:
+ nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
with self._network_gateway(name='something') as nw_gw:
nw_gw_id = nw_gw[self.resource]['id']
self._update(nvp_networkgw.COLLECTION_NAME, nw_gw_id,
def raise_nvp_api_exc(*args, **kwargs):
raise NvpApiClient.NvpApiException
- with mock.patch.object(nvplib,
+ with mock.patch.object(nsxlib.l2gateway,
'create_l2_gw_service',
new=raise_nvp_api_exc):
res = self._create_network_gateway(
self.assertEqual(500, res.status_int)
def test_create_network_gateway_nvp_error_returns_409(self):
- with mock.patch.object(nvplib,
+ with mock.patch.object(nsxlib.l2gateway,
'create_l2_gw_service',
side_effect=NvpApiClient.Conflict):
res = self._create_network_gateway(
exp_lp_uuid = uuidutils.generate_uuid()
ret_value = None, exp_lp_uuid
self._mock_port_mapping_db_calls(ret_value)
- with mock.patch(nicira_method('query_lswitch_lports'),
+ with mock.patch(nicira_method('query_lswitch_lports',
+ module_name='nsxlib.switch'),
return_value=[{'uuid': exp_lp_uuid,
'_relations': {
'LogicalSwitchConfig': {
exp_lp_uuid = uuidutils.generate_uuid()
ret_value = None, None
self._mock_port_mapping_db_calls(ret_value)
- with mock.patch(nicira_method('query_lswitch_lports'),
+ with mock.patch(nicira_method('query_lswitch_lports',
+ module_name='nsxlib.switch'),
return_value=[{'uuid': exp_lp_uuid,
'_relations': {
'LogicalSwitchConfig': {
# mappings are not found both in the db and the backend
ret_value = None, None
self._mock_port_mapping_db_calls(ret_value)
- with mock.patch(nicira_method('query_lswitch_lports'),
+ with mock.patch(nicira_method('query_lswitch_lports',
+ module_name='nsxlib.switch'),
return_value=[]):
self._verify_get_nsx_switch_and_port_id(None, None)
# found for a given network identifier
exp_ls_uuids = [uuidutils.generate_uuid()]
self._mock_network_mapping_db_calls(None)
- with mock.patch(nicira_method('get_lswitches'),
+ with mock.patch(nicira_method('get_lswitches',
+ module_name='nsxlib.switch'),
return_value=[{'uuid': uuid}
for uuid in exp_ls_uuids]):
self._verify_get_nsx_switch_ids(exp_ls_uuids)
# This test verifies that the function returns None if the mappings
# are not found both in the db and in the backend
self._mock_network_mapping_db_calls(None)
- with mock.patch(nicira_method('get_lswitches'),
+ with mock.patch(nicira_method('get_lswitches',
+ module_name='nsxlib.switch'),
return_value=[]):
self._verify_get_nsx_switch_ids(None)
#
# @author: Salvatore Orlando, VMware
-import hashlib
import mock
-from neutron.common import constants
from neutron.common import exceptions
from neutron.plugins.nicira.common import config # noqa
from neutron.plugins.nicira.common import exceptions as nvp_exc
self.addCleanup(self.mock_nvpapi.stop)
-class L2GatewayNegativeTestCase(NsxlibNegativeBaseTestCase):
-
- def test_create_l2_gw_service_on_failure(self):
- self.assertRaises(nvplib.NvpApiClient.NvpApiException,
- nvplib.create_l2_gw_service,
- self.fake_cluster,
- 'fake-tenant',
- 'fake-gateway',
- [{'id': _uuid(),
- 'interface_name': 'xxx'}])
-
- def test_delete_l2_gw_service_on_failure(self):
- self.assertRaises(nvplib.NvpApiClient.NvpApiException,
- nvplib.delete_l2_gw_service,
- self.fake_cluster,
- 'fake-gateway')
-
- def test_get_l2_gw_service_on_failure(self):
- self.assertRaises(nvplib.NvpApiClient.NvpApiException,
- nvplib.get_l2_gw_service,
- self.fake_cluster,
- 'fake-gateway')
-
- def test_update_l2_gw_service_on_failure(self):
- self.assertRaises(nvplib.NvpApiClient.NvpApiException,
- nvplib.update_l2_gw_service,
- self.fake_cluster,
- 'fake-gateway',
- 'pluto')
-
-
-class TestNvplibL2Gateway(NvplibTestCase):
-
- def _create_gw_service(self, node_uuid, display_name,
- tenant_id='fake_tenant'):
- return nvplib.create_l2_gw_service(self.fake_cluster,
- tenant_id,
- display_name,
- [{'id': node_uuid,
- 'interface_name': 'xxx'}])
-
- def test_create_l2_gw_service(self):
- display_name = 'fake-gateway'
- node_uuid = _uuid()
- response = self._create_gw_service(node_uuid, display_name)
- self.assertEqual(response.get('type'), 'L2GatewayServiceConfig')
- self.assertEqual(response.get('display_name'), display_name)
- gateways = response.get('gateways', [])
- self.assertEqual(len(gateways), 1)
- self.assertEqual(gateways[0]['type'], 'L2Gateway')
- self.assertEqual(gateways[0]['device_id'], 'xxx')
- self.assertEqual(gateways[0]['transport_node_uuid'], node_uuid)
-
- def test_update_l2_gw_service(self):
- display_name = 'fake-gateway'
- new_display_name = 'still-fake-gateway'
- node_uuid = _uuid()
- res1 = self._create_gw_service(node_uuid, display_name)
- gw_id = res1['uuid']
- res2 = nvplib.update_l2_gw_service(self.fake_cluster, gw_id,
- new_display_name)
- self.assertEqual(res2['display_name'], new_display_name)
-
- def test_get_l2_gw_service(self):
- display_name = 'fake-gateway'
- node_uuid = _uuid()
- gw_id = self._create_gw_service(node_uuid, display_name)['uuid']
- response = nvplib.get_l2_gw_service(self.fake_cluster, gw_id)
- self.assertEqual(response.get('type'), 'L2GatewayServiceConfig')
- self.assertEqual(response.get('display_name'), display_name)
- self.assertEqual(response.get('uuid'), gw_id)
-
- def test_list_l2_gw_service(self):
- gw_ids = []
- for name in ('fake-1', 'fake-2'):
- gw_ids.append(self._create_gw_service(_uuid(), name)['uuid'])
- results = nvplib.get_l2_gw_services(self.fake_cluster)
- self.assertEqual(len(results), 2)
- self.assertEqual(sorted(gw_ids), sorted([r['uuid'] for r in results]))
-
- def test_list_l2_gw_service_by_tenant(self):
- gw_ids = [self._create_gw_service(
- _uuid(), name, tenant_id=name)['uuid']
- for name in ('fake-1', 'fake-2')]
- results = nvplib.get_l2_gw_services(self.fake_cluster,
- tenant_id='fake-1')
- self.assertEqual(len(results), 1)
- self.assertEqual(results[0]['uuid'], gw_ids[0])
-
- def test_delete_l2_gw_service(self):
- display_name = 'fake-gateway'
- node_uuid = _uuid()
- gw_id = self._create_gw_service(node_uuid, display_name)['uuid']
- nvplib.delete_l2_gw_service(self.fake_cluster, gw_id)
- results = nvplib.get_l2_gw_services(self.fake_cluster)
- self.assertEqual(len(results), 0)
-
- def test_plug_l2_gw_port_attachment(self):
- tenant_id = 'pippo'
- node_uuid = _uuid()
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster, _uuid(), tenant_id,
- 'fake-switch', transport_zones_config)
- gw_id = self._create_gw_service(node_uuid, 'fake-gw')['uuid']
- lport = nvplib.create_lport(self.fake_cluster,
- lswitch['uuid'],
- tenant_id,
- _uuid(),
- 'fake-gw-port',
- gw_id,
- True)
- nvplib.plug_l2_gw_service(self.fake_cluster,
- lswitch['uuid'],
- lport['uuid'],
- gw_id)
- uri = nvplib._build_uri_path(nvplib.LSWITCHPORT_RESOURCE,
- lport['uuid'],
- lswitch['uuid'],
- is_attachment=True)
- resp_obj = nvplib.do_request("GET", uri,
- cluster=self.fake_cluster)
- self.assertIn('LogicalPortAttachment', resp_obj)
- self.assertEqual(resp_obj['LogicalPortAttachment']['type'],
- 'L2GatewayAttachment')
-
-
-class TestNvplibLogicalSwitches(NvplibTestCase):
-
- def test_create_and_get_lswitches_single(self):
- tenant_id = 'pippo'
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- _uuid(),
- tenant_id,
- 'fake-switch',
- transport_zones_config)
- res_lswitch = nvplib.get_lswitches(self.fake_cluster,
- lswitch['uuid'])
- self.assertEqual(len(res_lswitch), 1)
- self.assertEqual(res_lswitch[0]['uuid'],
- lswitch['uuid'])
-
- def test_create_and_get_lswitches_single_name_exceeds_40_chars(self):
- tenant_id = 'pippo'
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- tenant_id,
- _uuid(),
- '*' * 50,
- transport_zones_config)
- res_lswitch = nvplib.get_lswitches(self.fake_cluster,
- lswitch['uuid'])
- self.assertEqual(len(res_lswitch), 1)
- self.assertEqual(res_lswitch[0]['uuid'], lswitch['uuid'])
- self.assertEqual(res_lswitch[0]['display_name'], '*' * 40)
-
- def test_create_and_get_lswitches_multiple(self):
- tenant_id = 'pippo'
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- network_id = _uuid()
- main_lswitch = nvplib.create_lswitch(
- self.fake_cluster, network_id,
- tenant_id, 'fake-switch', transport_zones_config,
- tags=[{'scope': 'multi_lswitch', 'tag': 'True'}])
- # Create secondary lswitch
- second_lswitch = nvplib.create_lswitch(
- self.fake_cluster, network_id,
- tenant_id, 'fake-switch-2', transport_zones_config)
- res_lswitch = nvplib.get_lswitches(self.fake_cluster,
- network_id)
- self.assertEqual(len(res_lswitch), 2)
- switch_uuids = [ls['uuid'] for ls in res_lswitch]
- self.assertIn(main_lswitch['uuid'], switch_uuids)
- self.assertIn(second_lswitch['uuid'], switch_uuids)
- for ls in res_lswitch:
- if ls['uuid'] == main_lswitch['uuid']:
- main_ls = ls
- else:
- second_ls = ls
- main_ls_tags = self._build_tag_dict(main_ls['tags'])
- second_ls_tags = self._build_tag_dict(second_ls['tags'])
- self.assertIn('multi_lswitch', main_ls_tags)
- self.assertNotIn('multi_lswitch', second_ls_tags)
- self.assertIn('quantum_net_id', main_ls_tags)
- self.assertIn('quantum_net_id', second_ls_tags)
- self.assertEqual(main_ls_tags['quantum_net_id'],
- network_id)
- self.assertEqual(second_ls_tags['quantum_net_id'],
- network_id)
-
- def test_update_lswitch(self):
- new_name = 'new-name'
- new_tags = [{'scope': 'new_tag', 'tag': 'xxx'}]
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- _uuid(),
- 'pippo',
- 'fake-switch',
- transport_zones_config)
- nvplib.update_lswitch(self.fake_cluster, lswitch['uuid'],
- new_name, tags=new_tags)
- res_lswitch = nvplib.get_lswitches(self.fake_cluster,
- lswitch['uuid'])
- self.assertEqual(len(res_lswitch), 1)
- self.assertEqual(res_lswitch[0]['display_name'], new_name)
- switch_tags = self._build_tag_dict(res_lswitch[0]['tags'])
- self.assertIn('new_tag', switch_tags)
- self.assertEqual(switch_tags['new_tag'], 'xxx')
-
- def test_update_non_existing_lswitch_raises(self):
- self.assertRaises(exceptions.NetworkNotFound,
- nvplib.update_lswitch,
- self.fake_cluster, 'whatever',
- 'foo', 'bar')
-
- def test_delete_networks(self):
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- _uuid(),
- 'pippo',
- 'fake-switch',
- transport_zones_config)
- nvplib.delete_networks(self.fake_cluster, lswitch['uuid'],
- [lswitch['uuid']])
- self.assertRaises(exceptions.NotFound,
- nvplib.get_lswitches,
- self.fake_cluster,
- lswitch['uuid'])
-
- def test_delete_non_existing_lswitch_raises(self):
- self.assertRaises(exceptions.NetworkNotFound,
- nvplib.delete_networks,
- self.fake_cluster, 'whatever', ['whatever'])
-
-
class TestNvplibSecurityProfile(NvplibTestCase):
def test_create_and_get_security_profile(self):
self.fake_cluster, 'whatever')
-class TestNvplibLogicalPorts(NvplibTestCase):
-
- def _create_switch_and_port(self, tenant_id='pippo',
- neutron_port_id='whatever',
- name='name', device_id='device_id'):
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster,
- _uuid(), tenant_id, 'fake-switch',
- transport_zones_config)
- lport = nvplib.create_lport(self.fake_cluster, lswitch['uuid'],
- tenant_id, neutron_port_id,
- name, device_id, True)
- return lswitch, lport
-
- def test_create_and_get_port(self):
- lswitch, lport = self._create_switch_and_port()
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- self.assertEqual(lport['uuid'], lport_res['uuid'])
- # Try again with relation
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'],
- relations='LogicalPortStatus')
- self.assertEqual(lport['uuid'], lport_res['uuid'])
-
- def test_plug_interface(self):
- lswitch, lport = self._create_switch_and_port()
- nvplib.plug_interface(self.fake_cluster, lswitch['uuid'],
- lport['uuid'], 'VifAttachment', 'fake')
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- self.assertEqual(lport['uuid'], lport_res['uuid'])
-
- def test_get_port_by_tag(self):
- lswitch, lport = self._create_switch_and_port()
- lport2 = nvplib.get_port_by_neutron_tag(self.fake_cluster,
- lswitch['uuid'],
- 'whatever')
- self.assertIsNotNone(lport2)
- self.assertEqual(lport['uuid'], lport2['uuid'])
-
- def test_get_port_by_tag_not_found_returns_None(self):
- tenant_id = 'pippo'
- neutron_port_id = 'whatever'
- transport_zones_config = [{'zone_uuid': _uuid(),
- 'transport_type': 'stt'}]
- lswitch = nvplib.create_lswitch(self.fake_cluster, tenant_id, _uuid(),
- 'fake-switch', transport_zones_config)
- lport = nvplib.get_port_by_neutron_tag(self.fake_cluster,
- lswitch['uuid'],
- neutron_port_id)
- self.assertIsNone(lport)
-
- def test_get_port_status(self):
- lswitch, lport = self._create_switch_and_port()
- status = nvplib.get_port_status(self.fake_cluster,
- lswitch['uuid'],
- lport['uuid'])
- self.assertEqual(constants.PORT_STATUS_ACTIVE, status)
-
- def test_get_port_status_non_existent_raises(self):
- self.assertRaises(exceptions.PortNotFoundOnNetwork,
- nvplib.get_port_status,
- self.fake_cluster,
- 'boo', 'boo')
-
- def test_update_port(self):
- lswitch, lport = self._create_switch_and_port()
- nvplib.update_port(
- self.fake_cluster, lswitch['uuid'], lport['uuid'],
- 'neutron_port_id', 'pippo2', 'new_name', 'device_id', False)
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- self.assertEqual(lport['uuid'], lport_res['uuid'])
- self.assertEqual('new_name', lport_res['display_name'])
- self.assertEqual('False', lport_res['admin_status_enabled'])
- port_tags = self._build_tag_dict(lport_res['tags'])
- self.assertIn('os_tid', port_tags)
- self.assertIn('q_port_id', port_tags)
- self.assertIn('vm_id', port_tags)
-
- def test_create_port_device_id_less_than_40_chars(self):
- lswitch, lport = self._create_switch_and_port()
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- port_tags = self._build_tag_dict(lport_res['tags'])
- self.assertEqual('device_id', port_tags['vm_id'])
-
- def test_create_port_device_id_more_than_40_chars(self):
- dev_id = "this_is_a_very_long_device_id_with_lots_of_characters"
- lswitch, lport = self._create_switch_and_port(device_id=dev_id)
- lport_res = nvplib.get_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- port_tags = self._build_tag_dict(lport_res['tags'])
- self.assertNotEqual(len(dev_id), len(port_tags['vm_id']))
-
- def test_get_ports_with_obsolete_and_new_vm_id_tag(self):
- def obsolete(device_id, obfuscate=False):
- return hashlib.sha1(device_id).hexdigest()
-
- with mock.patch.object(nvplib, 'device_id_to_vm_id', new=obsolete):
- dev_id1 = "short-dev-id-1"
- _, lport1 = self._create_switch_and_port(device_id=dev_id1)
- dev_id2 = "short-dev-id-2"
- _, lport2 = self._create_switch_and_port(device_id=dev_id2)
-
- lports = nvplib.get_ports(self.fake_cluster, None, [dev_id1])
- port_tags = self._build_tag_dict(lports['whatever']['tags'])
- self.assertNotEqual(dev_id1, port_tags['vm_id'])
-
- lports = nvplib.get_ports(self.fake_cluster, None, [dev_id2])
- port_tags = self._build_tag_dict(lports['whatever']['tags'])
- self.assertEqual(dev_id2, port_tags['vm_id'])
-
- def test_update_non_existent_port_raises(self):
- self.assertRaises(exceptions.PortNotFoundOnNetwork,
- nvplib.update_port, self.fake_cluster,
- 'boo', 'boo', 'boo', 'boo', 'boo', 'boo', False)
-
- def test_delete_port(self):
- lswitch, lport = self._create_switch_and_port()
- nvplib.delete_port(self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
- self.assertRaises(exceptions.PortNotFoundOnNetwork,
- nvplib.get_port, self.fake_cluster,
- lswitch['uuid'], lport['uuid'])
-
- def test_delete_non_existent_port_raises(self):
- lswitch = self._create_switch_and_port()[0]
- self.assertRaises(exceptions.PortNotFoundOnNetwork,
- nvplib.delete_port, self.fake_cluster,
- lswitch['uuid'], 'bad_port_uuid')
-
- def test_query_lswitch_ports(self):
- lswitch, lport = self._create_switch_and_port()
- switch_port_uuids = [
- nvplib.create_lport(
- self.fake_cluster, lswitch['uuid'], 'pippo', 'qportid-%s' % k,
- 'port-%s' % k, 'deviceid-%s' % k, True)['uuid']
- for k in range(2)]
- switch_port_uuids.append(lport['uuid'])
- ports = nvplib.query_lswitch_lports(self.fake_cluster, lswitch['uuid'])
- self.assertEqual(len(ports), 3)
- for res_port in ports:
- self.assertIn(res_port['uuid'], switch_port_uuids)
-
-
class TestNvplibClusterManagement(NvplibTestCase):
def test_get_cluster_version(self):