diff --git a/doc/source/devref/contribute.rst b/doc/source/devref/contribute.rst index 73c9e8794a7..dd6c220f1c8 100644 --- a/doc/source/devref/contribute.rst +++ b/doc/source/devref/contribute.rst @@ -402,7 +402,7 @@ The following chart captures the following aspects: +-------------------------------+-----------------------+-----------+------------------+---------+--------------+ | networking-bigswitch_ | ml2,core,l3 | no | yes | [C] | Kilo | +-------------------------------+-----------------------+-----------+------------------+---------+--------------+ -| networking-brocade_ | | | | | | +| networking-brocade_ | ml2,l3 | yes | yes | [C] | Kilo | +-------------------------------+-----------------------+-----------+------------------+---------+--------------+ | networking-cisco_ | core,ml2,l3,fw,vpn | yes | yes | [B] | | +-------------------------------+-----------------------+-----------+------------------+---------+--------------+ @@ -452,6 +452,11 @@ Big Switch Networks .. _networking-brocade: +* Git: https://github.com/stackforge/networking-brocade +* Launchpad: https://launchpad.net/networking-brocade +* PyPI: https://pypi.python.org/pypi/networking-brocade + + .. _networking-cisco: Cisco diff --git a/neutron/plugins/ml2/drivers/brocade/README.md b/neutron/plugins/ml2/drivers/brocade/README.md index 9ee4e0b97b6..6a2cb2a5c49 100644 --- a/neutron/plugins/ml2/drivers/brocade/README.md +++ b/neutron/plugins/ml2/drivers/brocade/README.md @@ -1,10 +1,16 @@ Brocade ML2 Mechanism driver from ML2 plugin ============================================ +* The real code now resides in stackforge: + http://github.com/stackforge/networking-brocade + * up-to-date version of these instructions are located at: http://50.56.236.34/docs/brocade-ml2-mechanism.txt + * N.B.: Please see Prerequisites section regarding ncclient (netconf client library) + * Supports VCS (Virtual Cluster of Switches) + * Issues/Questions/Bugs: sharis@brocade.com diff --git a/neutron/plugins/ml2/drivers/brocade/mechanism_brocade.py b/neutron/plugins/ml2/drivers/brocade/mechanism_brocade.py index dd98bf7d4d9..a9953dedcad 100644 --- a/neutron/plugins/ml2/drivers/brocade/mechanism_brocade.py +++ b/neutron/plugins/ml2/drivers/brocade/mechanism_brocade.py @@ -17,17 +17,6 @@ """Implentation of Brocade ML2 Mechanism driver for ML2 Plugin.""" from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import excutils -from oslo_utils import importutils - -from neutron.i18n import _LE, _LI -from neutron.plugins.ml2 import driver_api -from neutron.plugins.ml2.drivers.brocade.db import models as brocade_db - -LOG = logging.getLogger(__name__) -MECHANISM_VERSION = 0.9 -NOS_DRIVER = 'neutron.plugins.ml2.drivers.brocade.nos.nosdriver.NOSdriver' ML2_BROCADE = [cfg.StrOpt('address', default='', help=_('The address of the host to SSH to')), @@ -44,410 +33,3 @@ ML2_BROCADE = [cfg.StrOpt('address', default='', ] cfg.CONF.register_opts(ML2_BROCADE, "ml2_brocade") - - -class BrocadeMechanism(driver_api.MechanismDriver): - """ML2 Mechanism driver for Brocade VDX switches. This is the upper - layer driver class that interfaces to lower layer (NETCONF) below. - - """ - - def __init__(self): - self._driver = None - self._physical_networks = None - self._switch = None - self.initialize() - - def initialize(self): - """Initilize of variables needed by this class.""" - - self._physical_networks = cfg.CONF.ml2_brocade.physical_networks - self.brocade_init() - - def brocade_init(self): - """Brocade specific initialization for this class.""" - - osversion = None - self._switch = { - 'address': cfg.CONF.ml2_brocade.address, - 'username': cfg.CONF.ml2_brocade.username, - 'password': cfg.CONF.ml2_brocade.password, - 'ostype': cfg.CONF.ml2_brocade.ostype, - 'osversion': cfg.CONF.ml2_brocade.osversion} - - self._driver = importutils.import_object(NOS_DRIVER) - - # Detect version of NOS on the switch - osversion = self._switch['osversion'] - if osversion == "autodetect": - osversion = self._driver.get_nos_version( - self._switch['address'], - self._switch['username'], - self._switch['password']) - - virtual_fabric_enabled = self._driver.is_virtual_fabric_enabled( - self._switch['address'], - self._switch['username'], - self._switch['password']) - - if virtual_fabric_enabled: - LOG.debug("Virtual Fabric: enabled") - else: - LOG.debug("Virtual Fabric: not enabled") - - self.set_features_enabled(osversion, virtual_fabric_enabled) - - def set_features_enabled(self, nos_version, virtual_fabric_enabled): - self._virtual_fabric_enabled = virtual_fabric_enabled - version = nos_version.split(".", 2) - - # Starting 4.1.0 port profile domains are supported - if int(version[0]) >= 5 or (int(version[0]) >= 4 - and int(version[1]) >= 1): - self._pp_domains_supported = True - else: - self._pp_domains_supported = False - self._driver.set_features_enabled(self._pp_domains_supported, - self._virtual_fabric_enabled) - - def get_features_enabled(self): - return self._pp_domains_supported, self._virtual_fabric_enabled - - def create_network_precommit(self, mech_context): - """Create Network in the mechanism specific database table.""" - - network = mech_context.current - context = mech_context._plugin_context - tenant_id = network['tenant_id'] - network_id = network['id'] - - segments = mech_context.network_segments - # currently supports only one segment per network - segment = segments[0] - - network_type = segment['network_type'] - vlan_id = segment['segmentation_id'] - segment_id = segment['id'] - - if segment['physical_network'] not in self._physical_networks: - raise Exception( - _("Brocade Mechanism: failed to create network, " - "network cannot be created in the configured " - "physical network")) - - if network_type != 'vlan': - raise Exception( - _("Brocade Mechanism: failed to create network, " - "only network type vlan is supported")) - - try: - brocade_db.create_network(context, network_id, vlan_id, - segment_id, network_type, tenant_id) - except Exception: - LOG.exception( - _LE("Brocade Mechanism: failed to create network in db")) - raise Exception( - _("Brocade Mechanism: create_network_precommit failed")) - - LOG.info(_LI("create network (precommit): %(network_id)s " - "of network type = %(network_type)s " - "with vlan = %(vlan_id)s " - "for tenant %(tenant_id)s"), - {'network_id': network_id, - 'network_type': network_type, - 'vlan_id': vlan_id, - 'tenant_id': tenant_id}) - - def create_network_postcommit(self, mech_context): - """Create Network as a portprofile on the switch.""" - - LOG.debug("create_network_postcommit: called") - - network = mech_context.current - # use network_id to get the network attributes - # ONLY depend on our db for getting back network attributes - # this is so we can replay postcommit from db - context = mech_context._plugin_context - - network_id = network['id'] - network = brocade_db.get_network(context, network_id) - network_type = network['network_type'] - tenant_id = network['tenant_id'] - vlan_id = network['vlan'] - - try: - self._driver.create_network(self._switch['address'], - self._switch['username'], - self._switch['password'], - vlan_id) - except Exception: - LOG.exception(_LE("Brocade NOS driver: failed in create network")) - brocade_db.delete_network(context, network_id) - raise Exception( - _("Brocade Mechanism: create_network_postcommmit failed")) - - LOG.info(_LI("created network (postcommit): %(network_id)s" - " of network type = %(network_type)s" - " with vlan = %(vlan_id)s" - " for tenant %(tenant_id)s"), - {'network_id': network_id, - 'network_type': network_type, - 'vlan_id': vlan_id, - 'tenant_id': tenant_id}) - - def delete_network_precommit(self, mech_context): - """Delete Network from the plugin specific database table.""" - - LOG.debug("delete_network_precommit: called") - - network = mech_context.current - network_id = network['id'] - vlan_id = network['provider:segmentation_id'] - tenant_id = network['tenant_id'] - - context = mech_context._plugin_context - - try: - brocade_db.delete_network(context, network_id) - except Exception: - LOG.exception( - _LE("Brocade Mechanism: failed to delete network in db")) - raise Exception( - _("Brocade Mechanism: delete_network_precommit failed")) - - LOG.info(_LI("delete network (precommit): %(network_id)s" - " with vlan = %(vlan_id)s" - " for tenant %(tenant_id)s"), - {'network_id': network_id, - 'vlan_id': vlan_id, - 'tenant_id': tenant_id}) - - def delete_network_postcommit(self, mech_context): - """Delete network which translates to removng portprofile - from the switch. - """ - - LOG.debug("delete_network_postcommit: called") - network = mech_context.current - network_id = network['id'] - vlan_id = network['provider:segmentation_id'] - tenant_id = network['tenant_id'] - - try: - self._driver.delete_network(self._switch['address'], - self._switch['username'], - self._switch['password'], - vlan_id) - except Exception: - LOG.exception(_LE("Brocade NOS driver: failed to delete network")) - raise Exception( - _("Brocade switch exception, " - "delete_network_postcommit failed")) - - LOG.info(_LI("delete network (postcommit): %(network_id)s" - " with vlan = %(vlan_id)s" - " for tenant %(tenant_id)s"), - {'network_id': network_id, - 'vlan_id': vlan_id, - 'tenant_id': tenant_id}) - - def update_network_precommit(self, mech_context): - """Noop now, it is left here for future.""" - pass - - def update_network_postcommit(self, mech_context): - """Noop now, it is left here for future.""" - pass - - def create_port_precommit(self, mech_context): - """Create logical port on the switch (db update).""" - - LOG.debug("create_port_precommit: called") - - port = mech_context.current - port_id = port['id'] - network_id = port['network_id'] - tenant_id = port['tenant_id'] - admin_state_up = port['admin_state_up'] - - context = mech_context._plugin_context - - network = brocade_db.get_network(context, network_id) - vlan_id = network['vlan'] - - try: - brocade_db.create_port(context, port_id, network_id, - None, - vlan_id, tenant_id, admin_state_up) - except Exception: - LOG.exception(_LE("Brocade Mechanism: failed to create port" - " in db")) - raise Exception( - _("Brocade Mechanism: create_port_precommit failed")) - - def create_port_postcommit(self, mech_context): - """Associate the assigned MAC address to the portprofile.""" - - LOG.debug("create_port_postcommit: called") - - port = mech_context.current - port_id = port['id'] - network_id = port['network_id'] - tenant_id = port['tenant_id'] - - context = mech_context._plugin_context - - self._associate_mac_to_net(context, network_id, port['mac_address'], - "create_port_postcommit") - - LOG.info( - _LI("created port (postcommit): port_id=%(port_id)s" - " network_id=%(network_id)s tenant_id=%(tenant_id)s"), - {'port_id': port_id, - 'network_id': network_id, 'tenant_id': tenant_id}) - - def delete_port_precommit(self, mech_context): - """Delete logical port on the switch (db update).""" - - LOG.debug("delete_port_precommit: called") - port = mech_context.current - port_id = port['id'] - - context = mech_context._plugin_context - - try: - brocade_db.delete_port(context, port_id) - except Exception: - LOG.exception(_LE("Brocade Mechanism: failed to delete port" - " in db")) - raise Exception( - _("Brocade Mechanism: delete_port_precommit failed")) - - def delete_port_postcommit(self, mech_context): - """Dissociate MAC address from the portprofile.""" - - LOG.debug("delete_port_postcommit: called") - port = mech_context.current - port_id = port['id'] - network_id = port['network_id'] - tenant_id = port['tenant_id'] - - context = mech_context._plugin_context - - self._dissociate_mac_from_net(context, network_id, port['mac_address'], - "delete_port_postcommit") - - LOG.info( - _LI("delete port (postcommit): port_id=%(port_id)s" - " network_id=%(network_id)s tenant_id=%(tenant_id)s"), - {'port_id': port_id, - 'network_id': network_id, 'tenant_id': tenant_id}) - - def update_port_precommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("update_port_precommit(self: called") - - def update_port_postcommit(self, mech_context): - """If mac changes, update association to network.""" - - LOG.debug("update_port_postcommit: called") - port = mech_context.current - old_port = mech_context.original - if port['mac_address'] == old_port['mac_address']: - return - port_id = port['id'] - network_id = port['network_id'] - tenant_id = port['tenant_id'] - - context = mech_context._plugin_context - - self._dissociate_mac_from_net(context, network_id, - old_port['mac_address'], - "update_port_postcommit") - self._associate_mac_to_net(context, network_id, port['mac_address'], - "update_port_postcommit") - - LOG.info( - _LI("update port (postcommit): port_id=%(port_id)s" - " network_id=%(network_id)s tenant_id=%(tenant_id)s."), - {'port_id': port_id, - 'network_id': network_id, 'tenant_id': tenant_id}) - - def create_subnet_precommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("create_subnetwork_precommit: called") - - def create_subnet_postcommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("create_subnetwork_postcommit: called") - - def delete_subnet_precommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("delete_subnetwork_precommit: called") - - def delete_subnet_postcommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("delete_subnetwork_postcommit: called") - - def update_subnet_precommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("update_subnet_precommit(self: called") - - def update_subnet_postcommit(self, mech_context): - """Noop now, it is left here for future.""" - LOG.debug("update_subnet_postcommit: called") - - def _associate_mac_to_net(self, context, network_id, interface_mac, op): - network = brocade_db.get_network(context, network_id) - vlan_id = network['vlan'] - - # convert mac format: xx:xx:xx:xx:xx:xx -> xxxx.xxxx.xxxx - mac = self.mac_reformat_62to34(interface_mac) - try: - self._driver.associate_mac_to_network(self._switch['address'], - self._switch['username'], - self._switch['password'], - vlan_id, - mac) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception( - _LE("Brocade NOS driver: failed to associate mac %s"), - interface_mac) - - def _dissociate_mac_from_net(self, context, network_id, interface_mac, op): - - network = brocade_db.get_network(context, network_id) - vlan_id = network['vlan'] - - # convert mac format: xx:xx:xx:xx:xx:xx -> xxxx.xxxx.xxxx - mac = self.mac_reformat_62to34(interface_mac) - try: - self._driver.dissociate_mac_from_network( - self._switch['address'], - self._switch['username'], - self._switch['password'], - vlan_id, - mac) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception( - _LE("Brocade NOS driver: failed to dissociate MAC %s"), - interface_mac) - - @staticmethod - def mac_reformat_62to34(interface_mac): - """Transform MAC address format. - - Transforms from 6 groups of 2 hexadecimal numbers delimited by ":" - to 3 groups of 4 hexadecimals numbers delimited by ".". - - :param interface_mac: MAC address in the format xx:xx:xx:xx:xx:xx - :type interface_mac: string - :returns: MAC address in the format xxxx.xxxx.xxxx - :rtype: string - """ - - mac = interface_mac.replace(":", "") - mac = mac[0:4] + "." + mac[4:8] + "." + mac[8:12] - return mac diff --git a/neutron/plugins/ml2/drivers/brocade/nos/__init__.py b/neutron/plugins/ml2/drivers/brocade/nos/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/neutron/plugins/ml2/drivers/brocade/nos/nctemplates.py b/neutron/plugins/ml2/drivers/brocade/nos/nctemplates.py deleted file mode 100644 index f52c8c9f5f9..00000000000 --- a/neutron/plugins/ml2/drivers/brocade/nos/nctemplates.py +++ /dev/null @@ -1,433 +0,0 @@ -# Copyright (c) 2014 Brocade Communications Systems, 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. - - -"""NOS NETCONF XML Configuration Command Templates. - -Interface Configuration Commands -""" - -# Get NOS Version -SHOW_FIRMWARE_VERSION = ( - "show-firmware-version xmlns:nc=" - "'urn:brocade.com:mgmt:brocade-firmware-ext'" -) -GET_VCS_DETAILS = ( - 'get-vcs-details xmlns:nc="urn:brocade.com:mgmt:brocade-vcs"' -) -SHOW_VIRTUAL_FABRIC = ( - 'show-virtual-fabric xmlns:nc="urn:brocade.com:mgmt:brocade-vcs"' -) -GET_VIRTUAL_FABRIC_INFO = ( - 'interface xmlns:nc="urn:brocade.com:mgmt:brocade-firmware-ext"' -) - -NOS_VERSION = "./*/{urn:brocade.com:mgmt:brocade-firmware-ext}os-version" -VFAB_ENABLE = "./*/*/*/{urn:brocade.com:mgmt:brocade-vcs}vfab-enable" - -# Create VLAN (vlan_id) -CREATE_VLAN_INTERFACE = """ - - - - - {vlan_id} - - - - -""" - -# Delete VLAN (vlan_id) -DELETE_VLAN_INTERFACE = """ - - - - - {vlan_id} - - - - -""" - -# -# AMPP Life-cycle Management Configuration Commands -# - -# Create AMPP port-profile (port_profile_name) -CREATE_PORT_PROFILE = """ - - - {name} - - -""" - -# Create VLAN sub-profile for port-profile (port_profile_name) -CREATE_VLAN_PROFILE_FOR_PORT_PROFILE = """ - - - {name} - - - -""" - -# Configure L2 mode for VLAN sub-profile (port_profile_name) -CONFIGURE_L2_MODE_FOR_VLAN_PROFILE_IN_DOMAIN = """ - - - {name} - - - - - - - -""" - -# Configure L2 mode for VLAN sub-profile (port_profile_name) -CONFIGURE_L2_MODE_FOR_VLAN_PROFILE = """ - - - {name} - - - - - -""" - -# Configure trunk mode for VLAN sub-profile (port_profile_name) -CONFIGURE_TRUNK_MODE_FOR_VLAN_PROFILE = """ - - - {name} - - - - trunk - - - - - -""" - -# Configure allowed VLANs for VLAN sub-profile -# (port_profile_name, allowed_vlan, native_vlan) -CONFIGURE_ALLOWED_VLANS_FOR_VLAN_PROFILE = """ - - - {name} - - - - - - {vlan_id} - - - - - - - -""" - -# Delete port-profile (port_profile_name) -DELETE_PORT_PROFILE = """ - - - {name} - - -""" - -# Activate port-profile (port_profile_name) -ACTIVATE_PORT_PROFILE = """ - - - - {name} - - - - -""" - -# Deactivate port-profile (port_profile_name) -DEACTIVATE_PORT_PROFILE = """ - - - - {name} - - - - -""" - -# Associate MAC address to port-profile (port_profile_name, mac_address) -ASSOCIATE_MAC_TO_PORT_PROFILE = """ - - - - {name} - - {mac_address} - - - - -""" - -# Dissociate MAC address from port-profile (port_profile_name, mac_address) -DISSOCIATE_MAC_FROM_PORT_PROFILE = """ - - - - {name} - - {mac_address} - - - - -""" - -# port-profile domain management commands -REMOVE_PORTPROFILE_FROM_DOMAIN = """ - - - {domain_name} - - {name} - - - -""" -# put port profile in default domain -CONFIGURE_PORTPROFILE_IN_DOMAIN = """ - - - {domain_name} - - {name} - - - -""" - -# -# L3 Life-cycle Management Configuration Commands -# - -# Create SVI and assign ippaddres (rbridge_id,vlan_id,ip_address) -CONFIGURE_SVI_WITH_IP_ADDRESS = """ - - - {rbridge_id} - - - {vlan_id} - - -
-
{ip_address}
-
-
-
-
-
-
-
-""" - -# delete SVI (rbridge_id,vlan_id) -DELETE_SVI = """ - - - {rbridge_id} - - - {vlan_id} - - - - -""" - -# Activate SVI (rbridge_id,vlan_id) -ACTIVATE_SVI = """ - - - {rbridge_id} - - - {vlan_id} - - - - - -""" - -# Remove ipaddress from SVI (rbridge_id,vlan_id) -DECONFIGURE_IP_FROM_SVI = """ - - - {rbridge_id} - - - {vlan_id} - - -
-
{gw_ip}
-
-
-
-
-
-
-
-""" - -# create vrf (rbridge_id,vrf_name) -CREATE_VRF = """ - - - {rbridge_id} - - {vrf_name} - - - -""" - - -# delete vrf (rbridge_id,vrf_name) -DELETE_VRF = """ - - - {rbridge_id} - - {vrf_name} - - - -""" - -# configure route distinguisher for vrf (rbridge_id,vrf_name, rd) -CONFIGURE_RD_FOR_VRF = """ - - - {rbridge_id} - - {vrf_name} - {rd} - - - -""" - -# configure address-family for vrf (rbridge_id,vrf_name) -ADD_ADDRESS_FAMILY_FOR_VRF_V1 = """ - - - {rbridge_id} - - {vrf_name} - - - 1200 - - - - - -""" - -# configure address-family for vrf (rbridge_id,vrf_name) -ADD_ADDRESS_FAMILY_FOR_VRF = """ - - - {rbridge_id} - - {vrf_name} - - - - - - - - -""" - -# Bind vrf to SVI (rbridge_id,vlan_idi, vrf) -ADD_VRF_TO_SVI = """ - - - {rbridge_id} - - - {vlan_id} - - {vrf_name} - - - - - -""" - -# unbind vrf from SVI (rbridge_id,vlan_idi, vrf) -DELETE_VRF_FROM_SVI = """ - - - {rbridge_id} - - - {vlan_id} - - {vrf_name} - - - - - -""" - -# -# Constants -# - -# Port profile naming convention for Neutron networks -OS_PORT_PROFILE_NAME = "openstack-profile-{id}" -OS_VRF_NAME = "osv-{id}" - -# Port profile filter expressions -PORT_PROFILE_XPATH_FILTER = "/port-profile" -PORT_PROFILE_NAME_XPATH_FILTER = "/port-profile[name='{name}']" diff --git a/neutron/plugins/ml2/drivers/brocade/nos/nosdriver.py b/neutron/plugins/ml2/drivers/brocade/nos/nosdriver.py deleted file mode 100644 index 1ae52d331fe..00000000000 --- a/neutron/plugins/ml2/drivers/brocade/nos/nosdriver.py +++ /dev/null @@ -1,485 +0,0 @@ -# Copyright 2014 Brocade Communications System, 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. - - -"""Brocade NOS Driver implements NETCONF over SSHv2 for -Neutron network life-cycle management. -""" - -from ncclient import manager -from oslo_log import log as logging -from oslo_utils import excutils -from xml.etree import ElementTree - -from neutron.i18n import _LE -from neutron.plugins.ml2.drivers.brocade.nos import nctemplates as template - - -LOG = logging.getLogger(__name__) -SSH_PORT = 22 - - -def nos_unknown_host_cb(host, fingerprint): - """An unknown host callback. - - Returns `True` if it finds the key acceptable, - and `False` if not. This default callback for NOS always returns 'True' - (i.e. trusts all hosts for now). - """ - return True - - -class NOSdriver(object): - """NOS NETCONF interface driver for Neutron network. - - Handles life-cycle management of Neutron network (leverages AMPP on NOS) - """ - - def __init__(self): - self.mgr = None - self._virtual_fabric_enabled = False - self._pp_domains_supported = False - - def set_features_enabled(self, pp_domains_supported, - virtual_fabric_enabled): - """Set features in the driver based on what was detected by the MD.""" - self._pp_domains_supported = pp_domains_supported - self._virtual_fabric_enabled = virtual_fabric_enabled - - def get_features_enabled(self): - """Respond to status of features enabled.""" - return self._pp_domains_supported, self._virtual_fabric_enabled - - def connect(self, host, username, password): - """Connect via SSH and initialize the NETCONF session.""" - - # Use the persisted NETCONF connection - if self.mgr and self.mgr.connected: - return self.mgr - - # check if someone forgot to edit the conf file with real values - if host == '': - raise Exception(_("Brocade Switch IP address is not set, " - "check config ml2_conf_brocade.ini file")) - - # Open new NETCONF connection - try: - self.mgr = manager.connect(host=host, port=SSH_PORT, - username=username, password=password, - unknown_host_cb=nos_unknown_host_cb) - - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("Connect failed to switch")) - - LOG.debug("Connect success to host %(host)s:%(ssh_port)d", - dict(host=host, ssh_port=SSH_PORT)) - return self.mgr - - def close_session(self): - """Close NETCONF session.""" - if self.mgr: - self.mgr.close_session() - self.mgr = None - - def get_nos_version(self, host, username, password): - """Show version of NOS.""" - try: - mgr = self.connect(host, username, password) - return self.nos_version_request(mgr) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def is_virtual_fabric_enabled(self, host, username, password): - """Show version of NOS.""" - try: - mgr = self.connect(host, username, password) - return (self.virtual_fabric_info(mgr) == "enabled") - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def create_network(self, host, username, password, net_id): - """Creates a new virtual network.""" - - domain_name = "default" - name = template.OS_PORT_PROFILE_NAME.format(id=net_id) - try: - mgr = self.connect(host, username, password) - self.create_vlan_interface(mgr, net_id) - self.create_port_profile(mgr, name) - - if self._pp_domains_supported and self._virtual_fabric_enabled: - self.configure_port_profile_in_domain(mgr, domain_name, name) - - self.create_vlan_profile_for_port_profile(mgr, name) - - if self._pp_domains_supported: - self.configure_l2_mode_for_vlan_profile_with_domains(mgr, name) - else: - self.configure_l2_mode_for_vlan_profile(mgr, name) - - self.configure_trunk_mode_for_vlan_profile(mgr, name) - self.configure_allowed_vlans_for_vlan_profile(mgr, name, net_id) - self.activate_port_profile(mgr, name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def delete_network(self, host, username, password, net_id): - """Deletes a virtual network.""" - - domain_name = "default" - name = template.OS_PORT_PROFILE_NAME.format(id=net_id) - try: - mgr = self.connect(host, username, password) - if self._pp_domains_supported and self._virtual_fabric_enabled: - self.remove_port_profile_from_domain(mgr, domain_name, name) - self.deactivate_port_profile(mgr, name) - self.delete_port_profile(mgr, name) - self.delete_vlan_interface(mgr, net_id) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def associate_mac_to_network(self, host, username, password, - net_id, mac): - """Associates a MAC address to virtual network.""" - - name = template.OS_PORT_PROFILE_NAME.format(id=net_id) - try: - mgr = self.connect(host, username, password) - self.associate_mac_to_port_profile(mgr, name, mac) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def dissociate_mac_from_network(self, host, username, password, - net_id, mac): - """Dissociates a MAC address from virtual network.""" - - name = template.OS_PORT_PROFILE_NAME.format(id=net_id) - try: - mgr = self.connect(host, username, password) - self.dissociate_mac_from_port_profile(mgr, name, mac) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def create_vlan_interface(self, mgr, vlan_id): - """Configures a VLAN interface.""" - - confstr = template.CREATE_VLAN_INTERFACE.format(vlan_id=vlan_id) - mgr.edit_config(target='running', config=confstr) - - def delete_vlan_interface(self, mgr, vlan_id): - """Deletes a VLAN interface.""" - - confstr = template.DELETE_VLAN_INTERFACE.format(vlan_id=vlan_id) - mgr.edit_config(target='running', config=confstr) - - def get_port_profiles(self, mgr): - """Retrieves all port profiles.""" - - filterstr = template.PORT_PROFILE_XPATH_FILTER - response = mgr.get_config(source='running', - filter=('xpath', filterstr)).data_xml - return response - - def get_port_profile(self, mgr, name): - """Retrieves a port profile.""" - - filterstr = template.PORT_PROFILE_NAME_XPATH_FILTER.format(name=name) - response = mgr.get_config(source='running', - filter=('xpath', filterstr)).data_xml - return response - - def create_port_profile(self, mgr, name): - """Creates a port profile.""" - - confstr = template.CREATE_PORT_PROFILE.format(name=name) - mgr.edit_config(target='running', config=confstr) - - def delete_port_profile(self, mgr, name): - """Deletes a port profile.""" - - confstr = template.DELETE_PORT_PROFILE.format(name=name) - mgr.edit_config(target='running', config=confstr) - - def activate_port_profile(self, mgr, name): - """Activates a port profile.""" - - confstr = template.ACTIVATE_PORT_PROFILE.format(name=name) - mgr.edit_config(target='running', config=confstr) - - def deactivate_port_profile(self, mgr, name): - """Deactivates a port profile.""" - - confstr = template.DEACTIVATE_PORT_PROFILE.format(name=name) - mgr.edit_config(target='running', config=confstr) - - def associate_mac_to_port_profile(self, mgr, name, mac_address): - """Associates a MAC address to a port profile.""" - - confstr = template.ASSOCIATE_MAC_TO_PORT_PROFILE.format( - name=name, mac_address=mac_address) - mgr.edit_config(target='running', config=confstr) - - def dissociate_mac_from_port_profile(self, mgr, name, mac_address): - """Dissociates a MAC address from a port profile.""" - - confstr = template.DISSOCIATE_MAC_FROM_PORT_PROFILE.format( - name=name, mac_address=mac_address) - mgr.edit_config(target='running', config=confstr) - - def create_vlan_profile_for_port_profile(self, mgr, name): - """Creates VLAN sub-profile for port profile.""" - - confstr = template.CREATE_VLAN_PROFILE_FOR_PORT_PROFILE.format( - name=name) - mgr.edit_config(target='running', config=confstr) - - def configure_l2_mode_for_vlan_profile(self, mgr, name): - """Configures L2 mode for VLAN sub-profile.""" - - confstr = template.CONFIGURE_L2_MODE_FOR_VLAN_PROFILE.format( - name=name) - mgr.edit_config(target='running', config=confstr) - - def configure_trunk_mode_for_vlan_profile(self, mgr, name): - """Configures trunk mode for VLAN sub-profile.""" - - confstr = template.CONFIGURE_TRUNK_MODE_FOR_VLAN_PROFILE.format( - name=name) - mgr.edit_config(target='running', config=confstr) - - def configure_allowed_vlans_for_vlan_profile(self, mgr, name, vlan_id): - """Configures allowed VLANs for VLAN sub-profile.""" - - confstr = template.CONFIGURE_ALLOWED_VLANS_FOR_VLAN_PROFILE.format( - name=name, vlan_id=vlan_id) - mgr.edit_config(target='running', config=confstr) - - def remove_port_profile_from_domain(self, mgr, domain_name, name): - """Remove port-profile from default domain.""" - confstr = template.REMOVE_PORTPROFILE_FROM_DOMAIN.format( - domain_name=domain_name, name=name) - mgr.edit_config(target='running', config=confstr) - - def configure_port_profile_in_domain(self, mgr, domain_name, name): - """put port-profile in default domain.""" - confstr = template.CONFIGURE_PORTPROFILE_IN_DOMAIN.format( - domain_name=domain_name, name=name) - mgr.edit_config(target='running', config=confstr) - - def configure_l2_mode_for_vlan_profile_with_domains(self, mgr, name): - """Configures L2 mode for VLAN sub-profile.""" - confstr = template.CONFIGURE_L2_MODE_FOR_VLAN_PROFILE_IN_DOMAIN.format( - name=name) - mgr.edit_config(target='running', config=confstr) - - def nos_version_request(self, mgr): - """Get firmware information using NETCONF rpc.""" - reply = mgr.dispatch(template.SHOW_FIRMWARE_VERSION, None, None) - et = ElementTree.fromstring(str(reply)) - return et.find(template.NOS_VERSION).text - - def virtual_fabric_info(self, mgr): - """Get virtual fabric info using NETCONF get-config.""" - response = mgr.get_config('running', - filter=("xpath", "/vcs/virtual-fabric")) - et = ElementTree.fromstring(str(response)) - vfab_enable = et.find(template.VFAB_ENABLE) - if vfab_enable is not None: - return "enabled" - return "disabled" - - def create_svi(self, host, username, password, - rbridge_id, vlan_id, ip_address, router_id): - """create svi on configured rbridge-id.""" - try: - mgr = self.connect(host, username, password) - self.bind_vrf_to_svi(host, username, password, - rbridge_id, vlan_id, router_id) - self.configure_svi_with_ip_address(mgr, - rbridge_id, vlan_id, ip_address) - self.activate_svi(mgr, rbridge_id, vlan_id) - except Exception as ex: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error: %s"), ex) - self.close_session() - - def delete_svi(self, host, username, password, - rbridge_id, vlan_id, gw_ip, router_id): - """delete svi from configured rbridge-id.""" - try: - mgr = self.connect(host, username, password) - self.remove_svi(mgr, rbridge_id, vlan_id) - except Exception as ex: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error: %s"), ex) - self.close_session() - - def create_router(self, host, username, password, rbridge_id, router_id): - """create vrf and associate vrf.""" - router_id = router_id[0:11] - vrf_name = template.OS_VRF_NAME.format(id=router_id) - rd = router_id + ":" + router_id - try: - mgr = self.connect(host, username, password) - self.create_vrf(mgr, rbridge_id, vrf_name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - try: - # For Nos5.0.0 - self.configure_rd_for_vrf(mgr, rbridge_id, vrf_name, rd) - self.configure_address_family_for_vrf(mgr, rbridge_id, vrf_name) - except Exception: - with excutils.save_and_reraise_exception() as ctxt: - try: - # This is done because on 4.0.0 rd doesnt accept alpha - # character nor hyphen - rd = "".join(i for i in router_id if i in "0123456789") - rd = rd[:4] + ":" + rd[:4] - self.configure_rd_for_vrf(mgr, rbridge_id, vrf_name, rd) - self.configure_address_family_for_vrf_v1(mgr, - rbridge_id, - vrf_name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - ctxt.reraise = False - - def delete_router(self, host, username, password, rbridge_id, router_id): - """delete router and associated vrf.""" - router_id = router_id[0:11] - vrf_name = template.OS_VRF_NAME.format(id=router_id) - try: - mgr = self.connect(host, username, password) - self.delete_vrf(mgr, rbridge_id, vrf_name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def bind_vrf_to_svi(self, host, username, password, rbridge_id, - vlan_id, router_id): - """binds vrf to a svi.""" - router_id = router_id[0:11] - vrf_name = template.OS_VRF_NAME.format(id=router_id) - try: - mgr = self.connect(host, username, password) - self.add_vrf_to_svi(mgr, rbridge_id, vlan_id, vrf_name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def unbind_vrf_to_svi(self, host, username, password, rbridge_id, - vlan_id, router_id): - """unbind vrf from the svi.""" - router_id = router_id[0:11] - vrf_name = template.OS_VRF_NAME.format(id=router_id) - try: - mgr = self.connect(host, username, password) - self.delete_vrf_from_svi(mgr, rbridge_id, vlan_id, vrf_name) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("NETCONF error")) - self.close_session() - - def create_vrf(self, mgr, rbridge_id, vrf_name): - """create vrf on rbridge.""" - confstr = template.CREATE_VRF.format(rbridge_id=rbridge_id, - vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def delete_vrf(self, mgr, rbridge_id, vrf_name): - """delete vrf on rbridge.""" - - confstr = template.DELETE_VRF.format(rbridge_id=rbridge_id, - vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def configure_rd_for_vrf(self, mgr, rbridge_id, vrf_name, rd): - """configure rd on vrf on rbridge.""" - - confstr = template.CONFIGURE_RD_FOR_VRF.format(rbridge_id=rbridge_id, - vrf_name=vrf_name, - rd=rd) - mgr.edit_config(target='running', config=confstr) - - def configure_address_family_for_vrf_v1(self, mgr, rbridge_id, vrf_name): - """configure ipv4 address family to vrf on rbridge.""" - - confstr = template.ADD_ADDRESS_FAMILY_FOR_VRF_V1.format( - rbridge_id=rbridge_id, - vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def configure_address_family_for_vrf(self, mgr, rbridge_id, vrf_name): - """configure ipv4 address family to vrf on rbridge.""" - - confstr = template.ADD_ADDRESS_FAMILY_FOR_VRF.format( - rbridge_id=rbridge_id, vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def configure_svi_with_ip_address(self, mgr, rbridge_id, - vlan_id, ip_address): - """configure SVI with ip address on rbridge.""" - - confstr = template.CONFIGURE_SVI_WITH_IP_ADDRESS.format( - rbridge_id=rbridge_id, - vlan_id=vlan_id, - ip_address=ip_address) - - mgr.edit_config(target='running', config=confstr) - - def activate_svi(self, mgr, rbridge_id, vlan_id): - """activate the svi on the rbridge.""" - confstr = template.ACTIVATE_SVI.format(rbridge_id=rbridge_id, - vlan_id=vlan_id) - mgr.edit_config(target='running', config=confstr) - - def add_vrf_to_svi(self, mgr, rbridge_id, vlan_id, vrf_name): - """add vrf to svi on rbridge.""" - confstr = template.ADD_VRF_TO_SVI.format(rbridge_id=rbridge_id, - vlan_id=vlan_id, - vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def delete_vrf_from_svi(self, mgr, rbridge_id, vlan_id, vrf_name): - """delete vrf from svi on rbridge.""" - confstr = template.DELETE_VRF_FROM_SVI.format(rbridge_id=rbridge_id, - vlan_id=vlan_id, - vrf_name=vrf_name) - mgr.edit_config(target='running', config=confstr) - - def remove_svi(self, mgr, rbridge_id, vlan_id): - """delete vrf from svi on rbridge.""" - confstr = template.DELETE_SVI.format(rbridge_id=rbridge_id, - vlan_id=vlan_id) - mgr.edit_config(target='running', config=confstr) diff --git a/neutron/plugins/ml2/drivers/brocade/requirements.txt b/neutron/plugins/ml2/drivers/brocade/requirements.txt new file mode 100644 index 00000000000..15f03ff5cc7 --- /dev/null +++ b/neutron/plugins/ml2/drivers/brocade/requirements.txt @@ -0,0 +1 @@ +networking-brocade diff --git a/neutron/services/l3_router/brocade/l3_router_plugin.py b/neutron/services/l3_router/brocade/l3_router_plugin.py index 1be98dc5edc..c4b3a678097 100644 --- a/neutron/services/l3_router/brocade/l3_router_plugin.py +++ b/neutron/services/l3_router/brocade/l3_router_plugin.py @@ -18,20 +18,6 @@ """Implentation of Brocade SVI service Plugin.""" from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import excutils - -from neutron.common import constants as l3_constants -from neutron.i18n import _LE, _LI -from neutron.plugins.ml2 import db -from neutron.plugins.ml2.drivers.brocade.db import models as brocade_db -from neutron.plugins.ml2.drivers.brocade.nos import nosdriver as driver -from neutron.services.l3_router import l3_router_plugin as router - - -DEVICE_OWNER_ROUTER_INTF = l3_constants.DEVICE_OWNER_ROUTER_INTF -DEVICE_OWNER_ROUTER_GW = l3_constants.DEVICE_OWNER_ROUTER_GW -DEVICE_OWNER_FLOATINGIP = l3_constants.DEVICE_OWNER_FLOATINGIP ML2_BROCADE = [cfg.StrOpt('address', default='', help=_('The address of the host to SSH to')), @@ -44,194 +30,3 @@ ML2_BROCADE = [cfg.StrOpt('address', default='', ] cfg.CONF.register_opts(ML2_BROCADE, "ml2_brocade") - -LOG = logging.getLogger(__name__) - - -class BrocadeSVIPlugin(router.L3RouterPlugin): - """Brocade SVI service Plugin.""" - - def __init__(self): - """Initialize Brocade Plugin - - Specify switch address and db configuration. - """ - super(BrocadeSVIPlugin, self).__init__() - self._switch = None - self._driver = None - self.brocade_init() - - def brocade_init(self): - """Brocade specific initialization.""" - LOG.debug("brocadeSVIPlugin::brocade_init()") - - self._switch = {'address': cfg.CONF.ml2_brocade.address, - 'username': cfg.CONF.ml2_brocade.username, - 'password': cfg.CONF.ml2_brocade.password, - 'rbridge_id': cfg.CONF.ml2_brocade.rbridge_id - } - self._driver = driver.NOSdriver() - LOG.info(_LI("rbridge id %s"), self._switch['rbridge_id']) - - def create_router(self, context, router): - """Creates a vrf on NOS device.""" - LOG.debug("BrocadeSVIPlugin.create_router called: ") - with context.session.begin(subtransactions=True): - new_router = super(BrocadeSVIPlugin, self).create_router(context, - router) - # Router on VDX - try: - switch = self._switch - self._driver.create_router(switch['address'], - switch['username'], - switch['password'], - switch['rbridge_id'], - str(new_router['id'])) - except Exception: - with excutils.save_and_reraise_exception(): - with context.session.begin(subtransactions=True): - super(BrocadeSVIPlugin, self).delete_router( - context, - new_router['id']) - - LOG.debug("BrocadeSVIPlugin.create_router: " - "router created on VDX switch") - return new_router - - def delete_router(self, context, router_id): - """Delete a vrf on NOS device.""" - router = super(BrocadeSVIPlugin, self).get_router(context, router_id) - super(BrocadeSVIPlugin, self).delete_router(context, router_id) - - switch = self._switch - self._driver.delete_router(switch['address'], - switch['username'], - switch['password'], - switch['rbridge_id'], - str(router['id'])) - - def add_router_interface(self, context, router_id, interface_info): - """creates svi on NOS device and assigns ip address to SVI.""" - LOG.debug("BrocadeSVIPlugin.add_router_interface on VDX: " - "router_id=%(router_id)s " - "interface_info=%(interface_info)r", - {'router_id': router_id, 'interface_info': interface_info}) - - with context.session.begin(subtransactions=True): - - info = super(BrocadeSVIPlugin, self).add_router_interface( - context, router_id, interface_info) - - port = db.get_port(context.session, info["port_id"]) - - # shutting down neutron port to allow NOS to do Arp/Routing - port['admin_state_up'] = False - port['port'] = port - self._core_plugin.update_port(context, info["port_id"], port) - - interface_info = info - subnet = self._core_plugin._get_subnet(context, - interface_info["subnet_id"]) - cidr = subnet["cidr"] - net_addr, net_len = self.net_addr(cidr) - gateway_ip = subnet["gateway_ip"] - network_id = subnet['network_id'] - bnet = brocade_db.get_network(context, network_id) - vlan_id = bnet['vlan'] - gateway_ip_cidr = gateway_ip + '/' + str(net_len) - LOG.debug("Allocated cidr %(cidr)s from the pool, " - "network_id %(net_id)s " - "bnet %(bnet)s " - "vlan %(vlan_id)d ", {'cidr': gateway_ip_cidr, - 'net_id': network_id, - 'bnet': bnet, - 'vlan_id': int(vlan_id)}) - port_filters = {'network_id': [network_id], - 'device_owner': [DEVICE_OWNER_ROUTER_INTF]} - port_count = self._core_plugin.get_ports_count(context, - port_filters) - LOG.info(_LI("BrocadeSVIPlugin.add_router_interface ports_count " - "%d"), - port_count) - - # port count is checked against 2 since the current port is already - # added to db - if port_count == 2: - # This subnet is already part of some router - # (this is not supported in this version of brocade svi plugin) - msg = _("BrocadeSVIPlugin: adding redundant router interface " - "is not supported") - LOG.error(msg) - raise Exception(msg) - - try: - switch = self._switch - self._driver.create_svi(switch['address'], - switch['username'], - switch['password'], - switch['rbridge_id'], - vlan_id, - gateway_ip_cidr, - str(router_id)) - except Exception: - LOG.error(_LE("Failed to create Brocade resources to add router " - "interface. info=%(info)s, router_id=%(router_id)s"), - {"info": info, "router_id": router_id}) - with excutils.save_and_reraise_exception(): - with context.session.begin(subtransactions=True): - self.remove_router_interface(context, router_id, - interface_info) - return info - - def remove_router_interface(self, context, router_id, interface_info): - """Deletes svi from NOS device.""" - LOG.debug("BrocadeSVIPlugin.remove_router_interface called: " - "router_id=%(router_id)s " - "interface_info=%(interface_info)r", - {'router_id': router_id, 'interface_info': interface_info}) - - with context.session.begin(subtransactions=True): - info = super(BrocadeSVIPlugin, self).remove_router_interface( - context, router_id, interface_info) - try: - subnet = self._core_plugin._get_subnet(context, - info['subnet_id']) - cidr = subnet['cidr'] - net_addr, net_len = self.net_addr(cidr) - gateway_ip = subnet['gateway_ip'] - network_id = subnet['network_id'] - bnet = brocade_db.get_network(context, network_id) - vlan_id = bnet['vlan'] - gateway_ip_cidr = gateway_ip + '/' + str(net_len) - LOG.debug("remove_router_interface removed cidr %(cidr)s" - " from the pool," - " network_id %(net_id)s bnet %(bnet)s" - " vlan %(vlan_id)d", - {'cidr': gateway_ip_cidr, - 'net_id': network_id, - 'bnet': bnet, - 'vlan_id': int(vlan_id)}) - switch = self._switch - self._driver.delete_svi(switch['address'], - switch['username'], - switch['password'], - switch['rbridge_id'], - vlan_id, - gateway_ip_cidr, - str(router_id)) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.error(_LE("Fail remove of interface from brocade " - "router interface. info=%(info)s, " - "router_id=%(router_id)s"), - {"info": info, "router_id": router_id}) - return True - - @staticmethod - def net_addr(addr): - """Get network address prefix and length from a given address.""" - if addr is None: - return None, None - nw_addr, nw_len = addr.split('/') - nw_len = int(nw_len) - return nw_addr, nw_len diff --git a/neutron/tests/unit/ml2/drivers/brocade/__init__.py b/neutron/tests/unit/ml2/drivers/brocade/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_l3_plugin.py b/neutron/tests/unit/ml2/drivers/brocade/test_brocade_l3_plugin.py deleted file mode 100644 index 85119008c0d..00000000000 --- a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_l3_plugin.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -import mock -from oslo_config import cfg -from oslo_context import context as oslo_context -from oslo_log import log as logging -from oslo_utils import importutils - -from neutron.db import api as db -from neutron.tests.unit import test_l3_plugin - -LOG = logging.getLogger(__name__) -L3_SVC_PLUGIN = ('neutron.services.l3_router.' - 'brocade.l3_router_plugin.BrocadeSVIPlugin') - - -class BrocadeSVIPlugin_TestCases(test_l3_plugin.TestL3NatBasePlugin): - - def setUp(self): - - def mocked_brocade_init(self): - LOG.debug("brocadeSVIPlugin::mocked_brocade_init()") - - self._switch = {'address': cfg.CONF.ml2_brocade.address, - 'username': cfg.CONF.ml2_brocade.username, - 'password': cfg.CONF.ml2_brocade.password, - 'rbridge_id': cfg.CONF.ml2_brocade.rbridge_id - } - LOG.info(_("rbridge id %s"), self._switch['rbridge_id']) - self._driver = mock.MagicMock() - - self.l3_plugin = importutils.import_object(L3_SVC_PLUGIN) - with mock.patch.object(self.l3_plugin, - 'brocade_init', new=mocked_brocade_init): - super(BrocadeSVIPlugin_TestCases, self).setUp() - self.context = oslo_context.get_admin_context() - self.context.session = db.get_session() - - -class TestBrocadeSVINatBase(test_l3_plugin.L3NatExtensionTestCase, - BrocadeSVIPlugin_TestCases): - pass diff --git a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py b/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py deleted file mode 100644 index cbb1df6ad6d..00000000000 --- a/neutron/tests/unit/ml2/drivers/brocade/test_brocade_mechanism_driver.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import mock -from oslo_log import log as logging -from oslo_utils import importutils - -from neutron.plugins.ml2 import config as ml2_config -from neutron.plugins.ml2.drivers.brocade import (mechanism_brocade - as brocademechanism) -from neutron.tests.unit.ml2 import test_ml2_plugin - -LOG = logging.getLogger(__name__) -MECHANISM_NAME = ('neutron.plugins.ml2.' - 'drivers.brocade.mechanism_brocade.BrocadeMechanism') - - -class TestBrocadeMechDriverV2(test_ml2_plugin.Ml2PluginV2TestCase): - """Test Brocade VCS/VDX mechanism driver. - """ - - _mechanism_name = MECHANISM_NAME - - def setUp(self): - - _mechanism_name = MECHANISM_NAME - - ml2_opts = { - 'mechanism_drivers': ['brocade'], - 'tenant_network_types': ['vlan']} - - for opt, val in ml2_opts.items(): - ml2_config.cfg.CONF.set_override(opt, val, 'ml2') - - def mocked_brocade_init(self): - self._driver = mock.MagicMock() - - with mock.patch.object(brocademechanism.BrocadeMechanism, - 'brocade_init', new=mocked_brocade_init): - super(TestBrocadeMechDriverV2, self).setUp() - self.mechanism_driver = importutils.import_object(_mechanism_name) - - -class TestBrocadeMechDriverNetworksV2(test_ml2_plugin.TestMl2NetworksV2, - TestBrocadeMechDriverV2): - pass - - -class TestBrocadeMechDriverPortsV2(test_ml2_plugin.TestMl2PortsV2, - TestBrocadeMechDriverV2): - pass - - -class TestBrocadeMechDriverSubnetsV2(test_ml2_plugin.TestMl2SubnetsV2, - TestBrocadeMechDriverV2): - pass - - -class TestBrocadeMechDriverFeaturesEnabledTestCase(TestBrocadeMechDriverV2): - - def setUp(self): - super(TestBrocadeMechDriverFeaturesEnabledTestCase, self).setUp() - - def test_version_features(self): - - vf = True - # Test for NOS version 4.0.3 - self.mechanism_driver.set_features_enabled("4.0.3", vf) - # Verify - pp_domain_support, virtual_fabric_enabled = ( - self.mechanism_driver.get_features_enabled() - ) - self.assertFalse(pp_domain_support) - self.assertTrue(virtual_fabric_enabled) - - # Test for NOS version 4.1.0 - vf = True - self.mechanism_driver.set_features_enabled("4.1.0", vf) - # Verify - pp_domain_support, virtual_fabric_enabled = ( - self.mechanism_driver.get_features_enabled() - ) - self.assertTrue(pp_domain_support) - self.assertTrue(virtual_fabric_enabled) - - # Test for NOS version 4.1.3 - vf = False - self.mechanism_driver.set_features_enabled("4.1.3", vf) - # Verify - pp_domain_support, virtual_fabric_enabled = ( - self.mechanism_driver.get_features_enabled() - ) - self.assertTrue(pp_domain_support) - self.assertFalse(virtual_fabric_enabled) - - # Test for NOS version 5.0.0 - vf = True - self.mechanism_driver.set_features_enabled("5.0.0", vf) - # Verify - pp_domain_support, virtual_fabric_enabled = ( - self.mechanism_driver.get_features_enabled() - ) - self.assertTrue(pp_domain_support) - self.assertTrue(virtual_fabric_enabled) diff --git a/setup.cfg b/setup.cfg index 44d7b4c1797..7c55d3f5527 100644 --- a/setup.cfg +++ b/setup.cfg @@ -174,7 +174,7 @@ neutron.ml2.mechanism_drivers = bigswitch = neutron.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver ofagent = neutron.plugins.ml2.drivers.ofagent.driver:OfagentMechanismDriver mlnx = neutron.plugins.ml2.drivers.mlnx.mech_mlnx:MlnxMechanismDriver - brocade = neutron.plugins.ml2.drivers.brocade.mechanism_brocade:BrocadeMechanism + brocade = networking_brocade.vdx.ml2driver.mechanism_brocade:BrocadeMechanism fslsdn = neutron.plugins.ml2.drivers.freescale.mechanism_fslsdn:FslsdnMechanismDriver sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver:SriovNicSwitchMechanismDriver nuage = neutron.plugins.ml2.drivers.mech_nuage.driver:NuageMechanismDriver