From: Mohammad Banikazemi Date: Thu, 27 Aug 2015 13:10:33 +0000 (-0400) Subject: Removing the SDN-VE monolithic plugin X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=bdfe8dcf42275f22afa457fccf188d2e3352e4a7;p=openstack-build%2Fneutron-build.git Removing the SDN-VE monolithic plugin As the SDN-VE monolithic plugin is no longer in use by anyone, this is to remove the code from the Neutron source tree. DocImpact Change-Id: I8def7fc2e92f967785b9ab05f8496de641e8f866 --- diff --git a/etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini b/etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini deleted file mode 100644 index 0fab50706..000000000 --- a/etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini +++ /dev/null @@ -1,50 +0,0 @@ -[sdnve] -# (ListOpt) The IP address of one (or more) SDN-VE controllers -# Default value is: controller_ips = 127.0.0.1 -# Example: controller_ips = 127.0.0.1,127.0.0.2 -# (StrOpt) The integration bridge for OF based implementation -# The default value for integration_bridge is None -# Example: integration_bridge = br-int -# (ListOpt) The interface mapping connecting the integration -# bridge to external network as a list of physical network names and -# interfaces: : -# Example: interface_mappings = default:eth2 -# (BoolOpt) Used to reset the integration bridge, if exists -# The default value for reset_bridge is True -# Example: reset_bridge = False -# (BoolOpt) Used to set the OVS controller as out-of-band -# The default value for out_of_band is True -# Example: out_of_band = False -# -# (BoolOpt) The fake controller for testing purposes -# Default value is: use_fake_controller = False -# (StrOpt) The port number for use with controller -# The default value for the port is 8443 -# Example: port = 8443 -# (StrOpt) The userid for use with controller -# The default value for the userid is admin -# Example: userid = sdnve_user -# (StrOpt) The password for use with controller -# The default value for the password is admin -# Example: password = sdnve_password -# -# (StrOpt) The default type of tenants (and associated resources) -# Available choices are: OVERLAY or OF -# The default value for tenant type is OVERLAY -# Example: default_tenant_type = OVERLAY -# (StrOpt) The string in tenant description that indicates -# Default value for OF tenants: of_signature = SDNVE-OF -# (StrOpt) The string in tenant description that indicates -# Default value for OVERLAY tenants: overlay_signature = SDNVE-OVERLAY - -[sdnve_agent] -# (IntOpt) Agent's polling interval in seconds -# polling_interval = 2 -# (StrOpt) What to use for root helper -# The default value: root_helper = 'sudo' -# (BoolOpt) Whether to use rpc or not -# The default value: rpc = True - -[securitygroup] -# The security group is not supported: -# firewall_driver = neutron.agent.firewall.NoopFirewallDriver diff --git a/neutron/plugins/ibm/README b/neutron/plugins/ibm/README deleted file mode 100644 index 732fd7776..000000000 --- a/neutron/plugins/ibm/README +++ /dev/null @@ -1,6 +0,0 @@ -IBM SDN-VE Neutron Plugin - -This plugin implements Neutron v2 APIs. - -For more details on how to use it please refer to the following page: -http://wiki.openstack.org/wiki/IBM-Neutron diff --git a/neutron/plugins/ibm/__init__.py b/neutron/plugins/ibm/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/ibm/agent/__init__.py b/neutron/plugins/ibm/agent/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/ibm/agent/sdnve_neutron_agent.py b/neutron/plugins/ibm/agent/sdnve_neutron_agent.py deleted file mode 100644 index d0a4df61b..000000000 --- a/neutron/plugins/ibm/agent/sdnve_neutron_agent.py +++ /dev/null @@ -1,265 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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 socket -import sys -import time - -import eventlet -eventlet.monkey_patch() - -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging -from oslo_service import loopingcall -import six - -from neutron.agent.common import ovs_lib -from neutron.agent.linux import ip_lib -from neutron.agent import rpc as agent_rpc -from neutron.common import config as common_config -from neutron.common import constants as n_const -from neutron.common import topics -from neutron.common import utils as n_utils -from neutron.i18n import _LE, _LI -from neutron import context -from neutron.plugins.ibm.common import constants - - -LOG = logging.getLogger(__name__) -cfg.CONF.import_group('SDNVE', 'neutron.plugins.ibm.common.config') -cfg.CONF.import_group('SDNVE_AGENT', 'neutron.plugins.ibm.common.config') - -AGENT_TYPE_SDNVE = 'IBM SDN-VE agent' - - -class SdnvePluginApi(agent_rpc.PluginApi): - - def sdnve_info(self, context, info): - cctxt = self.client.prepare() - return cctxt.call(context, 'sdnve_info', info=info) - - -class SdnveNeutronAgent(object): - - target = oslo_messaging.Target(version='1.1') - - def __init__(self, integ_br, interface_mappings, - info, polling_interval, - controller_ip, reset_br, out_of_band): - '''The agent initialization. - - Sets the following parameters and sets up the integration - bridge and physical interfaces if need be. - :param integ_br: name of the integration bridge. - :param interface_mappings: interfaces to physical networks. - :param info: local IP address of this hypervisor. - :param polling_interval: interval (secs) to poll DB. - :param controller_ip: Ip address of SDN-VE controller. - ''' - - super(SdnveNeutronAgent, self).__init__() - self.int_bridge_name = integ_br - self.controller_ip = controller_ip - self.interface_mappings = interface_mappings - self.polling_interval = polling_interval - self.info = info - self.reset_br = reset_br - self.out_of_band = out_of_band - - self.agent_state = { - 'binary': 'neutron-sdnve-agent', - 'host': cfg.CONF.host, - 'topic': n_const.L2_AGENT_TOPIC, - 'configurations': {'interface_mappings': interface_mappings, - 'reset_br': self.reset_br, - 'out_of_band': self.out_of_band, - 'controller_ip': self.controller_ip}, - 'agent_type': AGENT_TYPE_SDNVE, - 'start_flag': True} - - if self.int_bridge_name: - self.int_br = self.setup_integration_br(integ_br, reset_br, - out_of_band, - self.controller_ip) - self.setup_physical_interfaces(self.interface_mappings) - else: - self.int_br = None - - self.setup_rpc() - - def _report_state(self): - try: - self.state_rpc.report_state(self.context, - self.agent_state) - self.agent_state.pop('start_flag', None) - except Exception: - LOG.exception(_LE("Failed reporting state!")) - - def setup_rpc(self): - if self.int_br: - mac = self.int_br.get_local_port_mac() - self.agent_id = '%s%s' % ('sdnve', (mac.replace(":", ""))) - else: - nameaddr = socket.gethostbyname(socket.gethostname()) - self.agent_id = '%s%s' % ('sdnve_', (nameaddr.replace(".", "_"))) - - self.topic = topics.AGENT - self.plugin_rpc = SdnvePluginApi(topics.PLUGIN) - self.state_rpc = agent_rpc.PluginReportStateAPI(topics.PLUGIN) - - self.context = context.get_admin_context_without_session() - self.endpoints = [self] - consumers = [[constants.INFO, topics.UPDATE]] - - self.connection = agent_rpc.create_consumers(self.endpoints, - self.topic, - consumers) - if self.polling_interval: - heartbeat = loopingcall.FixedIntervalLoopingCall( - self._report_state) - heartbeat.start(interval=self.polling_interval) - - # Plugin calls the agents through the following - def info_update(self, context, **kwargs): - LOG.debug("info_update received") - info = kwargs.get('info', {}) - new_controller = info.get('new_controller') - out_of_band = info.get('out_of_band') - if self.int_br and new_controller: - LOG.debug("info_update received. New controller " - "is to be set to: %s", new_controller) - self.int_br.set_controller(["tcp:" + new_controller]) - if out_of_band: - LOG.debug("info_update received. New controller " - "is set to be out of band") - self.int_br.set_db_attribute("Controller", - self.int_bridge_name, - "connection-mode", - "out-of-band") - - def setup_integration_br(self, bridge_name, reset_br, out_of_band, - controller_ip=None): - '''Sets up the integration bridge. - - Create the bridge and remove all existing flows if reset_br is True. - Otherwise, creates the bridge if not already existing. - :param bridge_name: the name of the integration bridge. - :param reset_br: A boolean to rest the bridge if True. - :param out_of_band: A boolean indicating controller is out of band. - :param controller_ip: IP address to use as the bridge controller. - :returns: the integration bridge - ''' - - int_br = ovs_lib.OVSBridge(bridge_name) - if reset_br: - int_br.reset_bridge() - int_br.remove_all_flows() - else: - int_br.create() - - # set the controller - if controller_ip: - int_br.set_controller(["tcp:" + controller_ip]) - if out_of_band: - int_br.set_db_attribute("Controller", bridge_name, - "connection-mode", "out-of-band") - - return int_br - - def setup_physical_interfaces(self, interface_mappings): - '''Sets up the physical network interfaces. - - Link physical interfaces to the integration bridge. - :param interface_mappings: map physical net names to interface names. - ''' - - for physical_network, interface in six.iteritems(interface_mappings): - LOG.info(_LI("Mapping physical network %(physical_network)s to " - "interface %(interface)s"), - {'physical_network': physical_network, - 'interface': interface}) - # Connect the physical interface to the bridge - if not ip_lib.device_exists(interface): - LOG.error(_LE("Interface %(interface)s for physical network " - "%(physical_network)s does not exist. Agent " - "terminated!"), - {'physical_network': physical_network, - 'interface': interface}) - raise SystemExit(1) - self.int_br.add_port(interface) - - def sdnve_info(self): - details = self.plugin_rpc.sdnve_info( - self.context, - {'info': self.info}) - return details - - def rpc_loop(self): - - while True: - start = time.time() - LOG.debug("Agent in the rpc loop.") - - # sleep till end of polling interval - elapsed = (time.time() - start) - if (elapsed < self.polling_interval): - time.sleep(self.polling_interval - elapsed) - else: - LOG.info(_LI("Loop iteration exceeded interval " - "(%(polling_interval)s vs. %(elapsed)s)!"), - {'polling_interval': self.polling_interval, - 'elapsed': elapsed}) - - def daemon_loop(self): - self.rpc_loop() - - -def create_agent_config_map(config): - interface_mappings = n_utils.parse_mappings( - config.SDNVE.interface_mappings) - - controller_ips = config.SDNVE.controller_ips - LOG.info(_LI("Controller IPs: %s"), controller_ips) - controller_ip = controller_ips[0] - - return { - 'integ_br': config.SDNVE.integration_bridge, - 'interface_mappings': interface_mappings, - 'controller_ip': controller_ip, - 'info': config.SDNVE.info, - 'polling_interval': config.SDNVE_AGENT.polling_interval, - 'reset_br': config.SDNVE.reset_bridge, - 'out_of_band': config.SDNVE.out_of_band} - - -def main(): - cfg.CONF.register_opts(ip_lib.OPTS) - common_config.init(sys.argv[1:]) - common_config.setup_logging() - - try: - agent_config = create_agent_config_map(cfg.CONF) - except ValueError as e: - LOG.exception(_LE("%s Agent terminated!"), e) - raise SystemExit(1) - - plugin = SdnveNeutronAgent(**agent_config) - - # Start everything. - LOG.info(_LI("Agent initialized successfully, now running... ")) - plugin.daemon_loop() diff --git a/neutron/plugins/ibm/common/__init__.py b/neutron/plugins/ibm/common/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/ibm/common/config.py b/neutron/plugins/ibm/common/config.py deleted file mode 100644 index 73580bca7..000000000 --- a/neutron/plugins/ibm/common/config.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - - -from oslo_config import cfg - - -DEFAULT_INTERFACE_MAPPINGS = [] -DEFAULT_CONTROLLER_IPS = ['127.0.0.1'] - -sdnve_opts = [ - cfg.BoolOpt('use_fake_controller', default=False, - help=_("Whether to use a fake controller.")), - cfg.StrOpt('base_url', default='/one/nb/v2/', - help=_("Base URL for SDN-VE controller REST API.")), - cfg.ListOpt('controller_ips', default=DEFAULT_CONTROLLER_IPS, - help=_("List of IP addresses of SDN-VE controller(s).")), - cfg.StrOpt('info', default='sdnve_info_string', - help=_("SDN-VE RPC subject.")), - cfg.StrOpt('port', default='8443', - help=_("SDN-VE controller port number.")), - cfg.StrOpt('format', default='json', - help=_("SDN-VE request/response format.")), - cfg.StrOpt('userid', default='admin', - help=_("SDN-VE administrator user ID.")), - cfg.StrOpt('password', default='admin', secret=True, - help=_("SDN-VE administrator password.")), - cfg.StrOpt('integration_bridge', - help=_("Integration bridge to use.")), - cfg.BoolOpt('reset_bridge', default=True, - help=_("Whether to reset the integration bridge before use.")), - cfg.BoolOpt('out_of_band', default=True, - help=_("Indicating if controller is out of band or not.")), - cfg.ListOpt('interface_mappings', - default=DEFAULT_INTERFACE_MAPPINGS, - help=_("List of : " - "mappings.")), - cfg.StrOpt('default_tenant_type', default='OVERLAY', - help=_("Tenant type: OVERLAY (default) or OF.")), - cfg.StrOpt('overlay_signature', default='SDNVE-OVERLAY', - help=_("The string in tenant description that indicates " - "the tenant is a OVERLAY tenant.")), - cfg.StrOpt('of_signature', default='SDNVE-OF', - help=_("The string in tenant description that indicates " - "the tenant is a OF tenant.")), -] - -sdnve_agent_opts = [ - cfg.IntOpt('polling_interval', default=2, - help=_("Agent polling interval if necessary.")), - cfg.BoolOpt('rpc', default=True, - help=_("Whether to use rpc.")), - -] - - -cfg.CONF.register_opts(sdnve_opts, "SDNVE") -cfg.CONF.register_opts(sdnve_agent_opts, "SDNVE_AGENT") diff --git a/neutron/plugins/ibm/common/constants.py b/neutron/plugins/ibm/common/constants.py deleted file mode 100644 index f296c49e2..000000000 --- a/neutron/plugins/ibm/common/constants.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - - -from six.moves import http_client as httplib - -# Topic for info notifications between the plugin and agent -INFO = 'info' - -TENANT_TYPE_OF = 'OF' -TENANT_TYPE_OVERLAY = 'OVERLAY' - -HTTP_ACCEPTABLE = [httplib.OK, - httplib.CREATED, - httplib.ACCEPTED, - httplib.NO_CONTENT - ] diff --git a/neutron/plugins/ibm/common/exceptions.py b/neutron/plugins/ibm/common/exceptions.py deleted file mode 100644 index 26298bae1..000000000 --- a/neutron/plugins/ibm/common/exceptions.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - -from neutron.common import exceptions - - -class SdnveException(exceptions.NeutronException): - message = _("An unexpected error occurred in the SDN-VE Plugin. " - "Here is the error message: %(msg)s") - - -class BadInputException(exceptions.BadRequest): - message = _("The input does not contain nececessary info: %(msg)s") diff --git a/neutron/plugins/ibm/sdnve_api.py b/neutron/plugins/ibm/sdnve_api.py deleted file mode 100644 index 63546d303..000000000 --- a/neutron/plugins/ibm/sdnve_api.py +++ /dev/null @@ -1,387 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - - -from six.moves import http_client as httplib - -import httplib2 -from keystoneclient.v2_0 import client as keyclient -from oslo_config import cfg -from oslo_log import log as logging -from six.moves.urllib import parse - -from neutron.api.v2 import attributes -from neutron.common import utils -from neutron.i18n import _LE, _LI -from neutron.plugins.ibm.common import config # noqa -from neutron.plugins.ibm.common import constants -from neutron import wsgi - -LOG = logging.getLogger(__name__) - -SDNVE_VERSION = '2.0' -SDNVE_ACTION_PREFIX = '/sdnve' -SDNVE_RETRIES = 0 -SDNVE_RETRIY_INTERVAL = 1 -SDNVE_TENANT_TYPE_OVERLAY = u'DOVE' -SDNVE_URL = 'https://%s:%s%s' - - -class RequestHandler(object): - '''Handles processing requests to and responses from controller.''' - - def __init__(self, controller_ips=None, port=None, ssl=None, - base_url=None, userid=None, password=None, - timeout=10, formats=None): - '''Initializes the RequestHandler for communication with controller - - Following keyword arguments are used; if not specified, default - values are used. - :param port: Username for authentication. - :param timeout: Time out for http requests. - :param userid: User id for accessing controller. - :param password: Password for accessing the controller. - :param base_url: The base url for the controller. - :param controller_ips: List of controller IP addresses. - :param formats: Supported formats. - ''' - self.port = port or cfg.CONF.SDNVE.port - self.timeout = timeout - self._s_meta = None - self.connection = None - self.httpclient = httplib2.Http( - disable_ssl_certificate_validation=True) - self.cookie = None - - userid = userid or cfg.CONF.SDNVE.userid - password = password or cfg.CONF.SDNVE.password - if (userid and password): - self.httpclient.add_credentials(userid, password) - - self.base_url = base_url or cfg.CONF.SDNVE.base_url - self.controller_ips = controller_ips or cfg.CONF.SDNVE.controller_ips - - LOG.info(_LI("The IP addr of available SDN-VE controllers: %s"), - self.controller_ips) - self.controller_ip = self.controller_ips[0] - LOG.info(_LI("The SDN-VE controller IP address: %s"), - self.controller_ip) - - self.new_controller = False - self.format = formats or cfg.CONF.SDNVE.format - - self.version = SDNVE_VERSION - self.action_prefix = SDNVE_ACTION_PREFIX - self.retries = SDNVE_RETRIES - self.retry_interval = SDNVE_RETRIY_INTERVAL - - def serialize(self, data): - '''Serializes a dictionary with a single key.''' - - if isinstance(data, dict): - return wsgi.Serializer().serialize(data, self.content_type()) - elif data: - raise TypeError(_("unable to serialize object type: '%s'") % - type(data)) - - def deserialize(self, data, status_code): - '''Deserializes an xml or json string into a dictionary.''' - - # NOTE(mb): Temporary fix for backend controller requirement - data = data.replace("router_external", "router:external") - - if status_code == httplib.NO_CONTENT: - return data - try: - deserialized_data = wsgi.Serializer( - metadata=self._s_meta).deserialize(data, self.content_type()) - deserialized_data = deserialized_data['body'] - except Exception: - deserialized_data = data - - return deserialized_data - - def content_type(self, format=None): - '''Returns the mime-type for either 'xml' or 'json'.''' - - return 'application/%s' % (format or self.format) - - def delete(self, url, body=None, headers=None, params=None): - return self.do_request("DELETE", url, body=body, - headers=headers, params=params) - - def get(self, url, body=None, headers=None, params=None): - return self.do_request("GET", url, body=body, - headers=headers, params=params) - - def post(self, url, body=None, headers=None, params=None): - return self.do_request("POST", url, body=body, - headers=headers, params=params) - - def put(self, url, body=None, headers=None, params=None): - return self.do_request("PUT", url, body=body, - headers=headers, params=params) - - def do_request(self, method, url, body=None, headers=None, - params=None, connection_type=None): - - status_code = -1 - replybody_deserialized = '' - - if body: - body = self.serialize(body) - - self.headers = headers or {'Content-Type': self.content_type()} - if self.cookie: - self.headers['cookie'] = self.cookie - - if self.controller_ip != self.controller_ips[0]: - controllers = [self.controller_ip] - else: - controllers = [] - controllers.extend(self.controller_ips) - - for controller_ip in controllers: - serverurl = SDNVE_URL % (controller_ip, self.port, self.base_url) - myurl = serverurl + url - if params and isinstance(params, dict): - myurl += '?' + parse.urlencode(params, doseq=1) - - try: - LOG.debug("Sending request to SDN-VE. url: " - "%(myurl)s method: %(method)s body: " - "%(body)s header: %(header)s ", - {'myurl': myurl, 'method': method, - 'body': body, 'header': self.headers}) - resp, replybody = self.httpclient.request( - myurl, method=method, body=body, headers=self.headers) - LOG.debug("Response recd from SDN-VE. resp: %(resp)s " - "body: %(body)s", - {'resp': resp.status, 'body': replybody}) - status_code = resp.status - - except Exception as e: - LOG.error(_LE("Error: Could not reach server: %(url)s " - "Exception: %(excp)s."), - {'url': myurl, 'excp': e}) - self.cookie = None - continue - - if status_code not in constants.HTTP_ACCEPTABLE: - LOG.debug("Error message: %(reply)s -- Status: %(status)s", - {'reply': replybody, 'status': status_code}) - else: - LOG.debug("Received response status: %s", status_code) - - if resp.get('set-cookie'): - self.cookie = resp['set-cookie'] - replybody_deserialized = self.deserialize( - replybody, - status_code) - LOG.debug("Deserialized body: %s", replybody_deserialized) - if controller_ip != self.controller_ip: - # bcast the change of controller - self.new_controller = True - self.controller_ip = controller_ip - - return (status_code, replybody_deserialized) - - return (httplib.REQUEST_TIMEOUT, 'Could not reach server(s)') - - -class Client(RequestHandler): - '''Client for SDNVE controller.''' - - def __init__(self): - '''Initialize a new SDNVE client.''' - super(Client, self).__init__() - - self.keystoneclient = KeystoneClient() - - resource_path = { - 'network': "ln/networks/", - 'subnet': "ln/subnets/", - 'port': "ln/ports/", - 'tenant': "ln/tenants/", - 'router': "ln/routers/", - 'floatingip': "ln/floatingips/", - } - - def process_request(self, body): - '''Processes requests according to requirements of controller.''' - if self.format == 'json': - body = dict( - (k.replace(':', '_'), v) for k, v in body.items() - if attributes.is_attr_set(v)) - return body - - def sdnve_list(self, resource, **params): - '''Fetches a list of resources.''' - - res = self.resource_path.get(resource, None) - if not res: - LOG.info(_LI("Bad resource for forming a list request")) - return 0, '' - - return self.get(res, params=params) - - def sdnve_show(self, resource, specific, **params): - '''Fetches information of a certain resource.''' - - res = self.resource_path.get(resource, None) - if not res: - LOG.info(_LI("Bad resource for forming a show request")) - return 0, '' - - return self.get(res + specific, params=params) - - def sdnve_create(self, resource, body): - '''Creates a new resource.''' - - res = self.resource_path.get(resource, None) - if not res: - LOG.info(_LI("Bad resource for forming a create request")) - return 0, '' - - body = self.process_request(body) - status, data = self.post(res, body=body) - return (status, data) - - def sdnve_update(self, resource, specific, body=None): - '''Updates a resource.''' - - res = self.resource_path.get(resource, None) - if not res: - LOG.info(_LI("Bad resource for forming a update request")) - return 0, '' - - body = self.process_request(body) - return self.put(res + specific, body=body) - - def sdnve_delete(self, resource, specific): - '''Deletes the specified resource.''' - - res = self.resource_path.get(resource, None) - if not res: - LOG.info(_LI("Bad resource for forming a delete request")) - return 0, '' - - return self.delete(res + specific) - - def _tenant_id_conversion(self, osid): - return osid - - def sdnve_get_tenant_byid(self, os_tenant_id): - sdnve_tenant_id = self._tenant_id_conversion(os_tenant_id) - resp, content = self.sdnve_show('tenant', sdnve_tenant_id) - if resp in constants.HTTP_ACCEPTABLE: - tenant_id = content.get('id') - tenant_type = content.get('network_type') - if tenant_type == SDNVE_TENANT_TYPE_OVERLAY: - tenant_type = constants.TENANT_TYPE_OVERLAY - return tenant_id, tenant_type - return None, None - - def sdnve_check_and_create_tenant(self, os_tenant_id, network_type=None): - - if not os_tenant_id: - return - tenant_id, tenant_type = self.sdnve_get_tenant_byid(os_tenant_id) - if tenant_id: - if not network_type: - return tenant_id - if tenant_type != network_type: - LOG.info(_LI("Non matching tenant and network types: " - "%(ttype)s %(ntype)s"), - {'ttype': tenant_type, 'ntype': network_type}) - return - return tenant_id - - # Have to create a new tenant - sdnve_tenant_id = self._tenant_id_conversion(os_tenant_id) - if not network_type: - network_type = self.keystoneclient.get_tenant_type(os_tenant_id) - if network_type == constants.TENANT_TYPE_OVERLAY: - network_type = SDNVE_TENANT_TYPE_OVERLAY - - pinn_desc = ("Created by SDN-VE Neutron Plugin, OS project name = " + - self.keystoneclient.get_tenant_name(os_tenant_id)) - - res, content = self.sdnve_create('tenant', - {'id': sdnve_tenant_id, - 'name': os_tenant_id, - 'network_type': network_type, - 'description': pinn_desc}) - if res not in constants.HTTP_ACCEPTABLE: - return - - return sdnve_tenant_id - - def sdnve_get_controller(self): - if self.new_controller: - self.new_controller = False - return self.controller_ip - - -class KeystoneClient(object): - - def __init__(self, username=None, tenant_name=None, password=None, - auth_url=None): - - keystone_conf = cfg.CONF.keystone_authtoken - - username = username or keystone_conf.admin_user - tenant_name = tenant_name or keystone_conf.admin_tenant_name - password = password or keystone_conf.admin_password - # FIXME(ihrachys): plugins should not construct keystone URL - # from configuration file and should instead rely on service - # catalog contents - auth_url = auth_url or utils.get_keystone_url(keystone_conf) - - self.overlay_signature = cfg.CONF.SDNVE.overlay_signature - self.of_signature = cfg.CONF.SDNVE.of_signature - self.default_tenant_type = cfg.CONF.SDNVE.default_tenant_type - - self.client = keyclient.Client(username=username, - password=password, - tenant_name=tenant_name, - auth_url=auth_url) - - def get_tenant_byid(self, id): - - try: - return self.client.tenants.get(id) - except Exception: - LOG.exception(_LE("Did not find tenant: %r"), id) - - def get_tenant_type(self, id): - - tenant = self.get_tenant_byid(id) - if tenant: - description = tenant.description - if description: - if (description.find(self.overlay_signature) >= 0): - return constants.TENANT_TYPE_OVERLAY - if (description.find(self.of_signature) >= 0): - return constants.TENANT_TYPE_OF - return self.default_tenant_type - - def get_tenant_name(self, id): - - tenant = self.get_tenant_byid(id) - if tenant: - return tenant.name - return 'not found' diff --git a/neutron/plugins/ibm/sdnve_api_fake.py b/neutron/plugins/ibm/sdnve_api_fake.py deleted file mode 100644 index a6c0aeedf..000000000 --- a/neutron/plugins/ibm/sdnve_api_fake.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - -from oslo_log import log as logging - -from neutron.i18n import _LI -from neutron.plugins.ibm.common import constants - -LOG = logging.getLogger(__name__) - -HTTP_OK = 200 - - -class FakeClient(object): - - '''Fake Client for SDNVE controller.''' - - def __init__(self, **kwargs): - LOG.info(_LI('Fake SDNVE controller initialized')) - - def sdnve_list(self, resource, **_params): - LOG.info(_LI('Fake SDNVE controller: list')) - return (HTTP_OK, None) - - def sdnve_show(self, resource, specific, **_params): - LOG.info(_LI('Fake SDNVE controller: show')) - return (HTTP_OK, None) - - def sdnve_create(self, resource, body): - LOG.info(_LI('Fake SDNVE controller: create')) - return (HTTP_OK, None) - - def sdnve_update(self, resource, specific, body=None): - LOG.info(_LI('Fake SDNVE controller: update')) - return (HTTP_OK, None) - - def sdnve_delete(self, resource, specific): - LOG.info(_LI('Fake SDNVE controller: delete')) - return (HTTP_OK, None) - - def sdnve_get_tenant_byid(self, id): - LOG.info(_LI('Fake SDNVE controller: get tenant by id')) - return id, constants.TENANT_TYPE_OF - - def sdnve_check_and_create_tenant(self, id, network_type=None): - LOG.info(_LI('Fake SDNVE controller: check and create tenant')) - return id - - def sdnve_get_controller(self): - LOG.info(_LI('Fake SDNVE controller: get controller')) - return None diff --git a/neutron/plugins/ibm/sdnve_neutron_plugin.py b/neutron/plugins/ibm/sdnve_neutron_plugin.py deleted file mode 100644 index ac4ae1a3b..000000000 --- a/neutron/plugins/ibm/sdnve_neutron_plugin.py +++ /dev/null @@ -1,678 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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 functools - -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging -from oslo_utils import excutils - -from neutron.common import constants as n_const -from neutron.common import exceptions as n_exc -from neutron.common import rpc as n_rpc -from neutron.common import topics -from neutron.db import agents_db -from neutron.db import db_base_plugin_v2 -from neutron.db import external_net_db -from neutron.db import l3_gwmode_db -from neutron.db import portbindings_db -from neutron.extensions import portbindings -from neutron.i18n import _LE, _LI, _LW -from neutron.plugins.ibm.common import config # noqa -from neutron.plugins.ibm.common import constants -from neutron.plugins.ibm.common import exceptions as sdnve_exc -from neutron.plugins.ibm import sdnve_api as sdnve -from neutron.plugins.ibm import sdnve_api_fake as sdnve_fake - -LOG = logging.getLogger(__name__) - - -class SdnveRpcCallbacks(object): - - def __init__(self, notifier): - self.notifier = notifier # used to notify the agent - - def sdnve_info(self, rpc_context, **kwargs): - '''Update new information.''' - info = kwargs.get('info') - # Notify all other listening agents - self.notifier.info_update(rpc_context, info) - return info - - -class AgentNotifierApi(object): - '''Agent side of the SDN-VE rpc API.''' - - def __init__(self, topic): - target = oslo_messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - self.topic_info_update = topics.get_topic_name(topic, - constants.INFO, - topics.UPDATE) - - def info_update(self, context, info): - cctxt = self.client.prepare(topic=self.topic_info_update, fanout=True) - cctxt.cast(context, 'info_update', info=info) - - -def _ha(func): - '''Supports the high availability feature of the controller.''' - - @functools.wraps(func) - def hawrapper(self, *args, **kwargs): - '''This wrapper sets the new controller if necessary - - When a controller is detected to be not responding, and a - new controller is chosen to be used in its place, this decorator - makes sure the existing integration bridges are set to point - to the new controller by calling the set_controller method. - ''' - ret_func = func(self, *args, **kwargs) - self.set_controller(args[0]) - return ret_func - return hawrapper - - -class SdnvePluginV2(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin, - portbindings_db.PortBindingMixin, - l3_gwmode_db.L3_NAT_db_mixin, - agents_db.AgentDbMixin, - ): - - ''' - Implement the Neutron abstractions using SDN-VE SDN Controller. - ''' - - __native_bulk_support = False - __native_pagination_support = False - __native_sorting_support = False - - supported_extension_aliases = ["binding", "router", "external-net", - "agent", "quotas"] - - def __init__(self, configfile=None): - self.base_binding_dict = { - portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS, - portbindings.VIF_DETAILS: {portbindings.CAP_PORT_FILTER: False}} - - super(SdnvePluginV2, self).__init__() - self.setup_rpc() - self.sdnve_controller_select() - if self.fake_controller: - self.sdnve_client = sdnve_fake.FakeClient() - else: - self.sdnve_client = sdnve.Client() - - def sdnve_controller_select(self): - self.fake_controller = cfg.CONF.SDNVE.use_fake_controller - - def setup_rpc(self): - # RPC support - self.topic = topics.PLUGIN - self.conn = n_rpc.create_connection(new=True) - self.notifier = AgentNotifierApi(topics.AGENT) - self.endpoints = [SdnveRpcCallbacks(self.notifier), - agents_db.AgentExtRpcCallback()] - self.conn.create_consumer(self.topic, self.endpoints, - fanout=False) - # Consume from all consumers in threads - self.conn.consume_in_threads() - - def _update_base_binding_dict(self, tenant_type): - if tenant_type == constants.TENANT_TYPE_OVERLAY: - self.base_binding_dict[ - portbindings.VIF_TYPE] = portbindings.VIF_TYPE_BRIDGE - if tenant_type == constants.TENANT_TYPE_OF: - self.base_binding_dict[ - portbindings.VIF_TYPE] = portbindings.VIF_TYPE_OVS - - def set_controller(self, context): - LOG.info(_LI("Set a new controller if needed.")) - new_controller = self.sdnve_client.sdnve_get_controller() - if new_controller: - self.notifier.info_update( - context, - {'new_controller': new_controller}) - LOG.info(_LI("Set the controller to a new controller: %s"), - new_controller) - - def _process_request(self, request, current): - new_request = dict( - (k, v) for k, v in request.items() - if v != current.get(k)) - - msg = _("Original SDN-VE HTTP request: %(orig)s; New request: %(new)s") - LOG.debug(msg, {'orig': request, 'new': new_request}) - return new_request - - # - # Network - # - - @_ha - def create_network(self, context, network): - LOG.debug("Create network in progress: %r", network) - session = context.session - - tenant_id = self._get_tenant_id_for_create(context, network['network']) - # Create a new SDN-VE tenant if need be - sdnve_tenant = self.sdnve_client.sdnve_check_and_create_tenant( - tenant_id) - if sdnve_tenant is None: - raise sdnve_exc.SdnveException( - msg=_('Create net failed: no SDN-VE tenant.')) - - with session.begin(subtransactions=True): - net = super(SdnvePluginV2, self).create_network(context, network) - self._process_l3_create(context, net, network['network']) - - # Create SDN-VE network - (res, data) = self.sdnve_client.sdnve_create('network', net) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).delete_network(context, net['id']) - raise sdnve_exc.SdnveException( - msg=(_('Create net failed in SDN-VE: %s') % res)) - - LOG.debug("Created network: %s", net['id']) - return net - - @_ha - def update_network(self, context, id, network): - LOG.debug("Update network in progress: %r", network) - session = context.session - - processed_request = {} - with session.begin(subtransactions=True): - original_network = super(SdnvePluginV2, self).get_network( - context, id) - processed_request['network'] = self._process_request( - network['network'], original_network) - net = super(SdnvePluginV2, self).update_network( - context, id, network) - self._process_l3_update(context, net, network['network']) - - if processed_request['network']: - (res, data) = self.sdnve_client.sdnve_update( - 'network', id, processed_request['network']) - if res not in constants.HTTP_ACCEPTABLE: - net = super(SdnvePluginV2, self).update_network( - context, id, {'network': original_network}) - raise sdnve_exc.SdnveException( - msg=(_('Update net failed in SDN-VE: %s') % res)) - - return net - - @_ha - def delete_network(self, context, id): - LOG.debug("Delete network in progress: %s", id) - session = context.session - - with session.begin(subtransactions=True): - self._process_l3_delete(context, id) - super(SdnvePluginV2, self).delete_network(context, id) - - (res, data) = self.sdnve_client.sdnve_delete('network', id) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error( - _LE("Delete net failed after deleting the network in DB: %s"), - res) - - @_ha - def get_network(self, context, id, fields=None): - LOG.debug("Get network in progress: %s", id) - return super(SdnvePluginV2, self).get_network(context, id, fields) - - @_ha - def get_networks(self, context, filters=None, fields=None, sorts=None, - limit=None, marker=None, page_reverse=False): - LOG.debug("Get networks in progress") - return super(SdnvePluginV2, self).get_networks( - context, filters, fields, sorts, limit, marker, page_reverse) - - # - # Port - # - - @_ha - def create_port(self, context, port): - LOG.debug("Create port in progress: %r", port) - session = context.session - - # Set port status as 'ACTIVE' to avoid needing the agent - port['port']['status'] = n_const.PORT_STATUS_ACTIVE - port_data = port['port'] - - with session.begin(subtransactions=True): - port = super(SdnvePluginV2, self).create_port(context, port) - if 'id' not in port: - return port - # If the tenant_id is set to '' by create_port, add the id to - # the request being sent to the controller as the controller - # requires a tenant id - tenant_id = port.get('tenant_id') - if not tenant_id: - LOG.debug("Create port does not have tenant id info") - original_network = super(SdnvePluginV2, self).get_network( - context, port['network_id']) - original_tenant_id = original_network['tenant_id'] - port['tenant_id'] = original_tenant_id - LOG.debug( - "Create port does not have tenant id info; " - "obtained is: %s", - port['tenant_id']) - - os_tenant_id = tenant_id - id_na, tenant_type = self.sdnve_client.sdnve_get_tenant_byid( - os_tenant_id) - self._update_base_binding_dict(tenant_type) - self._process_portbindings_create_and_update(context, - port_data, port) - - # NOTE(mb): Remove this block when controller is updated - # Remove the information that the controller does not accept - sdnve_port = port.copy() - sdnve_port.pop('device_id', None) - sdnve_port.pop('device_owner', None) - - (res, data) = self.sdnve_client.sdnve_create('port', sdnve_port) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).delete_port(context, port['id']) - raise sdnve_exc.SdnveException( - msg=(_('Create port failed in SDN-VE: %s') % res)) - - LOG.debug("Created port: %s", port.get('id', 'id not found')) - return port - - @_ha - def update_port(self, context, id, port): - LOG.debug("Update port in progress: %r", port) - session = context.session - - processed_request = {} - with session.begin(subtransactions=True): - original_port = super(SdnvePluginV2, self).get_port( - context, id) - processed_request['port'] = self._process_request( - port['port'], original_port) - updated_port = super(SdnvePluginV2, self).update_port( - context, id, port) - - os_tenant_id = updated_port['tenant_id'] - id_na, tenant_type = self.sdnve_client.sdnve_get_tenant_byid( - os_tenant_id) - self._update_base_binding_dict(tenant_type) - self._process_portbindings_create_and_update(context, - port['port'], - updated_port) - - if processed_request['port']: - (res, data) = self.sdnve_client.sdnve_update( - 'port', id, processed_request['port']) - if res not in constants.HTTP_ACCEPTABLE: - updated_port = super(SdnvePluginV2, self).update_port( - context, id, {'port': original_port}) - raise sdnve_exc.SdnveException( - msg=(_('Update port failed in SDN-VE: %s') % res)) - - return updated_port - - @_ha - def delete_port(self, context, id, l3_port_check=True): - LOG.debug("Delete port in progress: %s", id) - - # if needed, check to see if this is a port owned by - # an l3-router. If so, we should prevent deletion. - if l3_port_check: - self.prevent_l3_port_deletion(context, id) - self.disassociate_floatingips(context, id) - - super(SdnvePluginV2, self).delete_port(context, id) - - (res, data) = self.sdnve_client.sdnve_delete('port', id) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error( - _LE("Delete port operation failed in SDN-VE " - "after deleting the port from DB: %s"), res) - - # - # Subnet - # - - @_ha - def create_subnet(self, context, subnet): - LOG.debug("Create subnet in progress: %r", subnet) - new_subnet = super(SdnvePluginV2, self).create_subnet(context, subnet) - - # Note(mb): Use of null string currently required by controller - sdnve_subnet = new_subnet.copy() - if subnet.get('gateway_ip') is None: - sdnve_subnet['gateway_ip'] = 'null' - (res, data) = self.sdnve_client.sdnve_create('subnet', sdnve_subnet) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).delete_subnet(context, - new_subnet['id']) - raise sdnve_exc.SdnveException( - msg=(_('Create subnet failed in SDN-VE: %s') % res)) - - LOG.debug("Subnet created: %s", new_subnet['id']) - - return new_subnet - - @_ha - def update_subnet(self, context, id, subnet): - LOG.debug("Update subnet in progress: %r", subnet) - session = context.session - - processed_request = {} - with session.begin(subtransactions=True): - original_subnet = super(SdnvePluginV2, self).get_subnet( - context, id) - processed_request['subnet'] = self._process_request( - subnet['subnet'], original_subnet) - updated_subnet = super(SdnvePluginV2, self).update_subnet( - context, id, subnet) - - if processed_request['subnet']: - # Note(mb): Use of string containing null required by controller - if 'gateway_ip' in processed_request['subnet']: - if processed_request['subnet'].get('gateway_ip') is None: - processed_request['subnet']['gateway_ip'] = 'null' - (res, data) = self.sdnve_client.sdnve_update( - 'subnet', id, processed_request['subnet']) - if res not in constants.HTTP_ACCEPTABLE: - for key in subnet['subnet'].keys(): - subnet['subnet'][key] = original_subnet[key] - super(SdnvePluginV2, self).update_subnet( - context, id, subnet) - raise sdnve_exc.SdnveException( - msg=(_('Update subnet failed in SDN-VE: %s') % res)) - - return updated_subnet - - @_ha - def delete_subnet(self, context, id): - LOG.debug("Delete subnet in progress: %s", id) - super(SdnvePluginV2, self).delete_subnet(context, id) - - (res, data) = self.sdnve_client.sdnve_delete('subnet', id) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error(_LE("Delete subnet operation failed in SDN-VE after " - "deleting the subnet from DB: %s"), res) - - # - # Router - # - - @_ha - def create_router(self, context, router): - LOG.debug("Create router in progress: %r", router) - - if router['router']['admin_state_up'] is False: - LOG.warning(_LW('Ignoring admin_state_up=False for router=%r. ' - 'Overriding with True'), router) - router['router']['admin_state_up'] = True - - tenant_id = self._get_tenant_id_for_create(context, router['router']) - # Create a new SDN-VE tenant if need be - sdnve_tenant = self.sdnve_client.sdnve_check_and_create_tenant( - tenant_id) - if sdnve_tenant is None: - raise sdnve_exc.SdnveException( - msg=_('Create router failed: no SDN-VE tenant.')) - - new_router = super(SdnvePluginV2, self).create_router(context, router) - # Create SDN-VE router - (res, data) = self.sdnve_client.sdnve_create('router', new_router) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).delete_router(context, new_router['id']) - raise sdnve_exc.SdnveException( - msg=(_('Create router failed in SDN-VE: %s') % res)) - - LOG.debug("Router created: %r", new_router) - return new_router - - @_ha - def update_router(self, context, id, router): - LOG.debug("Update router in progress: id=%(id)s " - "router=%(router)r", - {'id': id, 'router': router}) - session = context.session - - processed_request = {} - if not router['router'].get('admin_state_up', True): - raise n_exc.NotImplementedError(_('admin_state_up=False ' - 'routers are not ' - 'supported.')) - - with session.begin(subtransactions=True): - original_router = super(SdnvePluginV2, self).get_router( - context, id) - processed_request['router'] = self._process_request( - router['router'], original_router) - updated_router = super(SdnvePluginV2, self).update_router( - context, id, router) - - if processed_request['router']: - egw = processed_request['router'].get('external_gateway_info') - # Check for existing empty set (different from None) in request - if egw == {}: - processed_request['router'][ - 'external_gateway_info'] = {'network_id': 'null'} - (res, data) = self.sdnve_client.sdnve_update( - 'router', id, processed_request['router']) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).update_router( - context, id, {'router': original_router}) - raise sdnve_exc.SdnveException( - msg=(_('Update router failed in SDN-VE: %s') % res)) - - return updated_router - - @_ha - def delete_router(self, context, id): - LOG.debug("Delete router in progress: %s", id) - - super(SdnvePluginV2, self).delete_router(context, id) - - (res, data) = self.sdnve_client.sdnve_delete('router', id) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error( - _LE("Delete router operation failed in SDN-VE after " - "deleting the router in DB: %s"), res) - - @_ha - def add_router_interface(self, context, router_id, interface_info): - LOG.debug("Add router interface in progress: " - "router_id=%(router_id)s " - "interface_info=%(interface_info)r", - {'router_id': router_id, 'interface_info': interface_info}) - - new_interface = super(SdnvePluginV2, self).add_router_interface( - context, router_id, interface_info) - LOG.debug( - "SdnvePluginV2.add_router_interface called. Port info: %s", - new_interface) - request_info = interface_info.copy() - request_info['port_id'] = new_interface['port_id'] - # Add the subnet_id to the request sent to the controller - if 'subnet_id' not in interface_info: - request_info['subnet_id'] = new_interface['subnet_id'] - - (res, data) = self.sdnve_client.sdnve_update( - 'router', router_id + '/add_router_interface', request_info) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).remove_router_interface( - context, router_id, interface_info) - raise sdnve_exc.SdnveException( - msg=(_('Update router-add-interface failed in SDN-VE: %s') % - res)) - - LOG.debug("Added router interface: %r", new_interface) - return new_interface - - def _add_router_interface_only(self, context, router_id, interface_info): - LOG.debug("Add router interface only called: " - "router_id=%(router_id)s " - "interface_info=%(interface_info)r", - {'router_id': router_id, 'interface_info': interface_info}) - - port_id = interface_info.get('port_id') - if port_id: - (res, data) = self.sdnve_client.sdnve_update( - 'router', router_id + '/add_router_interface', interface_info) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error(_LE("SdnvePluginV2._add_router_interface_only: " - "failed to add the interface in the roll back." - " of a remove_router_interface operation")) - - def _find_router_port_by_subnet_id(self, ports, subnet_id): - for p in ports: - subnet_ids = [fip['subnet_id'] for fip in p['fixed_ips']] - if subnet_id in subnet_ids: - return p['id'] - - @_ha - def remove_router_interface(self, context, router_id, interface_info): - LOG.debug("Remove router interface in progress: " - "router_id=%(router_id)s " - "interface_info=%(interface_info)r", - {'router_id': router_id, 'interface_info': interface_info}) - - subnet_id = interface_info.get('subnet_id') - port_id = interface_info.get('port_id') - if not subnet_id: - if not port_id: - raise sdnve_exc.BadInputException(msg=_('No port ID')) - myport = super(SdnvePluginV2, self).get_port(context, port_id) - LOG.debug("SdnvePluginV2.remove_router_interface port: %s", - myport) - myfixed_ips = myport.get('fixed_ips') - if not myfixed_ips: - raise sdnve_exc.BadInputException(msg=_('No fixed IP')) - subnet_id = myfixed_ips[0].get('subnet_id') - if subnet_id: - interface_info['subnet_id'] = subnet_id - LOG.debug( - "SdnvePluginV2.remove_router_interface subnet_id: %s", - subnet_id) - else: - if not port_id: - # The backend requires port id info in the request - subnet = super(SdnvePluginV2, self).get_subnet(context, - subnet_id) - df = {'device_id': [router_id], - 'device_owner': [n_const.DEVICE_OWNER_ROUTER_INTF], - 'network_id': [subnet['network_id']]} - ports = self.get_ports(context, filters=df) - if ports: - pid = self._find_router_port_by_subnet_id(ports, subnet_id) - if not pid: - raise sdnve_exc.SdnveException( - msg=(_('Update router-remove-interface ' - 'failed SDN-VE: subnet %(sid) is not ' - 'associated with any ports on router ' - '%(rid)'), {'sid': subnet_id, - 'rid': router_id})) - interface_info['port_id'] = pid - msg = ("SdnvePluginV2.remove_router_interface " - "subnet_id: %(sid)s port_id: %(pid)s") - LOG.debug(msg, {'sid': subnet_id, 'pid': pid}) - - (res, data) = self.sdnve_client.sdnve_update( - 'router', router_id + '/remove_router_interface', interface_info) - - if res not in constants.HTTP_ACCEPTABLE: - raise sdnve_exc.SdnveException( - msg=(_('Update router-remove-interface failed SDN-VE: %s') % - res)) - - session = context.session - with session.begin(subtransactions=True): - try: - if not port_id: - # port_id was not originally given in interface_info, - # so we want to remove the interface by subnet instead - # of port - del interface_info['port_id'] - info = super(SdnvePluginV2, self).remove_router_interface( - context, router_id, interface_info) - except Exception: - with excutils.save_and_reraise_exception(): - self._add_router_interface_only(context, - router_id, interface_info) - - return info - - # - # Floating Ip - # - - @_ha - def create_floatingip(self, context, floatingip): - LOG.debug("Create floatingip in progress: %r", - floatingip) - new_floatingip = super(SdnvePluginV2, self).create_floatingip( - context, floatingip) - - (res, data) = self.sdnve_client.sdnve_create( - 'floatingip', {'floatingip': new_floatingip}) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).delete_floatingip( - context, new_floatingip['id']) - raise sdnve_exc.SdnveException( - msg=(_('Creating floating ip operation failed ' - 'in SDN-VE controller: %s') % res)) - - LOG.debug("Created floatingip : %r", new_floatingip) - return new_floatingip - - @_ha - def update_floatingip(self, context, id, floatingip): - LOG.debug("Update floatingip in progress: %r", floatingip) - session = context.session - - processed_request = {} - with session.begin(subtransactions=True): - original_floatingip = super( - SdnvePluginV2, self).get_floatingip(context, id) - processed_request['floatingip'] = self._process_request( - floatingip['floatingip'], original_floatingip) - updated_floatingip = super( - SdnvePluginV2, self).update_floatingip(context, id, floatingip) - - if processed_request['floatingip']: - (res, data) = self.sdnve_client.sdnve_update( - 'floatingip', id, - {'floatingip': processed_request['floatingip']}) - if res not in constants.HTTP_ACCEPTABLE: - super(SdnvePluginV2, self).update_floatingip( - context, id, {'floatingip': original_floatingip}) - raise sdnve_exc.SdnveException( - msg=(_('Update floating ip failed in SDN-VE: %s') % res)) - - return updated_floatingip - - @_ha - def delete_floatingip(self, context, id): - LOG.debug("Delete floatingip in progress: %s", id) - super(SdnvePluginV2, self).delete_floatingip(context, id) - - (res, data) = self.sdnve_client.sdnve_delete('floatingip', id) - if res not in constants.HTTP_ACCEPTABLE: - LOG.error(_LE("Delete floatingip failed in SDN-VE: %s"), res) diff --git a/neutron/tests/unit/plugins/ibm/__init__.py b/neutron/tests/unit/plugins/ibm/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/plugins/ibm/test_sdnve_agent.py b/neutron/tests/unit/plugins/ibm/test_sdnve_agent.py deleted file mode 100644 index 08d689e12..000000000 --- a/neutron/tests/unit/plugins/ibm/test_sdnve_agent.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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 mock -from oslo_config import cfg - -from neutron.agent.linux import ip_lib -from neutron.plugins.ibm.agent import sdnve_neutron_agent -from neutron.tests import base - - -NOTIFIER = ('neutron.plugins.ibm.' - 'sdnve_neutron_plugin.AgentNotifierApi') - - -class CreateAgentConfigMap(base.BaseTestCase): - - def test_create_agent_config_map_succeeds(self): - self.assertTrue(sdnve_neutron_agent.create_agent_config_map(cfg.CONF)) - - def test_create_agent_config_using_controller_ips(self): - cfg.CONF.set_override('controller_ips', - ['10.10.10.1', '10.10.10.2'], group='SDNVE') - cfgmap = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['controller_ip'], '10.10.10.1') - - def test_create_agent_config_using_interface_mappings(self): - cfg.CONF.set_override('interface_mappings', - ['interface1 : eth1', 'interface2 : eth2'], - group='SDNVE') - cfgmap = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - self.assertEqual(cfgmap['interface_mappings'], - {'interface1': 'eth1', 'interface2': 'eth2'}) - - -class TestSdnveNeutronAgent(base.BaseTestCase): - - def setUp(self): - super(TestSdnveNeutronAgent, self).setUp() - notifier_p = mock.patch(NOTIFIER) - notifier_cls = notifier_p.start() - self.notifier = mock.Mock() - notifier_cls.return_value = self.notifier - cfg.CONF.set_override('integration_bridge', - 'br_int', group='SDNVE') - kwargs = sdnve_neutron_agent.create_agent_config_map(cfg.CONF) - - class MockFixedIntervalLoopingCall(object): - def __init__(self, f): - self.f = f - - def start(self, interval=0): - self.f() - - with mock.patch('neutron.plugins.ibm.agent.sdnve_neutron_agent.' - 'SdnveNeutronAgent.setup_integration_br', - return_value=mock.Mock()),\ - mock.patch('oslo_service.loopingcall.' - 'FixedIntervalLoopingCall', - new=MockFixedIntervalLoopingCall): - self.agent = sdnve_neutron_agent.SdnveNeutronAgent(**kwargs) - - def test_setup_physical_interfaces(self): - with mock.patch.object(self.agent.int_br, - 'add_port') as add_port_func: - with mock.patch.object(ip_lib, - 'device_exists', - return_valxue=True): - self.agent.setup_physical_interfaces({"interface1": "eth1"}) - add_port_func.assert_called_once_with('eth1') - - def test_setup_physical_interfaces_none(self): - with mock.patch.object(self.agent.int_br, - 'add_port') as add_port_func: - with mock.patch.object(ip_lib, - 'device_exists', - return_valxue=True): - self.agent.setup_physical_interfaces({}) - self.assertFalse(add_port_func.called) - - def test_get_info_set_controller(self): - with mock.patch.object(self.agent.int_br, - 'set_controller') as set_controller_func: - kwargs = {} - kwargs['info'] = {'new_controller': '10.10.10.1'} - self.agent.info_update('dummy', **kwargs) - set_controller_func.assert_called_once_with(['tcp:10.10.10.1']) - - def test_get_info(self): - with mock.patch.object(self.agent.int_br, - 'set_controller') as set_controller_func: - kwargs = {} - self.agent.info_update('dummy', **kwargs) - self.assertFalse(set_controller_func.called) diff --git a/neutron/tests/unit/plugins/ibm/test_sdnve_api.py b/neutron/tests/unit/plugins/ibm/test_sdnve_api.py deleted file mode 100644 index 22dfcb340..000000000 --- a/neutron/tests/unit/plugins/ibm/test_sdnve_api.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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 mock -from oslo_utils import uuidutils - -from neutron.plugins.ibm.common import constants -from neutron.plugins.ibm import sdnve_api -from neutron.tests import base - -RESOURCE_PATH = { - 'network': "ln/networks/", -} -RESOURCE = 'network' -HTTP_OK = 200 -TENANT_ID = uuidutils.generate_uuid() - - -class TestSdnveApi(base.BaseTestCase): - - def setUp(self): - super(TestSdnveApi, self).setUp() - - class MockKeystoneClient(object): - def __init__(self, **kwargs): - pass - - def get_tenant_name(self, id): - return 'test tenant name' - - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'KeystoneClient', - new=MockKeystoneClient): - self.api = sdnve_api.Client() - - def mock_do_request(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (HTTP_OK, url) - - def mock_do_request_tenant(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (HTTP_OK, {'id': TENANT_ID, - 'network_type': constants.TENANT_TYPE_OF}) - - def mock_do_request_no_tenant(self, method, url, body=None, headers=None, - params=None, connection_type=None): - return (None, None) - - def mock_process_request(self, body): - return body - - def test_sdnve_api_list(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_list(RESOURCE) - self.assertEqual(result, (HTTP_OK, RESOURCE_PATH[RESOURCE])) - - def test_sdnve_api_show(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_show(RESOURCE, TENANT_ID) - self.assertEqual(result, - (HTTP_OK, RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_api_create(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.process_request', - new=self.mock_process_request): - result = self.api.sdnve_create(RESOURCE, '') - self.assertEqual(result, (HTTP_OK, RESOURCE_PATH[RESOURCE])) - - def test_sdnve_api_update(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.process_request', - new=self.mock_process_request): - result = self.api.sdnve_update(RESOURCE, TENANT_ID, '') - self.assertEqual(result, - (HTTP_OK, - RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_api_delete(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request): - result = self.api.sdnve_delete(RESOURCE, TENANT_ID) - self.assertEqual(result, - (HTTP_OK, RESOURCE_PATH[RESOURCE] + TENANT_ID)) - - def test_sdnve_get_tenant_by_id(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_tenant): - id = TENANT_ID - result = self.api.sdnve_get_tenant_byid(id) - self.assertEqual(result, - (TENANT_ID, constants.TENANT_TYPE_OF)) - - def test_sdnve_check_and_create_tenant(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_tenant): - id = TENANT_ID - result = self.api.sdnve_check_and_create_tenant(id) - self.assertEqual(result, TENANT_ID) - - def test_sdnve_check_and_create_tenant_fail(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' - 'Client.do_request', - new=self.mock_do_request_no_tenant): - id = TENANT_ID - result = self.api.sdnve_check_and_create_tenant( - id, constants.TENANT_TYPE_OF) - self.assertIsNone(result) - - def test_process_request(self): - my_request = {'key_1': 'value_1', 'router:external': 'True', - 'key_2': 'value_2'} - expected = {'key_1': 'value_1', 'router_external': 'True', - 'key_2': 'value_2'} - result = self.api.process_request(my_request) - self.assertEqual(expected, result) diff --git a/neutron/tests/unit/plugins/ibm/test_sdnve_plugin.py b/neutron/tests/unit/plugins/ibm/test_sdnve_plugin.py deleted file mode 100644 index ff79eafff..000000000 --- a/neutron/tests/unit/plugins/ibm/test_sdnve_plugin.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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 mock - -from neutron.extensions import portbindings -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin -from neutron.tests.unit.extensions import test_l3 as test_l3 - -from neutron.plugins.ibm.common import constants - - -_plugin_name = ('neutron.plugins.ibm.' - 'sdnve_neutron_plugin.SdnvePluginV2') -HTTP_OK = 200 - - -class MockClient(object): - def sdnve_list(self, resource, **params): - return (HTTP_OK, 'body') - - def sdnve_show(self, resource, specific, **params): - return (HTTP_OK, 'body') - - def sdnve_create(self, resource, body): - return (HTTP_OK, 'body') - - def sdnve_update(self, resource, specific, body=None): - return (HTTP_OK, 'body') - - def sdnve_delete(self, resource, specific): - return (HTTP_OK, 'body') - - def sdnve_get_tenant_byid(self, os_tenant_id): - return (os_tenant_id, constants.TENANT_TYPE_OF) - - def sdnve_check_and_create_tenant( - self, os_tenant_id, network_type=None): - return os_tenant_id - - def sdnve_get_controller(self): - return - - -class MockKeystoneClient(object): - def __init__(self, **kwargs): - pass - - def get_tenant_type(self, id): - return constants.TENANT_TYPE_OF - - def get_tenant_name(self, id): - return "tenant name" - - -class IBMPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - def setUp(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' 'KeystoneClient', - new=MockKeystoneClient),\ - mock.patch('neutron.plugins.ibm.sdnve_api.' 'Client', - new=MockClient): - super(IBMPluginV2TestCase, self).setUp(plugin=_plugin_name) - - -class TestIBMBasicGet(test_plugin.TestBasicGet, - IBMPluginV2TestCase): - pass - - -class TestIBMV2HTTPResponse(test_plugin.TestV2HTTPResponse, - IBMPluginV2TestCase): - pass - - -class TestIBMNetworksV2(test_plugin.TestNetworksV2, - IBMPluginV2TestCase): - pass - - -class TestIBMPortsV2(test_plugin.TestPortsV2, - IBMPluginV2TestCase): - pass - - -class TestIBMSubnetsV2(test_plugin.TestSubnetsV2, - IBMPluginV2TestCase): - pass - - -class TestIBMPortBinding(IBMPluginV2TestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - - -class IBMPluginRouterTestCase(test_l3.L3NatDBIntTestCase): - - def setUp(self): - with mock.patch('neutron.plugins.ibm.sdnve_api.' 'KeystoneClient', - new=MockKeystoneClient),\ - mock.patch('neutron.plugins.ibm.sdnve_api.' 'Client', - new=MockClient): - super(IBMPluginRouterTestCase, self).setUp(plugin=_plugin_name) - - def test_floating_port_status_not_applicable(self): - self.skipTest('Plugin changes floating port status') diff --git a/setup.cfg b/setup.cfg index c2ac4ac29..5b4104854 100644 --- a/setup.cfg +++ b/setup.cfg @@ -56,7 +56,6 @@ data_files = etc/neutron/plugins/cisco/cisco_router_plugin.ini etc/neutron/plugins/cisco/cisco_vpn_agent.ini etc/neutron/plugins/embrane = etc/neutron/plugins/embrane/heleos_conf.ini - etc/neutron/plugins/ibm = etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini etc/neutron/plugins/midonet = etc/neutron/plugins/midonet/midonet.ini etc/neutron/plugins/ml2 = etc/neutron/plugins/bigswitch/restproxy.ini @@ -84,7 +83,6 @@ console_scripts = neutron-dhcp-agent = neutron.cmd.eventlet.agents.dhcp:main neutron-hyperv-agent = neutron.cmd.eventlet.plugins.hyperv_neutron_agent:main neutron-keepalived-state-change = neutron.cmd.keepalived_state_change:main - neutron-ibm-agent = neutron.plugins.ibm.agent.sdnve_neutron_agent:main neutron-ipset-cleanup = neutron.cmd.ipset_cleanup:main neutron-l3-agent = neutron.cmd.eventlet.agents.l3:main neutron-linuxbridge-agent = neutron.plugins.ml2.drivers.linuxbridge.agent.linuxbridge_neutron_agent:main @@ -110,7 +108,6 @@ neutron.core_plugins = brocade = neutron.plugins.brocade.NeutronPlugin:BrocadePluginV2 cisco = neutron.plugins.cisco.network_plugin:PluginV2 embrane = neutron.plugins.embrane.plugins.embrane_ml2_plugin:EmbraneMl2Plugin - ibm = neutron.plugins.ibm.sdnve_neutron_plugin:SdnvePluginV2 midonet = neutron.plugins.midonet.plugin:MidonetPluginV2 ml2 = neutron.plugins.ml2.plugin:Ml2Plugin nuage = neutron.plugins.nuage.plugin:NuagePlugin