From: armando-migliaccio Date: Wed, 12 Feb 2014 21:39:48 +0000 (-0800) Subject: Rename/refactoring of NVP api client to NSX X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=200e159ea6536910f184776fbda90c8297e2b49b;p=openstack-build%2Fneutron-build.git Rename/refactoring of NVP api client to NSX Partial-implements blueprint nicira-plugin-renaming Change-Id: I7d3bc088762f53473892480b2e238fe60c2c0b74 --- diff --git a/neutron/plugins/nicira/NeutronPlugin.py b/neutron/plugins/nicira/NeutronPlugin.py index b706b5db5..bad803cde 100644 --- a/neutron/plugins/nicira/NeutronPlugin.py +++ b/neutron/plugins/nicira/NeutronPlugin.py @@ -61,6 +61,7 @@ from neutron.openstack.common.db import exception as db_exc from neutron.openstack.common import excutils from neutron.openstack.common import lockutils from neutron.plugins.common import constants as plugin_const +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import config # noqa from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import nsx_utils @@ -80,7 +81,6 @@ from neutron.plugins.nicira.nsxlib import queue as queuelib from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import secgroup as secgrouplib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient LOG = logging.getLogger("NeutronPlugin") @@ -265,7 +265,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, port_data.get('admin_state_up', True), ip_addresses, port_data.get('mac_address')) LOG.debug(_("Created NVP router port:%s"), lrouter_port['uuid']) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: LOG.exception(_("Unable to create port on NVP logical router %s"), nsx_router_id) raise nvp_exc.NvpPluginException( @@ -349,7 +349,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, attachment_vlan) LOG.debug(_("Attached %(att)s to NVP router port %(port)s"), {'att': attachment, 'port': nsx_router_port_id}) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: # Must remove NVP logical port routerlib.delete_router_lport(cluster, nsx_router_id, nsx_router_port_id) @@ -404,7 +404,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, return self._handle_lswitch_selection( context, self.cluster, network, network_bindings, max_ports, allow_extra_lswitches) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: err_desc = _("An exception occurred while selecting logical " "switch for the port") LOG.exception(err_desc) @@ -472,7 +472,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, LOG.debug(_("_nvp_create_port completed for port %(name)s " "on network %(network_id)s. The new port id is " "%(id)s."), port_data) - except (NvpApiClient.NvpApiException, q_exc.NeutronException): + except (api_exc.NsxApiException, q_exc.NeutronException): self._handle_create_port_exception( context, port_data['id'], selected_lswitch and selected_lswitch['uuid'], @@ -539,7 +539,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, nsx_router_id, nsx_switch_id, nsx_port_id) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: # Do not raise because the issue might as well be that the # router has already been deleted, so there would be nothing # to do here @@ -584,7 +584,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, "%(name)s on network %(network_id)s. The new " "port id is %(id)s."), port_data) - except (NvpApiClient.NvpApiException, q_exc.NeutronException): + except (api_exc.NsxApiException, q_exc.NeutronException): self._handle_create_port_exception( context, port_data['id'], selected_lswitch and selected_lswitch['uuid'], @@ -677,11 +677,11 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, "L3GatewayAttachment", self.cluster.default_l3_gw_service_uuid) - except NvpApiClient.ResourceNotFound: + except api_exc.ResourceNotFound: raise nvp_exc.NvpPluginException( err_msg=_("Logical router resource %s not found " "on NVP platform") % router_id) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: raise nvp_exc.NvpPluginException( err_msg=_("Unable to update logical router" "on NVP Platform")) @@ -1061,8 +1061,8 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, port['id']) except (TypeError, KeyError, - NvpApiClient.NvpApiException, - NvpApiClient.ResourceNotFound): + api_exc.NsxApiException, + api_exc.ResourceNotFound): # Do not raise because the issue might as well be that the # router has already been deleted, so there would be nothing # to do here @@ -1406,7 +1406,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, "without specifying the 'distributed' attribute.") LOG.exception(msg) raise q_exc.BadRequest(resource='router', msg=msg) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: err_msg = _("Unable to create logical router on NVP Platform") LOG.exception(err_msg) raise nvp_exc.NvpPluginException(err_msg=err_msg) @@ -1501,7 +1501,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, # Set external gateway and remove router in case of failure try: self._update_router_gw_info(context, router_db['id'], gw_info) - except (q_exc.NeutronException, NvpApiClient.NvpApiException): + except (q_exc.NeutronException, api_exc.NsxApiException): with excutils.save_and_reraise_exception(): # As setting gateway failed, the router must be deleted # in order to ensure atomicity @@ -1569,7 +1569,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, raise nvp_exc.NvpPluginException( err_msg=_("Logical router %s not found " "on NVP Platform") % router_id) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: raise nvp_exc.NvpPluginException( err_msg=_("Unable to update logical router on NVP Platform")) except nvp_exc.NvpInvalidVersion: @@ -1631,8 +1631,8 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, except q_exc.NotFound: # This is not a fatal error, but needs to be logged LOG.warning(_("Logical router '%s' not found " - "on NVP Platform"), nsx_router_id) - except NvpApiClient.NvpApiException: + "on NVP Platform"), router_id) + except api_exc.NsxApiException: raise nvp_exc.NvpPluginException( err_msg=(_("Unable to delete logical router '%s' " "on NVP Platform") % nsx_router_id)) @@ -1773,11 +1773,11 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, self.cluster, nsx_router_id, "NoSourceNatRule", max_num_expected=1, min_num_expected=0, destination_ip_addresses=subnet['cidr']) - except NvpApiClient.ResourceNotFound: + except api_exc.ResourceNotFound: raise nvp_exc.NvpPluginException( err_msg=(_("Logical router resource %s not found " "on NVP platform") % router_id)) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: raise nvp_exc.NvpPluginException( err_msg=(_("Unable to update logical router" "on NVP Platform"))) @@ -1809,7 +1809,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, min_num_expected=min_num_rules_expected, destination_ip_addresses=internal_ip) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: LOG.exception(_("An error occurred while removing NAT rules " "on the NVP platform for floating ip:%s"), floating_ip_address) @@ -1947,7 +1947,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, routerlib.update_lrouter_port_ips( self.cluster, nsx_router_id, nsx_gw_port_id, ips_to_add=nvp_floating_ips, ips_to_remove=[]) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: LOG.exception(_("An error occurred while creating NAT " "rules on the NVP platform for floating " "ip:%(floating_ip)s mapped to " @@ -2016,9 +2016,9 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, nsx_res = l2gwlib.create_l2_gw_service( self.cluster, tenant_id, gw_data['name'], devices) nsx_uuid = nsx_res.get('uuid') - except NvpApiClient.Conflict: + except api_exc.Conflict: raise nvp_exc.NvpL2GatewayAlreadyInUse(gateway=gw_data['name']) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: err_msg = _("Unable to create l2_gw_service for: %s") % gw_data LOG.exception(err_msg) raise nvp_exc.NvpPluginException(err_msg=err_msg) @@ -2039,7 +2039,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, super(NvpPluginV2, self).delete_network_gateway( context, gateway_id) l2gwlib.delete_l2_gw_service(self.cluster, gateway_id) - except NvpApiClient.ResourceNotFound: + except api_exc.ResourceNotFound: # Do not cause a 500 to be returned to the user if # the corresponding NVP resource does not exist LOG.exception(_("Unable to remove gateway service from " @@ -2069,7 +2069,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, if name: try: l2gwlib.update_l2_gw_service(self.cluster, id, name) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: # Consider backend failures as non-fatal, but still warn # because this might indicate something dodgy is going on LOG.warn(_("Unable to update name on NVP backend " @@ -2084,7 +2084,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, try: return super(NvpPluginV2, self).connect_network( context, network_gateway_id, network_mapping_info) - except NvpApiClient.Conflict: + except api_exc.Conflict: raise nvp_exc.NvpL2GatewayAlreadyInUse(gateway=network_gateway_id) def disconnect_network(self, context, network_gateway_id, diff --git a/neutron/plugins/nicira/NeutronServicePlugin.py b/neutron/plugins/nicira/NeutronServicePlugin.py index 8d4947778..098bee5a2 100644 --- a/neutron/plugins/nicira/NeutronServicePlugin.py +++ b/neutron/plugins/nicira/NeutronServicePlugin.py @@ -30,6 +30,7 @@ from neutron.extensions import routedserviceinsertion as rsi from neutron.openstack.common import excutils from neutron.openstack.common import log as logging from neutron.plugins.common import constants as service_constants +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import config # noqa from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import utils @@ -40,7 +41,6 @@ from neutron.plugins.nicira.extensions import servicerouter as sr from neutron.plugins.nicira import NeutronPlugin from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira.vshield.common import ( constants as vcns_const) from neutron.plugins.nicira.vshield.common.constants import RouterStatus @@ -417,7 +417,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin, ls_port = switchlib.create_lport( self.cluster, lswitch['uuid'], tenant_id, '', '', lrouter['uuid'], True) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: msg = (_("An exception occurred while creating a port " "on lswitch %s") % lswitch['uuid']) LOG.exception(msg) @@ -432,7 +432,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin, self.cluster, lrouter['uuid'], tenant_id, neutron_port_id, pname, admin_status_enabled, [vcns_const.INTEGRATION_LR_IPADDRESS]) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: msg = (_("Unable to create port on NVP logical router %s") % name) LOG.exception(msg) switchlib.delete_port( @@ -444,7 +444,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin, self._update_router_port_attachment( self.cluster, None, lrouter['uuid'], {}, lr_port['uuid'], 'PatchAttachment', ls_port['uuid'], None) - except NvpApiClient.NvpApiException as e: + except api_exc.NsxApiException as e: # lr_port should have been deleted switchlib.delete_port( self.cluster, lswitch['uuid'], ls_port['uuid']) diff --git a/neutron/plugins/nicira/NvpApiClient.py b/neutron/plugins/nicira/NvpApiClient.py deleted file mode 100644 index 6d6272230..000000000 --- a/neutron/plugins/nicira/NvpApiClient.py +++ /dev/null @@ -1,260 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, 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. -# -# @author: Somik Behera, Nicira Networks, Inc. - -import httplib # basic HTTP library for HTTPS connections -import logging -from neutron.plugins.nicira.api_client import ( - client_eventlet, request_eventlet) - -LOG = logging.getLogger("NVPApiHelper") -LOG.setLevel(logging.INFO) - - -def _find_nvp_version_in_headers(headers): - # be safe if headers is None - do not cause a failure - for (header_name, header_value) in (headers or ()): - try: - if header_name == 'server': - return NVPVersion(header_value.split('/')[1]) - except IndexError: - LOG.warning(_("Unable to fetch NVP version from response " - "headers:%s"), headers) - - -class NVPVersion(object): - """Abstracts NVP version by exposing major and minor.""" - - def __init__(self, nvp_version): - self.full_version = nvp_version.split('.') - self.major = int(self.full_version[0]) - self.minor = int(self.full_version[1]) - - def __str__(self): - return '.'.join(self.full_version) - - -class NVPApiHelper(client_eventlet.NvpApiClientEventlet): - '''API helper class. - - Helper class to do basic login, cookie management, and provide base - method to send HTTP requests. - - Implements new eventlet-based framework derived from the management - console nvp_gevent_client module. - ''' - - def __init__(self, api_providers, user, password, request_timeout, - http_timeout, retries, redirects, - concurrent_connections=10, nvp_gen_timeout=-1): - '''Constructor. - - :param api_providers: a list of tuples in the form: - (host, port, is_ssl=True). Passed on to NvpClientEventlet. - :param user: the login username. - :param password: the login password. - :param concurrent_connections: the number of concurrent connections. - :param request_timeout: all operations (including retries, redirects - from unresponsive controllers, etc) should finish within this - timeout. - :param http_timeout: how long to wait before aborting an - unresponsive controller (and allow for retries to another - controller in the cluster) - :param retries: the number of concurrent connections. - :param redirects: the number of concurrent connections. - ''' - client_eventlet.NvpApiClientEventlet.__init__( - self, api_providers, user, password, concurrent_connections, - nvp_gen_timeout) - - self._request_timeout = request_timeout - self._http_timeout = http_timeout - self._retries = retries - self._redirects = redirects - self._nvp_version = None - - # NOTE(salvatore-orlando): This method is not used anymore. Login is now - # performed automatically inside the request eventlet if necessary. - def login(self, user=None, password=None): - '''Login to NVP controller. - - Assumes same password is used for all controllers. - - :param user: NVP controller user (usually admin). Provided for - backwards compatibility. In the normal mode of operation - this should be None. - :param password: NVP controller password. Provided for backwards - compatibility. In the normal mode of operation this should - be None. - - :returns: Does not return a value. - ''' - if user: - self._user = user - if password: - self._password = password - - return client_eventlet.NvpApiClientEventlet._login(self) - - def request(self, method, url, body="", content_type="application/json"): - '''Issues request to controller.''' - - g = request_eventlet.NvpGenericRequestEventlet( - self, method, url, body, content_type, auto_login=True, - request_timeout=self._request_timeout, - http_timeout=self._http_timeout, - retries=self._retries, redirects=self._redirects) - g.start() - response = g.join() - LOG.debug(_('NVPApiHelper.request() returns "%s"'), response) - - # response is a modified HTTPResponse object or None. - # response.read() will not work on response as the underlying library - # request_eventlet.NvpApiRequestEventlet has already called this - # method in order to extract the body and headers for processing. - # NvpApiRequestEventlet derived classes call .read() and - # .getheaders() on the HTTPResponse objects and store the results in - # the response object's .body and .headers data members for future - # access. - - if response is None: - # Timeout. - LOG.error(_('Request timed out: %(method)s to %(url)s'), - {'method': method, 'url': url}) - raise RequestTimeout() - - status = response.status - if status == httplib.UNAUTHORIZED: - raise UnAuthorizedRequest() - - # Fail-fast: Check for exception conditions and raise the - # appropriate exceptions for known error codes. - if status in self.error_codes: - LOG.error(_("Received error code: %s"), status) - LOG.error(_("Server Error Message: %s"), response.body) - self.error_codes[status](self, response) - - # Continue processing for non-error condition. - if (status != httplib.OK and status != httplib.CREATED - and status != httplib.NO_CONTENT): - LOG.error(_("%(method)s to %(url)s, unexpected response code: " - "%(status)d (content = '%(body)s')"), - {'method': method, 'url': url, - 'status': response.status, 'body': response.body}) - return None - - if not self._nvp_version: - self._nvp_version = _find_nvp_version_in_headers(response.headers) - - return response.body - - def get_nvp_version(self): - if not self._nvp_version: - # Determine the NVP version by querying the control - # cluster nodes. Currently, the version will be the - # one of the server that responds. - self.request('GET', '/ws.v1/control-cluster/node') - if not self._nvp_version: - LOG.error(_('Unable to determine NVP version. ' - 'Plugin might not work as expected.')) - return self._nvp_version - - def fourZeroFour(self, response=None): - raise ResourceNotFound() - - def fourZeroNine(self, response=None): - raise Conflict() - - def fiveZeroThree(self, response=None): - raise ServiceUnavailable() - - def fourZeroThree(self, response=None): - if 'read-only' in response.body: - raise ReadOnlyMode() - else: - raise Forbidden() - - def zero(self, response=None): - raise NvpApiException() - - # TODO(del): ensure error_codes are handled/raised appropriately - # in api_client. - error_codes = {404: fourZeroFour, - 405: zero, - 409: fourZeroNine, - 503: fiveZeroThree, - 403: fourZeroThree, - 301: zero, - 307: zero, - 400: zero, - 500: zero, - 501: zero, - 503: zero} - - -class NvpApiException(Exception): - """Base NvpApiClient Exception. - - To correctly use this class, inherit from it and define - a 'message' property. That message will get printf'd - with the keyword arguments provided to the constructor. - - """ - message = _("An unknown exception occurred.") - - def __init__(self, **kwargs): - try: - self._error_string = self.message % kwargs - - except Exception: - # at least get the core message out if something happened - self._error_string = self.message - - def __str__(self): - return self._error_string - - -class UnAuthorizedRequest(NvpApiException): - message = _("Server denied session's authentication credentials.") - - -class ResourceNotFound(NvpApiException): - message = _("An entity referenced in the request was not found.") - - -class Conflict(NvpApiException): - message = _("Request conflicts with configuration on a different " - "entity.") - - -class ServiceUnavailable(NvpApiException): - message = _("Request could not completed because the associated " - "resource could not be reached.") - - -class Forbidden(NvpApiException): - message = _("The request is forbidden from accessing the " - "referenced resource.") - - -class ReadOnlyMode(Forbidden): - message = _("Create/Update actions are forbidden when in read-only mode.") - - -class RequestTimeout(NvpApiException): - message = _("The request has timed out.") diff --git a/neutron/plugins/nicira/api_client/__init__.py b/neutron/plugins/nicira/api_client/__init__.py index 268462585..6b7126b02 100644 --- a/neutron/plugins/nicira/api_client/__init__.py +++ b/neutron/plugins/nicira/api_client/__init__.py @@ -1,18 +1,29 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, Inc. +# Copyright 2012 VMware, Inc. +# # All Rights Reserved # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# 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 +# 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. +# 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. # -# @author: Aaron Rosen, Nicira Networks, Inc. + +import httplib + + +def ctrl_conn_to_str(conn): + """Returns a string representing a connection URL to the controller.""" + if isinstance(conn, httplib.HTTPSConnection): + proto = "https://" + elif isinstance(conn, httplib.HTTPConnection): + proto = "http://" + else: + raise TypeError(_('Invalid connection type: %s') % type(conn)) + return "%s%s:%s" % (proto, conn.host, conn.port) diff --git a/neutron/plugins/nicira/api_client/base.py b/neutron/plugins/nicira/api_client/base.py new file mode 100644 index 000000000..d819ae3d5 --- /dev/null +++ b/neutron/plugins/nicira/api_client/base.py @@ -0,0 +1,246 @@ +# Copyright 2012 VMware, Inc. +# +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from abc import ABCMeta +import httplib +import six +import time + +from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import ctrl_conn_to_str + +LOG = logging.getLogger(__name__) + +GENERATION_ID_TIMEOUT = -1 +DEFAULT_CONCURRENT_CONNECTIONS = 3 +DEFAULT_CONNECT_TIMEOUT = 5 + + +@six.add_metaclass(ABCMeta) +class ApiClientBase(object): + """An abstract baseclass for all API client implementations.""" + + CONN_IDLE_TIMEOUT = 60 * 15 + + def _create_connection(self, host, port, is_ssl): + if is_ssl: + return httplib.HTTPSConnection(host, port, + timeout=self._connect_timeout) + return httplib.HTTPConnection(host, port, + timeout=self._connect_timeout) + + @staticmethod + def _conn_params(http_conn): + is_ssl = isinstance(http_conn, httplib.HTTPSConnection) + return (http_conn.host, http_conn.port, is_ssl) + + @property + def user(self): + return self._user + + @property + def password(self): + return self._password + + @property + def config_gen(self): + # If NSX_gen_timeout is not -1 then: + # Maintain a timestamp along with the generation ID. Hold onto the + # ID long enough to be useful and block on sequential requests but + # not long enough to persist when Onix db is cleared, which resets + # the generation ID, causing the DAL to block indefinitely with some + # number that's higher than the cluster's value. + if self._gen_timeout != -1: + ts = self._config_gen_ts + if ts is not None: + if (time.time() - ts) > self._gen_timeout: + return None + return self._config_gen + + @config_gen.setter + def config_gen(self, value): + if self._config_gen != value: + if self._gen_timeout != -1: + self._config_gen_ts = time.time() + self._config_gen = value + + def auth_cookie(self, conn): + cookie = None + data = self._get_provider_data(conn) + if data: + cookie = data[1] + return cookie + + def set_auth_cookie(self, conn, cookie): + data = self._get_provider_data(conn) + if data: + self._set_provider_data(conn, (data[0], cookie)) + + def acquire_connection(self, auto_login=True, headers=None, rid=-1): + '''Check out an available HTTPConnection instance. + + Blocks until a connection is available. + :auto_login: automatically logins before returning conn + :headers: header to pass on to login attempt + :param rid: request id passed in from request eventlet. + :returns: An available HTTPConnection instance or None if no + api_providers are configured. + ''' + if not self._api_providers: + LOG.warn(_("[%d] no API providers currently available."), rid) + return None + if self._conn_pool.empty(): + LOG.debug(_("[%d] Waiting to acquire API client connection."), rid) + priority, conn = self._conn_pool.get() + now = time.time() + if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT: + LOG.info(_("[%(rid)d] Connection %(conn)s idle for %(sec)0.2f " + "seconds; reconnecting."), + {'rid': rid, 'conn': ctrl_conn_to_str(conn), + 'sec': now - conn.last_used}) + conn = self._create_connection(*self._conn_params(conn)) + + conn.last_used = now + conn.priority = priority # stash current priority for release + qsize = self._conn_pool.qsize() + LOG.debug(_("[%(rid)d] Acquired connection %(conn)s. %(qsize)d " + "connection(s) available."), + {'rid': rid, 'conn': ctrl_conn_to_str(conn), 'qsize': qsize}) + if auto_login and self.auth_cookie(conn) is None: + self._wait_for_login(conn, headers) + return conn + + def release_connection(self, http_conn, bad_state=False, + service_unavail=False, rid=-1): + '''Mark HTTPConnection instance as available for check-out. + + :param http_conn: An HTTPConnection instance obtained from this + instance. + :param bad_state: True if http_conn is known to be in a bad state + (e.g. connection fault.) + :service_unavail: True if http_conn returned 503 response. + :param rid: request id passed in from request eventlet. + ''' + conn_params = self._conn_params(http_conn) + if self._conn_params(http_conn) not in self._api_providers: + LOG.debug(_("[%(rid)d] Released connection %(conn)s is not an " + "API provider for the cluster"), + {'rid': rid, 'conn': ctrl_conn_to_str(http_conn)}) + return + elif hasattr(http_conn, "no_release"): + return + + if bad_state: + # Reconnect to provider. + LOG.warn(_("[%(rid)d] Connection returned in bad state, " + "reconnecting to %(conn)s"), + {'rid': rid, 'conn': ctrl_conn_to_str(http_conn)}) + http_conn = self._create_connection(*self._conn_params(http_conn)) + priority = self._next_conn_priority + self._next_conn_priority += 1 + elif service_unavail: + # http_conn returned a service unaviable response, put other + # connections to the same controller at end of priority queue, + conns = [] + while not self._conn_pool.empty(): + priority, conn = self._conn_pool.get() + if self._conn_params(conn) == conn_params: + priority = self._next_conn_priority + self._next_conn_priority += 1 + conns.append((priority, conn)) + for priority, conn in conns: + self._conn_pool.put((priority, conn)) + # put http_conn at end of queue also + priority = self._next_conn_priority + self._next_conn_priority += 1 + else: + priority = http_conn.priority + + self._conn_pool.put((priority, http_conn)) + LOG.debug(_("[%(rid)d] Released connection %(conn)s. %(qsize)d " + "connection(s) available."), + {'rid': rid, 'conn': ctrl_conn_to_str(http_conn), + 'qsize': self._conn_pool.qsize()}) + + def _wait_for_login(self, conn, headers=None): + '''Block until a login has occurred for the current API provider.''' + + data = self._get_provider_data(conn) + if data is None: + LOG.error(_("Login request for an invalid connection: '%s'"), + ctrl_conn_to_str(conn)) + return + provider_sem = data[0] + if provider_sem.acquire(blocking=False): + try: + cookie = self._login(conn, headers) + self.set_auth_cookie(conn, cookie) + finally: + provider_sem.release() + else: + LOG.debug(_("Waiting for auth to complete")) + # Wait until we can acquire then release + provider_sem.acquire(blocking=True) + provider_sem.release() + + def _get_provider_data(self, conn_or_conn_params, default=None): + """Get data for specified API provider. + + Args: + conn_or_conn_params: either a HTTP(S)Connection object or the + resolved conn_params tuple returned by self._conn_params(). + default: conn_params if ones passed aren't known + Returns: Data associated with specified provider + """ + conn_params = self._normalize_conn_params(conn_or_conn_params) + return self._api_provider_data.get(conn_params, default) + + def _set_provider_data(self, conn_or_conn_params, data): + """Set data for specified API provider. + + Args: + conn_or_conn_params: either a HTTP(S)Connection object or the + resolved conn_params tuple returned by self._conn_params(). + data: data to associate with API provider + """ + conn_params = self._normalize_conn_params(conn_or_conn_params) + if data is None: + del self._api_provider_data[conn_params] + else: + self._api_provider_data[conn_params] = data + + def _normalize_conn_params(self, conn_or_conn_params): + """Normalize conn_param tuple. + + Args: + conn_or_conn_params: either a HTTP(S)Connection object or the + resolved conn_params tuple returned by self._conn_params(). + + Returns: Normalized conn_param tuple + """ + if (not isinstance(conn_or_conn_params, tuple) and + not isinstance(conn_or_conn_params, httplib.HTTPConnection)): + LOG.debug(_("Invalid conn_params value: '%s'"), + str(conn_or_conn_params)) + return conn_or_conn_params + if isinstance(conn_or_conn_params, httplib.HTTPConnection): + conn_params = self._conn_params(conn_or_conn_params) + else: + conn_params = conn_or_conn_params + host, port, is_ssl = conn_params + if port is None: + port = 443 if is_ssl else 80 + return (host, port, is_ssl) diff --git a/neutron/plugins/nicira/api_client/client.py b/neutron/plugins/nicira/api_client/client.py index 8faacb2f1..fdbb440c5 100644 --- a/neutron/plugins/nicira/api_client/client.py +++ b/neutron/plugins/nicira/api_client/client.py @@ -1,259 +1,143 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, Inc. +# Copyright 2012 VMware, Inc. +# # All Rights Reserved # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at +# 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 +# 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. +# 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. # -# @author: David Lapsley , Nicira Networks, Inc. -# @author: Aaron Rosen, Nicira Networks, Inc. - -from abc import ABCMeta import httplib -import logging -import time - -import six -from neutron.plugins.nicira.api_client.common import ( - _conn_str) +from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import base +from neutron.plugins.nicira.api_client import eventlet_client +from neutron.plugins.nicira.api_client import eventlet_request +from neutron.plugins.nicira.api_client import exception +from neutron.plugins.nicira.api_client import version - -logging.basicConfig(level=logging.INFO) LOG = logging.getLogger(__name__) -#Default parameters. -GENERATION_ID_TIMEOUT = -1 -DEFAULT_CONCURRENT_CONNECTIONS = 3 -DEFAULT_CONNECT_TIMEOUT = 5 - - -@six.add_metaclass(ABCMeta) -class NvpApiClient(object): - '''An abstract baseclass for all NvpApiClient implementations. - - This defines the interface and property structure for synchronous and - coroutine-based classes. - ''' - - CONN_IDLE_TIMEOUT = 60 * 15 - - def _create_connection(self, host, port, is_ssl): - if is_ssl: - return httplib.HTTPSConnection(host, port, - timeout=self._connect_timeout) - return httplib.HTTPConnection(host, port, - timeout=self._connect_timeout) - - @staticmethod - def _conn_params(http_conn): - is_ssl = isinstance(http_conn, httplib.HTTPSConnection) - return (http_conn.host, http_conn.port, is_ssl) - - @property - def user(self): - return self._user - - @property - def password(self): - return self._password - - @property - def nvp_config_gen(self): - # If nvp_gen_timeout is not -1 then: - # Maintain a timestamp along with the generation ID. Hold onto the - # ID long enough to be useful and block on sequential requests but - # not long enough to persist when Onix db is cleared, which resets - # the generation ID, causing the DAL to block indefinitely with some - # number that's higher than the cluster's value. - if self._nvp_gen_timeout != -1: - ts = self._nvp_config_gen_ts - if ts is not None: - if (time.time() - ts) > self._nvp_gen_timeout: - return None - return self._nvp_config_gen - - @nvp_config_gen.setter - def nvp_config_gen(self, value): - if self._nvp_config_gen != value: - if self._nvp_gen_timeout != -1: - self._nvp_config_gen_ts = time.time() - self._nvp_config_gen = value - - def auth_cookie(self, conn): - cookie = None - data = self._get_provider_data(conn) - if data: - cookie = data[1] - return cookie - def set_auth_cookie(self, conn, cookie): - data = self._get_provider_data(conn) - if data: - self._set_provider_data(conn, (data[0], cookie)) - def acquire_connection(self, auto_login=True, headers=None, rid=-1): - '''Check out an available HTTPConnection instance. - - Blocks until a connection is available. - :auto_login: automatically logins before returning conn - :headers: header to pass on to login attempt - :param rid: request id passed in from request eventlet. - :returns: An available HTTPConnection instance or None if no - api_providers are configured. +class NsxApiClient(eventlet_client.EventletApiClient): + """The Nsx API Client.""" + + def __init__(self, api_providers, user, password, + concurrent_connections=base.DEFAULT_CONCURRENT_CONNECTIONS, + gen_timeout=base.GENERATION_ID_TIMEOUT, + use_https=True, + connect_timeout=base.DEFAULT_CONNECT_TIMEOUT, + request_timeout=30, http_timeout=10, retries=2, redirects=2): + '''Constructor. Adds the following: + + :param request_timeout: all operations (including retries, redirects + from unresponsive controllers, etc) should finish within this + timeout. + :param http_timeout: how long to wait before aborting an + unresponsive controller (and allow for retries to another + controller in the cluster) + :param retries: the number of concurrent connections. + :param redirects: the number of concurrent connections. ''' - if not self._api_providers: - LOG.warn(_("[%d] no API providers currently available."), rid) - return None - if self._conn_pool.empty(): - LOG.debug(_("[%d] Waiting to acquire API client connection."), rid) - priority, conn = self._conn_pool.get() - now = time.time() - if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT: - LOG.info(_("[%(rid)d] Connection %(conn)s idle for %(sec)0.2f " - "seconds; reconnecting."), - {'rid': rid, 'conn': _conn_str(conn), - 'sec': now - conn.last_used}) - conn = self._create_connection(*self._conn_params(conn)) - - conn.last_used = now - conn.priority = priority # stash current priority for release - qsize = self._conn_pool.qsize() - LOG.debug(_("[%(rid)d] Acquired connection %(conn)s. %(qsize)d " - "connection(s) available."), - {'rid': rid, 'conn': _conn_str(conn), 'qsize': qsize}) - if auto_login and self.auth_cookie(conn) is None: - self._wait_for_login(conn, headers) - return conn - - def release_connection(self, http_conn, bad_state=False, - service_unavail=False, rid=-1): - '''Mark HTTPConnection instance as available for check-out. - - :param http_conn: An HTTPConnection instance obtained from this - instance. - :param bad_state: True if http_conn is known to be in a bad state - (e.g. connection fault.) - :service_unavail: True if http_conn returned 503 response. - :param rid: request id passed in from request eventlet. + super(NsxApiClient, self).__init__( + api_providers, user, password, + concurrent_connections=concurrent_connections, + gen_timeout=gen_timeout, use_https=use_https, + connect_timeout=connect_timeout) + + self._request_timeout = request_timeout + self._http_timeout = http_timeout + self._retries = retries + self._redirects = redirects + self._version = None + + # NOTE(salvatore-orlando): This method is not used anymore. Login is now + # performed automatically inside the request eventlet if necessary. + def login(self, user=None, password=None): + '''Login to NSX controller. + + Assumes same password is used for all controllers. + + :param user: controller user (usually admin). Provided for + backwards compatibility. In the normal mode of operation + this should be None. + :param password: controller password. Provided for backwards + compatibility. In the normal mode of operation this should + be None. ''' - conn_params = self._conn_params(http_conn) - if self._conn_params(http_conn) not in self._api_providers: - LOG.debug(_("[%(rid)d] Released connection %(conn)s is not an " - "API provider for the cluster"), - {'rid': rid, 'conn': _conn_str(http_conn)}) - return - elif hasattr(http_conn, "no_release"): - return - - if bad_state: - # Reconnect to provider. - LOG.warn(_("[%(rid)d] Connection returned in bad state, " - "reconnecting to %(conn)s"), - {'rid': rid, 'conn': _conn_str(http_conn)}) - http_conn = self._create_connection(*self._conn_params(http_conn)) - priority = self._next_conn_priority - self._next_conn_priority += 1 - elif service_unavail: - # http_conn returned a service unaviable response, put other - # connections to the same controller at end of priority queue, - conns = [] - while not self._conn_pool.empty(): - priority, conn = self._conn_pool.get() - if self._conn_params(conn) == conn_params: - priority = self._next_conn_priority - self._next_conn_priority += 1 - conns.append((priority, conn)) - for priority, conn in conns: - self._conn_pool.put((priority, conn)) - # put http_conn at end of queue also - priority = self._next_conn_priority - self._next_conn_priority += 1 - else: - priority = http_conn.priority - - self._conn_pool.put((priority, http_conn)) - LOG.debug(_("[%(rid)d] Released connection %(conn)s. %(qsize)d " - "connection(s) available."), - {'rid': rid, 'conn': _conn_str(http_conn), - 'qsize': self._conn_pool.qsize()}) - - def _wait_for_login(self, conn, headers=None): - '''Block until a login has occurred for the current API provider.''' - - data = self._get_provider_data(conn) - if data is None: - LOG.error(_("Login request for an invalid connection: '%s'"), - _conn_str(conn)) - return - provider_sem = data[0] - if provider_sem.acquire(blocking=False): - try: - cookie = self._login(conn, headers) - self.set_auth_cookie(conn, cookie) - finally: - provider_sem.release() - else: - LOG.debug(_("Waiting for auth to complete")) - # Wait until we can acquire then release - provider_sem.acquire(blocking=True) - provider_sem.release() - - def _get_provider_data(self, conn_or_conn_params, default=None): - """Get data for specified API provider. - - Args: - conn_or_conn_params: either a HTTP(S)Connection object or the - resolved conn_params tuple returned by self._conn_params(). - default: conn_params if ones passed aren't known - Returns: Data associated with specified provider - """ - conn_params = self._normalize_conn_params(conn_or_conn_params) - return self._api_provider_data.get(conn_params, default) - - def _set_provider_data(self, conn_or_conn_params, data): - """Set data for specified API provider. - - Args: - conn_or_conn_params: either a HTTP(S)Connection object or the - resolved conn_params tuple returned by self._conn_params(). - data: data to associate with API provider - """ - conn_params = self._normalize_conn_params(conn_or_conn_params) - if data is None: - del self._api_provider_data[conn_params] - else: - self._api_provider_data[conn_params] = data - - def _normalize_conn_params(self, conn_or_conn_params): - """Normalize conn_param tuple. - - Args: - conn_or_conn_params: either a HTTP(S)Connection object or the - resolved conn_params tuple returned by self._conn_params(). + if user: + self._user = user + if password: + self._password = password + + return self._login() + + def request(self, method, url, body="", content_type="application/json"): + '''Issues request to controller.''' + + g = eventlet_request.GenericRequestEventlet( + self, method, url, body, content_type, auto_login=True, + request_timeout=self._request_timeout, + http_timeout=self._http_timeout, + retries=self._retries, redirects=self._redirects) + g.start() + response = g.join() + LOG.debug(_('Request returns "%s"'), response) + + # response is a modified HTTPResponse object or None. + # response.read() will not work on response as the underlying library + # request_eventlet.ApiRequestEventlet has already called this + # method in order to extract the body and headers for processing. + # ApiRequestEventlet derived classes call .read() and + # .getheaders() on the HTTPResponse objects and store the results in + # the response object's .body and .headers data members for future + # access. + + if response is None: + # Timeout. + LOG.error(_('Request timed out: %(method)s to %(url)s'), + {'method': method, 'url': url}) + raise exception.RequestTimeout() + + status = response.status + if status == httplib.UNAUTHORIZED: + raise exception.UnAuthorizedRequest() + + # Fail-fast: Check for exception conditions and raise the + # appropriate exceptions for known error codes. + if status in exception.ERROR_MAPPINGS: + LOG.error(_("Received error code: %s"), status) + LOG.error(_("Server Error Message: %s"), response.body) + exception.ERROR_MAPPINGS[status](response) + + # Continue processing for non-error condition. + if (status != httplib.OK and status != httplib.CREATED + and status != httplib.NO_CONTENT): + LOG.error(_("%(method)s to %(url)s, unexpected response code: " + "%(status)d (content = '%(body)s')"), + {'method': method, 'url': url, + 'status': response.status, 'body': response.body}) + return None - Returns: Normalized conn_param tuple - """ - if (not isinstance(conn_or_conn_params, tuple) and - not isinstance(conn_or_conn_params, httplib.HTTPConnection)): - LOG.debug(_("Invalid conn_params value: '%s'"), - str(conn_or_conn_params)) - return conn_or_conn_params - if isinstance(conn_or_conn_params, httplib.HTTPConnection): - conn_params = self._conn_params(conn_or_conn_params) - else: - conn_params = conn_or_conn_params - host, port, is_ssl = conn_params - if port is None: - port = 443 if is_ssl else 80 - return (host, port, is_ssl) + if not self._version: + self._version = version.find_version(response.headers) + return response.body + + def get_version(self): + if not self._version: + # Determine the controller version by querying the + # cluster nodes. Currently, the version will be the + # one of the server that responds. + self.request('GET', '/ws.v1/control-cluster/node') + if not self._version: + LOG.error(_('Unable to determine NSX version. ' + 'Plugin might not work as expected.')) + return self._version diff --git a/neutron/plugins/nicira/api_client/common.py b/neutron/plugins/nicira/api_client/common.py deleted file mode 100644 index 70e5db379..000000000 --- a/neutron/plugins/nicira/api_client/common.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, 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. -# -# @author: Aaron Rosen, Nicira Networks, Inc. - - -import httplib - - -def _conn_str(conn): - if isinstance(conn, httplib.HTTPSConnection): - proto = "https://" - elif isinstance(conn, httplib.HTTPConnection): - proto = "http://" - else: - raise TypeError(_('_conn_str() invalid connection type: %s') % - type(conn)) - - return "%s%s:%s" % (proto, conn.host, conn.port) diff --git a/neutron/plugins/nicira/api_client/client_eventlet.py b/neutron/plugins/nicira/api_client/eventlet_client.py similarity index 82% rename from neutron/plugins/nicira/api_client/client_eventlet.py rename to neutron/plugins/nicira/api_client/eventlet_client.py index 79ab60b2e..de97853e4 100644 --- a/neutron/plugins/nicira/api_client/client_eventlet.py +++ b/neutron/plugins/nicira/api_client/eventlet_client.py @@ -1,6 +1,5 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, Inc. +# Copyright 2012 VMware, Inc. +# # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -15,29 +14,26 @@ # License for the specific language governing permissions and limitations # under the License. # -# @author: Aaron Rosen, Nicira Networks, Inc. - import eventlet -import logging import time -from neutron.plugins.nicira.api_client import client -from neutron.plugins.nicira.api_client import request_eventlet +from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import base +from neutron.plugins.nicira.api_client import eventlet_request eventlet.monkey_patch() - -logging.basicConfig(level=logging.INFO) LOG = logging.getLogger(__name__) -class NvpApiClientEventlet(client.NvpApiClient): - '''Eventlet-based implementation of NvpApiClient ABC.''' +class EventletApiClient(base.ApiClientBase): + """Eventlet-based implementation of NSX ApiClient ABC.""" def __init__(self, api_providers, user, password, - concurrent_connections=client.DEFAULT_CONCURRENT_CONNECTIONS, - nvp_gen_timeout=client.GENERATION_ID_TIMEOUT, use_https=True, - connect_timeout=client.DEFAULT_CONNECT_TIMEOUT): + concurrent_connections=base.DEFAULT_CONCURRENT_CONNECTIONS, + gen_timeout=base.GENERATION_ID_TIMEOUT, + use_https=True, + connect_timeout=base.DEFAULT_CONNECT_TIMEOUT): '''Constructor :param api_providers: a list of tuples of the form: (host, port, @@ -47,13 +43,13 @@ class NvpApiClientEventlet(client.NvpApiClient): :param concurrent_connections: total number of concurrent connections. :param use_https: whether or not to use https for requests. :param connect_timeout: connection timeout in seconds. - :param nvp_gen_timeout controls how long the generation id is kept + :param gen_timeout controls how long the generation id is kept if set to -1 the generation id is never timed out ''' if not api_providers: api_providers = [] self._api_providers = set([tuple(p) for p in api_providers]) - self._api_provider_data = {} # tuple(semaphore, nvp_session_cookie) + self._api_provider_data = {} # tuple(semaphore, session_cookie) for p in self._api_providers: self._set_provider_data(p, (eventlet.semaphore.Semaphore(1), None)) self._user = user @@ -61,22 +57,22 @@ class NvpApiClientEventlet(client.NvpApiClient): self._concurrent_connections = concurrent_connections self._use_https = use_https self._connect_timeout = connect_timeout - self._nvp_config_gen = None - self._nvp_config_gen_ts = None - self._nvp_gen_timeout = nvp_gen_timeout + self._config_gen = None + self._config_gen_ts = None + self._gen_timeout = gen_timeout # Connection pool is a list of queues. self._conn_pool = eventlet.queue.PriorityQueue() self._next_conn_priority = 1 for host, port, is_ssl in api_providers: - for i in range(concurrent_connections): + for _ in range(concurrent_connections): conn = self._create_connection(host, port, is_ssl) self._conn_pool.put((self._next_conn_priority, conn)) self._next_conn_priority += 1 def acquire_redirect_connection(self, conn_params, auto_login=True, headers=None): - """Check out or create connection to redirected NVP API server. + """Check out or create connection to redirected NSX API server. Args: conn_params: tuple specifying target of redirect, see @@ -139,13 +135,13 @@ class NvpApiClientEventlet(client.NvpApiClient): def _login(self, conn=None, headers=None): '''Issue login request and update authentication cookie.''' cookie = None - g = request_eventlet.NvpLoginRequestEventlet( + g = eventlet_request.LoginRequestEventlet( self, self._user, self._password, conn, headers) g.start() ret = g.join() if ret: if isinstance(ret, Exception): - LOG.error(_('NvpApiClient: login error "%s"'), ret) + LOG.error(_('Login error "%s"'), ret) raise ret cookie = ret.getheader("Set-Cookie") @@ -155,4 +151,4 @@ class NvpApiClientEventlet(client.NvpApiClient): return cookie # Register as subclass. -client.NvpApiClient.register(NvpApiClientEventlet) +base.ApiClientBase.register(EventletApiClient) diff --git a/neutron/plugins/nicira/api_client/request_eventlet.py b/neutron/plugins/nicira/api_client/eventlet_request.py similarity index 84% rename from neutron/plugins/nicira/api_client/request_eventlet.py rename to neutron/plugins/nicira/api_client/eventlet_request.py index 2097ea1c5..56fdb99eb 100644 --- a/neutron/plugins/nicira/api_client/request_eventlet.py +++ b/neutron/plugins/nicira/api_client/eventlet_request.py @@ -1,6 +1,5 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, Inc. +# Copyright 2012 VMware, Inc. +# # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -14,29 +13,23 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Aaron Rosen, Nicira Networks, Inc. - import eventlet import httplib import json -import logging import urllib +from neutron.openstack.common import log as logging from neutron.plugins.nicira.api_client import request -eventlet.monkey_patch() -logging.basicConfig(level=logging.INFO) LOG = logging.getLogger(__name__) -USER_AGENT = "NVP Neutron eventlet client/2.0" +USER_AGENT = "Neutron eventlet client/2.0" -class NvpApiRequestEventlet(request.NvpApiRequest): +class EventletApiRequest(request.ApiRequest): '''Eventlet-based ApiRequest class. This class will form the basis for eventlet-based ApiRequest classes - (e.g. those used by the Neutron NVP Plugin). ''' # Maximum number of green threads present in the system at one time. @@ -53,7 +46,7 @@ class NvpApiRequestEventlet(request.NvpApiRequest): # The request id for the next incoming request. CURRENT_REQUEST_ID = 0 - def __init__(self, nvp_api_client, url, method="GET", body=None, + def __init__(self, client_obj, url, method="GET", body=None, headers=None, request_timeout=request.DEFAULT_REQUEST_TIMEOUT, retries=request.DEFAULT_RETRIES, @@ -61,7 +54,7 @@ class NvpApiRequestEventlet(request.NvpApiRequest): redirects=request.DEFAULT_REDIRECTS, http_timeout=request.DEFAULT_HTTP_TIMEOUT, client_conn=None): '''Constructor.''' - self._api_client = nvp_api_client + self._api_client = client_obj self._url = url self._method = method self._body = body @@ -80,15 +73,13 @@ class NvpApiRequestEventlet(request.NvpApiRequest): self._headers["User-Agent"] = USER_AGENT self._green_thread = None - # Retrieve and store this instance's unique request id. - self._request_id = NvpApiRequestEventlet.CURRENT_REQUEST_ID - + self._request_id = self.CURRENT_REQUEST_ID # Update the class variable that tracks request id. # Request IDs wrap around at MAXIMUM_REQUEST_ID next_request_id = self._request_id + 1 - next_request_id %= NvpApiRequestEventlet.MAXIMUM_REQUEST_ID - NvpApiRequestEventlet.CURRENT_REQUEST_ID = next_request_id + next_request_id %= self.MAXIMUM_REQUEST_ID + self.CURRENT_REQUEST_ID = next_request_id @classmethod def _spawn(cls, func, *args, **kwargs): @@ -116,7 +107,7 @@ class NvpApiRequestEventlet(request.NvpApiRequest): def copy(self): '''Return a copy of this request instance.''' - return NvpApiRequestEventlet( + return EventletApiRequest( self._api_client, self._url, self._method, self._body, self._headers, self._request_timeout, self._retries, self._auto_login, self._redirects, self._http_timeout) @@ -165,17 +156,17 @@ class NvpApiRequestEventlet(request.NvpApiRequest): return response -class NvpLoginRequestEventlet(NvpApiRequestEventlet): +class LoginRequestEventlet(EventletApiRequest): '''Process a login request.''' - def __init__(self, nvp_client, user, password, client_conn=None, + def __init__(self, client_obj, user, password, client_conn=None, headers=None): if headers is None: headers = {} headers.update({"Content-Type": "application/x-www-form-urlencoded"}) body = urllib.urlencode({"username": user, "password": password}) - NvpApiRequestEventlet.__init__( - self, nvp_client, "/ws.v1/login", "POST", body, headers, + super(LoginRequestEventlet, self).__init__( + client_obj, "/ws.v1/login", "POST", body, headers, auto_login=False, client_conn=client_conn) def session_cookie(self): @@ -184,13 +175,13 @@ class NvpLoginRequestEventlet(NvpApiRequestEventlet): return None -class NvpGetApiProvidersRequestEventlet(NvpApiRequestEventlet): - '''Gej a list of API providers.''' +class GetApiProvidersRequestEventlet(EventletApiRequest): + '''Get a list of API providers.''' - def __init__(self, nvp_client): + def __init__(self, client_obj): url = "/ws.v1/control-cluster/node?fields=roles" - NvpApiRequestEventlet.__init__( - self, nvp_client, url, "GET", auto_login=True) + super(GetApiProvidersRequestEventlet, self).__init__( + client_obj, url, "GET", auto_login=True) def api_providers(self): """Parse api_providers from response. @@ -220,18 +211,18 @@ class NvpGetApiProvidersRequestEventlet(NvpApiRequestEventlet): return None -class NvpGenericRequestEventlet(NvpApiRequestEventlet): +class GenericRequestEventlet(EventletApiRequest): '''Handle a generic request.''' - def __init__(self, nvp_client, method, url, body, content_type, + def __init__(self, client_obj, method, url, body, content_type, auto_login=False, request_timeout=request.DEFAULT_REQUEST_TIMEOUT, http_timeout=request.DEFAULT_HTTP_TIMEOUT, retries=request.DEFAULT_RETRIES, redirects=request.DEFAULT_REDIRECTS): headers = {"Content-Type": content_type} - NvpApiRequestEventlet.__init__( - self, nvp_client, url, method, body, headers, + super(GenericRequestEventlet, self).__init__( + client_obj, url, method, body, headers, request_timeout=request_timeout, retries=retries, auto_login=auto_login, redirects=redirects, http_timeout=http_timeout) @@ -242,5 +233,4 @@ class NvpGenericRequestEventlet(NvpApiRequestEventlet): return None -# Register subclasses -request.NvpApiRequest.register(NvpApiRequestEventlet) +request.ApiRequest.register(EventletApiRequest) diff --git a/neutron/plugins/nicira/api_client/exception.py b/neutron/plugins/nicira/api_client/exception.py new file mode 100644 index 000000000..46b870423 --- /dev/null +++ b/neutron/plugins/nicira/api_client/exception.py @@ -0,0 +1,106 @@ +# Copyright 2014 VMware, Inc. +# +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + + +class NsxApiException(Exception): + """Base NSX API Client Exception. + + To correctly use this class, inherit from it and define + a 'message' property. That message will get printf'd + with the keyword arguments provided to the constructor. + + """ + message = _("An unknown exception occurred.") + + def __init__(self, **kwargs): + try: + self._error_string = self.message % kwargs + except Exception: + # at least get the core message out if something happened + self._error_string = self.message + + def __str__(self): + return self._error_string + + +class UnAuthorizedRequest(NsxApiException): + message = _("Server denied session's authentication credentials.") + + +class ResourceNotFound(NsxApiException): + message = _("An entity referenced in the request was not found.") + + +class Conflict(NsxApiException): + message = _("Request conflicts with configuration on a different " + "entity.") + + +class ServiceUnavailable(NsxApiException): + message = _("Request could not completed because the associated " + "resource could not be reached.") + + +class Forbidden(NsxApiException): + message = _("The request is forbidden from accessing the " + "referenced resource.") + + +class ReadOnlyMode(Forbidden): + message = _("Create/Update actions are forbidden when in read-only mode.") + + +class RequestTimeout(NsxApiException): + message = _("The request has timed out.") + + +def fourZeroFour(response=None): + raise ResourceNotFound() + + +def fourZeroNine(response=None): + raise Conflict() + + +def fiveZeroThree(response=None): + raise ServiceUnavailable() + + +def fourZeroThree(response=None): + if 'read-only' in response.body: + raise ReadOnlyMode() + else: + raise Forbidden() + + +def zero(self, response=None): + raise NsxApiException() + + +ERROR_MAPPINGS = { + 404: fourZeroFour, + 405: zero, + 409: fourZeroNine, + 503: fiveZeroThree, + 403: fourZeroThree, + 301: zero, + 307: zero, + 400: zero, + 500: zero, + 501: zero, + 503: zero +} diff --git a/neutron/plugins/nicira/api_client/request.py b/neutron/plugins/nicira/api_client/request.py index 9f23666fe..68878c58e 100644 --- a/neutron/plugins/nicira/api_client/request.py +++ b/neutron/plugins/nicira/api_client/request.py @@ -1,6 +1,5 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nicira, Inc. +# Copyright 2012 VMware, Inc. +# # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -15,41 +14,34 @@ # License for the specific language governing permissions and limitations # under the License. # -# @author: Aaron Rosen, Nicira Networks, Inc. - from abc import ABCMeta from abc import abstractmethod import copy import eventlet import httplib -import logging import time import six import six.moves.urllib.parse as urlparse from neutron.openstack.common import excutils -from neutron.plugins.nicira.api_client.common import ( - _conn_str) - +from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import ctrl_conn_to_str -logging.basicConfig(level=logging.INFO) LOG = logging.getLogger(__name__) -# Default parameters. DEFAULT_REQUEST_TIMEOUT = 30 DEFAULT_HTTP_TIMEOUT = 10 DEFAULT_RETRIES = 2 DEFAULT_REDIRECTS = 2 DEFAULT_API_REQUEST_POOL_SIZE = 1000 DEFAULT_MAXIMUM_REQUEST_ID = 4294967295 -DOWNLOAD_TIMEOUT = 180 # The UI code has a coorespoind 190 sec timeout - # for downloads, see: django/nvp_console/views.py +DOWNLOAD_TIMEOUT = 180 @six.add_metaclass(ABCMeta) -class NvpApiRequest(object): +class ApiRequest(object): '''An abstract baseclass for all ApiRequest implementations. This defines the interface and property structure for both eventlet and @@ -119,7 +111,7 @@ class NvpApiRequest(object): if cookie: headers["Cookie"] = cookie - gen = self._api_client.nvp_config_gen + gen = self._api_client.config_gen if gen: headers["X-Nvp-Wait-For-Config-Generation"] = gen LOG.debug(_("Setting X-Nvp-Wait-For-Config-Generation " @@ -147,9 +139,9 @@ class NvpApiRequest(object): if new_gen: LOG.debug(_("Reading X-Nvp-config-Generation response " "header: '%s'"), new_gen) - if (self._api_client.nvp_config_gen is None or - self._api_client.nvp_config_gen < int(new_gen)): - self._api_client.nvp_config_gen = int(new_gen) + if (self._api_client.config_gen is None or + self._api_client.config_gen < int(new_gen)): + self._api_client.config_gen = int(new_gen) if response.status == httplib.UNAUTHORIZED: @@ -292,4 +284,4 @@ class NvpApiRequest(object): def _request_str(self, conn, url): '''Return string representation of connection.''' - return "%s %s/%s" % (self._method, _conn_str(conn), url) + return "%s %s/%s" % (self._method, ctrl_conn_to_str(conn), url) diff --git a/neutron/plugins/nicira/api_client/version.py b/neutron/plugins/nicira/api_client/version.py new file mode 100644 index 000000000..52fcd74b4 --- /dev/null +++ b/neutron/plugins/nicira/api_client/version.py @@ -0,0 +1,43 @@ +# Copyright 2012 VMware, Inc. +# +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from neutron.openstack.common import log as logging + +LOG = logging.getLogger(__name__) + + +def find_version(headers): + """Retrieve NSX controller version from response headers.""" + for (header_name, header_value) in (headers or ()): + try: + if header_name == 'server': + return Version(header_value.split('/')[1]) + except IndexError: + LOG.warning(_("Unable to fetch NSX version from response " + "headers :%s"), headers) + + +class Version(object): + """Abstracts NSX version by exposing major and minor.""" + + def __init__(self, version): + self.full_version = version.split('.') + self.major = int(self.full_version[0]) + self.minor = int(self.full_version[1]) + + def __str__(self): + return '.'.join(self.full_version) diff --git a/neutron/plugins/nicira/common/nsx_utils.py b/neutron/plugins/nicira/common/nsx_utils.py index 0e42cd9f3..054bd3a4b 100644 --- a/neutron/plugins/nicira/common/nsx_utils.py +++ b/neutron/plugins/nicira/common/nsx_utils.py @@ -16,11 +16,11 @@ # under the License. from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import client from neutron.plugins.nicira.dbexts import db as nsx_db from neutron.plugins.nicira import nsx_cluster from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient LOG = log.getLogger(__name__) @@ -125,7 +125,7 @@ def get_nsx_switch_and_port_id(session, cluster, neutron_port_id): return nsx_switch_id, nsx_port_id -def create_nsx_cluster(cluster_opts, concurrent_connections, nsx_gen_timeout): +def create_nsx_cluster(cluster_opts, concurrent_connections, gen_timeout): cluster = nsx_cluster.NSXCluster(**cluster_opts) def _ctrl_split(x, y): @@ -133,14 +133,14 @@ def create_nsx_cluster(cluster_opts, concurrent_connections, nsx_gen_timeout): api_providers = [_ctrl_split(*ctrl.split(':')) for ctrl in cluster.nsx_controllers] - cluster.api_client = NvpApiClient.NVPApiHelper( + cluster.api_client = client.NsxApiClient( api_providers, cluster.nsx_user, cluster.nsx_password, + concurrent_connections=concurrent_connections, + gen_timeout=gen_timeout, request_timeout=cluster.req_timeout, http_timeout=cluster.http_timeout, retries=cluster.retries, - redirects=cluster.redirects, - concurrent_connections=concurrent_connections, - nvp_gen_timeout=nsx_gen_timeout) + redirects=cluster.redirects) return cluster diff --git a/neutron/plugins/nicira/common/sync.py b/neutron/plugins/nicira/common/sync.py index b208c6c60..f6e0c3f5a 100644 --- a/neutron/plugins/nicira/common/sync.py +++ b/neutron/plugins/nicira/common/sync.py @@ -25,11 +25,11 @@ from neutron.openstack.common import jsonutils from neutron.openstack.common import log from neutron.openstack.common import loopingcall from neutron.openstack.common import timeutils +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import nsx_utils from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira import nvplib # Maximum page size for a single request @@ -261,7 +261,7 @@ class NvpSynchronizer(): neutron_network_data['id']) except exceptions.NetworkNotFound: # TODO(salv-orlando): We should be catching - # NvpApiClient.ResourceNotFound here + # api_exc.ResourceNotFound here # The logical switch was not found LOG.warning(_("Logical switch for neutron network %s not " "found on NVP."), neutron_network_data['id']) @@ -329,7 +329,7 @@ class NvpSynchronizer(): self._cluster, nsx_router_id) except exceptions.NotFound: # NOTE(salv-orlando): We should be catching - # NvpApiClient.ResourceNotFound here + # api_exc.ResourceNotFound here # The logical router was not found LOG.warning(_("Logical router for neutron router %s not " "found on NVP."), neutron_router_data['id']) @@ -405,7 +405,7 @@ class NvpSynchronizer(): relations='LogicalPortStatus') except (exceptions.PortNotFoundOnNetwork): # NOTE(salv-orlando): We should be catching - # NvpApiClient.ResourceNotFound here instead + # api_exc.ResourceNotFound here instead # of PortNotFoundOnNetwork when the id exists but # the logical switch port was not found LOG.warning(_("Logical switch port for neutron port %s " @@ -563,7 +563,7 @@ class NvpSynchronizer(): try: (lswitches, lrouters, lswitchports) = ( self._fetch_nvp_data_chunk(sp)) - except (NvpApiClient.RequestTimeout, NvpApiClient.NvpApiException): + except (api_exc.RequestTimeout, api_exc.NsxApiException): sleep_interval = self._sync_backoff # Cap max back off to 64 seconds self._sync_backoff = min(self._sync_backoff * 2, 64) diff --git a/neutron/plugins/nicira/dhcp_meta/lsnmanager.py b/neutron/plugins/nicira/dhcp_meta/lsnmanager.py index 02dd81a5d..b971b6b40 100644 --- a/neutron/plugins/nicira/dhcp_meta/lsnmanager.py +++ b/neutron/plugins/nicira/dhcp_meta/lsnmanager.py @@ -20,12 +20,12 @@ from oslo.config import cfg from neutron.common import exceptions as n_exc from neutron.openstack.common.db import exception as db_exc from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as p_exc from neutron.plugins.nicira.dbexts import lsn_db from neutron.plugins.nicira.dhcp_meta import constants as const from neutron.plugins.nicira.nsxlib import lsn as lsn_api from neutron.plugins.nicira.nsxlib import switch as switch_api -from neutron.plugins.nicira import nvplib as nsxlib LOG = logging.getLogger(__name__) @@ -64,7 +64,7 @@ class LsnManager(object): """Retrieve the LSN id associated to the network.""" try: return lsn_api.lsn_for_network_get(self.cluster, network_id) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): logger = raise_on_err and LOG.error or LOG.warn logger(_('Unable to find Logical Service Node for ' 'network %s'), network_id) @@ -76,7 +76,7 @@ class LsnManager(object): """Create a LSN associated to the network.""" try: return lsn_api.lsn_for_network_create(self.cluster, network_id) - except nsxlib.NvpApiClient.NvpApiException: + except api_exc.NsxApiException: err_msg = _('Unable to create LSN for network %s') % network_id raise p_exc.NvpPluginException(err_msg=err_msg) @@ -84,7 +84,7 @@ class LsnManager(object): """Delete a LSN given its id.""" try: lsn_api.lsn_delete(self.cluster, lsn_id) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): LOG.warn(_('Unable to delete Logical Service Node %s'), lsn_id) def lsn_delete_by_network(self, context, network_id): @@ -100,7 +100,7 @@ class LsnManager(object): try: lsn_port_id = lsn_api.lsn_port_by_subnet_get( self.cluster, lsn_id, subnet_id) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): logger = raise_on_err and LOG.error or LOG.warn logger(_('Unable to find Logical Service Node Port for ' 'LSN %(lsn_id)s and subnet %(subnet_id)s') @@ -122,7 +122,7 @@ class LsnManager(object): try: lsn_port_id = lsn_api.lsn_port_by_mac_get( self.cluster, lsn_id, mac) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): logger = raise_on_err and LOG.error or LOG.warn logger(_('Unable to find Logical Service Node Port for ' 'LSN %(lsn_id)s and mac address %(mac)s') @@ -143,7 +143,7 @@ class LsnManager(object): return lsn_api.lsn_port_create(self.cluster, lsn_id, subnet_info) except n_exc.NotFound: raise p_exc.LsnNotFound(entity='', entity_id=lsn_id) - except nsxlib.NvpApiClient.NvpApiException: + except api_exc.NsxApiException: err_msg = _('Unable to create port for LSN %s') % lsn_id raise p_exc.NvpPluginException(err_msg=err_msg) @@ -151,7 +151,7 @@ class LsnManager(object): """Delete a LSN port from the Logical Service Node.""" try: lsn_api.lsn_port_delete(self.cluster, lsn_id, lsn_port_id) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): LOG.warn(_('Unable to delete LSN Port %s'), lsn_port_id) def lsn_port_dispose(self, context, network_id, mac_address): @@ -168,7 +168,7 @@ class LsnManager(object): switch_api.delete_port( self.cluster, network_id, lswitch_port_id) except (n_exc.PortNotFoundOnNetwork, - switch_api.NvpApiClient.NvpApiException): + api_exc.NsxApiException): LOG.warn(_("Metadata port not found while attempting " "to delete it from network %s"), network_id) else: @@ -218,7 +218,7 @@ class LsnManager(object): const.METADATA_DEVICE_ID, True)['uuid'] lsn_port_id = self.lsn_port_create(self.cluster, lsn_id, data) except (n_exc.NotFound, p_exc.NvpPluginException, - nsxlib.NvpApiClient.NvpApiException): + api_exc.NsxApiException): raise p_exc.PortConfigurationError( net_id=network_id, lsn_id=lsn_id, port_id=lswitch_port_id) else: @@ -252,7 +252,7 @@ class LsnManager(object): try: lsn_api.lsn_port_dhcp_configure( self.cluster, lsn_id, lsn_port_id, is_enabled, dhcp_options) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): err_msg = (_('Unable to configure dhcp for Logical Service ' 'Node %(lsn_id)s and port %(lsn_port_id)s') % {'lsn_id': lsn_id, 'lsn_port_id': lsn_port_id}) @@ -273,7 +273,7 @@ class LsnManager(object): lsn_id = self.lsn_get(context, network_id) lsn_api.lsn_metadata_configure( self.cluster, lsn_id, is_enabled, metadata_options) - except (p_exc.LsnNotFound, nsxlib.NvpApiClient.NvpApiException): + except (p_exc.LsnNotFound, api_exc.NsxApiException): err_msg = (_('Unable to configure metadata ' 'for subnet %s') % subnet_id) LOG.error(err_msg) @@ -296,7 +296,7 @@ class LsnManager(object): lsn_id, lsn_port_id = self.lsn_port_get( context, network_id, subnet_id) hdlr(self.cluster, lsn_id, lsn_port_id, data) - except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): + except (n_exc.NotFound, api_exc.NsxApiException): LOG.error(_('Error while configuring LSN ' 'port %s'), lsn_port_id) raise p_exc.PortConfigurationError( @@ -336,7 +336,7 @@ class LsnManager(object): if meta and lsn_id and lsn_port_id: lsn_api.lsn_port_host_entries_update( self.cluster, lsn_id, lsn_port_id, META_CONF, meta) - except nsxlib.NvpApiClient.NvpApiException: + except api_exc.NsxApiException: raise p_exc.PortConfigurationError( net_id=network_id, lsn_id=lsn_id, port_id=lsn_port_id) diff --git a/neutron/plugins/nicira/dhcp_meta/nsx.py b/neutron/plugins/nicira/dhcp_meta/nsx.py index f12671493..30add73c1 100644 --- a/neutron/plugins/nicira/dhcp_meta/nsx.py +++ b/neutron/plugins/nicira/dhcp_meta/nsx.py @@ -190,7 +190,7 @@ def is_user_port(p, check_dev_id=False): def check_services_requirements(cluster): - ver = cluster.api_client.get_nvp_version() + ver = cluster.api_client.get_version() # It sounds like 4.1 is the first one where DHCP in NSX # will have the experimental feature if ver.major >= 4 and ver.minor >= 1: diff --git a/neutron/plugins/nicira/dhcp_meta/rpc.py b/neutron/plugins/nicira/dhcp_meta/rpc.py index 1651797f5..ada4ef755 100644 --- a/neutron/plugins/nicira/dhcp_meta/rpc.py +++ b/neutron/plugins/nicira/dhcp_meta/rpc.py @@ -31,9 +31,9 @@ from neutron.db import dhcp_rpc_base from neutron.db import l3_db from neutron.db import models_v2 from neutron.openstack.common import log as logging +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import config from neutron.plugins.nicira.common import exceptions as nvp_exc -from neutron.plugins.nicira import NvpApiClient LOG = logging.getLogger(__name__) @@ -136,7 +136,7 @@ def handle_router_metadata_access(plugin, context, router_id, interface=None): # TODO(salvatore-orlando): A better exception handling in the # NSX plugin would allow us to improve error handling here except (ntn_exc.NeutronException, nvp_exc.NvpPluginException, - NvpApiClient.NvpApiException): + api_exc.NsxApiException): # Any exception here should be regarded as non-fatal LOG.exception(_("An error occurred while operating on the " "metadata access network for router:'%s'"), @@ -189,7 +189,7 @@ def _create_metadata_access_network(plugin, context, router_id): greenthread.sleep(0) # yield except (ntn_exc.NeutronException, nvp_exc.NvpPluginException, - NvpApiClient.NvpApiException): + api_exc.NsxApiException): # It is not necessary to explicitly delete the subnet # as it will be removed with the network plugin.delete_network(context, meta_net['id']) @@ -215,7 +215,7 @@ def _destroy_metadata_access_network(plugin, context, router_id, ports): plugin.delete_network(context, meta_net_id) greenthread.sleep(0) # yield except (ntn_exc.NeutronException, nvp_exc.NvpPluginException, - NvpApiClient.NvpApiException): + api_exc.NsxApiException): # must re-add the router interface plugin.add_router_interface(context, router_id, {'subnet_id': meta_sub_id}) diff --git a/neutron/plugins/nicira/nsxlib/lsn.py b/neutron/plugins/nicira/nsxlib/lsn.py index ed291e5dc..3d88fd5b5 100644 --- a/neutron/plugins/nicira/nsxlib/lsn.py +++ b/neutron/plugins/nicira/nsxlib/lsn.py @@ -19,9 +19,9 @@ import json from neutron.common import exceptions as exception from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import utils -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira.nvplib import _build_uri_path from neutron.plugins.nicira.nvplib import do_request @@ -167,7 +167,7 @@ def lsn_port_plug_network(cluster, lsn_id, lsn_port_id, lswitch_port_id): is_attachment=True), json.dumps(patch_obj), cluster=cluster) - except NvpApiClient.Conflict: + except api_exc.Conflict: # This restriction might be lifted at some point msg = (_("Attempt to plug Logical Services Node %(lsn)s into " "network with port %(port)s failed. PatchAttachment " diff --git a/neutron/plugins/nicira/nsxlib/queue.py b/neutron/plugins/nicira/nsxlib/queue.py index 00e0aa427..a2d71c717 100644 --- a/neutron/plugins/nicira/nsxlib/queue.py +++ b/neutron/plugins/nicira/nsxlib/queue.py @@ -18,8 +18,8 @@ from neutron.common import exceptions as exception from neutron.openstack.common import excutils from neutron.openstack.common import jsonutils from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import utils -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira.nvplib import _build_uri_path from neutron.plugins.nicira.nvplib import do_request @@ -54,7 +54,7 @@ def create_lqueue(cluster, queue_data): _build_uri_path(LQUEUE_RESOURCE), jsonutils.dumps(queue_obj), cluster=cluster)['uuid'] - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: # FIXME(salv-orlando): This should not raise NeutronException with excutils.save_and_reraise_exception(): raise exception.NeutronException() diff --git a/neutron/plugins/nicira/nsxlib/router.py b/neutron/plugins/nicira/nsxlib/router.py index 97b9adc5a..c7cd796fd 100644 --- a/neutron/plugins/nicira/nsxlib/router.py +++ b/neutron/plugins/nicira/nsxlib/router.py @@ -17,12 +17,12 @@ from neutron.common import exceptions as exception from neutron.openstack.common import excutils from neutron.openstack.common import jsonutils from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import utils from neutron.plugins.nicira.nsxlib.switch import get_port from neutron.plugins.nicira.nsxlib.versioning import DEFAULT_VERSION from neutron.plugins.nicira.nsxlib.versioning import versioned -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira.nvplib import _build_uri_path from neutron.plugins.nicira.nvplib import do_request from neutron.plugins.nicira.nvplib import get_all_query_pages @@ -90,7 +90,7 @@ def create_implicit_routing_lrouter(cluster, neutron_router_id, tenant_id, the logical router is being created :param display_name: Descriptive name of this logical router :param nexthop: External gateway IP address for the logical router - :raise NvpApiException: if there is a problem while communicating + :raise NsxApiException: if there is a problem while communicating with the NSX controller """ return _create_implicit_routing_lrouter( @@ -109,7 +109,7 @@ def create_implicit_routing_lrouter_with_distribution( :param display_name: Descriptive name of this logical router :param nexthop: External gateway IP address for the logical router :param distributed: True for distributed logical routers - :raise NvpApiException: if there is a problem while communicating + :raise NsxApiException: if there is a problem while communicating with the NSX controller """ return _create_implicit_routing_lrouter( @@ -243,7 +243,7 @@ def update_explicit_routes_lrouter(cluster, router_id, routes): uuid = create_explicit_route_lrouter(cluster, router_id, route) added_routes.append(uuid) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: LOG.exception(_('Cannot update NSX routes %(routes)s for ' 'router %(router_id)s'), {'routes': routes, 'router_id': router_id}) @@ -598,7 +598,7 @@ def update_lrouter_port_ips(cluster, lrouter_id, lport_id, "%(lrouter_id)s") % data) LOG.exception(msg) raise nvp_exc.NvpPluginException(err_msg=msg) - except NvpApiClient.NvpApiException as e: + except api_exc.NsxApiException as e: msg = _("An exception occurred while updating IP addresses on a " "router logical port:%s") % str(e) LOG.exception(msg) @@ -636,7 +636,7 @@ ROUTER_FUNC_DICT = { @versioned(ROUTER_FUNC_DICT) def create_lrouter(cluster, *args, **kwargs): if kwargs.get('distributed', None): - v = cluster.api_client.get_nvp_version() + v = cluster.api_client.get_version() if (v.major, v.minor) < (3, 1): raise nvp_exc.NvpInvalidVersion(version=v) return v @@ -650,7 +650,7 @@ def get_default_route_explicit_routing_lrouter(cluster, *args, **kwargs): @versioned(ROUTER_FUNC_DICT) def update_lrouter(cluster, *args, **kwargs): if kwargs.get('routes', None): - v = cluster.api_client.get_nvp_version() + v = cluster.api_client.get_version() if (v.major, v.minor) < (3, 2): raise nvp_exc.NvpInvalidVersion(version=v) return v diff --git a/neutron/plugins/nicira/nsxlib/switch.py b/neutron/plugins/nicira/nsxlib/switch.py index 3a0e17988..7b6f7005e 100644 --- a/neutron/plugins/nicira/nsxlib/switch.py +++ b/neutron/plugins/nicira/nsxlib/switch.py @@ -19,9 +19,9 @@ import json from neutron.common import constants from neutron.common import exceptions as exception from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nvp_exc from neutron.plugins.nicira.common import utils -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira.nvplib import _build_uri_path from neutron.plugins.nicira.nvplib import do_request from neutron.plugins.nicira.nvplib import get_all_query_pages @@ -180,7 +180,7 @@ def delete_port(cluster, switch, port): LOG.exception(_("Port or Network not found")) raise exception.PortNotFoundOnNetwork( net_id=switch, port_id=port) - except NvpApiClient.NvpApiException: + except api_exc.NsxApiException: raise exception.NeutronException() diff --git a/neutron/plugins/nicira/nsxlib/versioning.py b/neutron/plugins/nicira/nsxlib/versioning.py index dfa4cb6b0..055226b37 100644 --- a/neutron/plugins/nicira/nsxlib/versioning.py +++ b/neutron/plugins/nicira/nsxlib/versioning.py @@ -15,7 +15,7 @@ import inspect -from neutron.plugins.nicira import NvpApiClient +from neutron.plugins.nicira.api_client import exception DEFAULT_VERSION = -1 @@ -30,7 +30,7 @@ def versioned(func_table): # run validation checks regarding versions. It # should return the NVP version v = (wrapped_func(cluster, *args, **kwargs) or - cluster.api_client.get_nvp_version()) + cluster.api_client.get_version()) func = get_function_by_version(func_table, func_name, v) func_kwargs = kwargs arg_spec = inspect.getargspec(func) @@ -63,4 +63,4 @@ def get_function_by_version(func_table, func_name, ver): else: msg = _('NSX version is not set. Unable to complete request ' 'correctly. Check log for NSX communication errors.') - raise NvpApiClient.ServiceUnavailable(message=msg) + raise exception.ServiceUnavailable(message=msg) diff --git a/neutron/plugins/nicira/nvplib.py b/neutron/plugins/nicira/nvplib.py index 1ba4cd43d..857d2e9c3 100644 --- a/neutron/plugins/nicira/nvplib.py +++ b/neutron/plugins/nicira/nvplib.py @@ -25,8 +25,8 @@ import json from neutron.common import exceptions as exception from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nvp_exc -from neutron.plugins.nicira import NvpApiClient LOG = log.getLogger(__name__) @@ -142,7 +142,7 @@ def do_request(*args, **kwargs): res = cluster.api_client.request(*args) if res: return json.loads(res) - except NvpApiClient.ResourceNotFound: + except api_exc.ResourceNotFound: raise exception.NotFound() - except NvpApiClient.ReadOnlyMode: + except api_exc.ReadOnlyMode: raise nvp_exc.MaintenanceInProgress() diff --git a/neutron/tests/unit/vmware/__init__.py b/neutron/tests/unit/vmware/__init__.py index 1abde0032..2c8b3fd9a 100644 --- a/neutron/tests/unit/vmware/__init__.py +++ b/neutron/tests/unit/vmware/__init__.py @@ -1,6 +1,5 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - # Copyright 2013 OpenStack Foundation. +# # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -17,31 +16,32 @@ import os -import neutron.plugins.nicira.api_client.client_eventlet as client +from neutron.plugins.nicira.api_client import client as nsx_client +from neutron.plugins.nicira.api_client import eventlet_client from neutron.plugins.nicira import extensions -import neutron.plugins.nicira.NvpApiClient as nsxapi from neutron.plugins.nicira import nvplib from neutron.plugins.nicira.vshield.common import VcnsApiClient as vcnsapi from neutron.plugins.nicira.vshield import vcns import neutron.plugins.nicira.vshield.vcns_driver as vcnsdriver import neutron.plugins.vmware.plugin as neutron_plugin + plugin = neutron_plugin.NsxPlugin service_plugin = neutron_plugin.NsxServicePlugin -api_helper = nsxapi.NVPApiHelper -api_client = client.NvpApiClientEventlet +api_client = nsx_client.NsxApiClient +evt_client = eventlet_client.EventletApiClient vcns_class = vcns.Vcns vcns_driver = vcnsdriver.VcnsDriver vcns_api_helper = vcnsapi.VcnsApiHelper STUBS_PATH = os.path.join(os.path.dirname(__file__), 'etc') NSXEXT_PATH = os.path.dirname(extensions.__file__) -NSXAPI_NAME = '%s.%s' % (api_helper.__module__, api_helper.__name__) +NSXAPI_NAME = '%s.%s' % (api_client.__module__, api_client.__name__) NSXLIB_NAME = nvplib.__name__ PLUGIN_NAME = '%s.%s' % (plugin.__module__, plugin.__name__) SERVICE_PLUGIN_NAME = '%s.%s' % (service_plugin.__module__, service_plugin.__name__) -CLIENT_NAME = '%s.%s' % (api_client.__module__, api_client.__name__) +CLIENT_NAME = '%s.%s' % (evt_client.__module__, evt_client.__name__) VCNS_NAME = '%s.%s' % (vcns_class.__module__, vcns_class.__name__) VCNS_DRIVER_NAME = '%s.%s' % (vcns_driver.__module__, vcns_driver.__name__) VCNSAPI_NAME = '%s.%s' % (vcns_api_helper.__module__, vcns_api_helper.__name__) diff --git a/neutron/tests/unit/vmware/apiclient/fake.py b/neutron/tests/unit/vmware/apiclient/fake.py index 84ebdc7c7..ce7cb316b 100644 --- a/neutron/tests/unit/vmware/apiclient/fake.py +++ b/neutron/tests/unit/vmware/apiclient/fake.py @@ -20,7 +20,7 @@ import six.moves.urllib.parse as urlparse from neutron.openstack.common import log as logging from neutron.openstack.common import uuidutils -from neutron.plugins.nicira import NvpApiClient as api_client +from neutron.plugins.nicira.api_client import exception as api_exc LOG = logging.getLogger(__name__) @@ -257,7 +257,7 @@ class FakeClient: try: fake_lrouter = self._fake_lrouter_dict[lr_uuid] except KeyError: - raise api_client.ResourceNotFound() + raise api_exc.ResourceNotFound() fake_lrouter['lport_count'] += 1 fake_lport_status = fake_lport.copy() fake_lport_status['lr_tenant_id'] = fake_lrouter['tenant_id'] @@ -496,7 +496,7 @@ class FakeClient: for res_uuid in res_dict if res_uuid == target_uuid] if items: return json.dumps(items[0]) - raise api_client.ResourceNotFound() + raise api_exc.ResourceNotFound() def handle_get(self, url): #TODO(salvatore-orlando): handle field selection @@ -505,7 +505,7 @@ class FakeClient: relations = urlparse.parse_qs(parsedurl.query).get('relations') response_file = self.FAKE_GET_RESPONSES.get(res_type) if not response_file: - raise api_client.NvpApiException() + raise api_exc.NsxApiException() if 'lport' in res_type or 'nat' in res_type: if len(uuids) > 1: return self._show(res_type, response_file, uuids[0], @@ -569,7 +569,7 @@ class FakeClient: try: resource = res_dict[uuids[-1]] except KeyError: - raise api_client.ResourceNotFound() + raise api_exc.ResourceNotFound() if not is_attachment: edit_resource = getattr(self, '_build_%s' % res_type, None) if edit_resource: @@ -640,7 +640,7 @@ class FakeClient: try: del res_dict[uuids[-1]] except KeyError: - raise api_client.ResourceNotFound() + raise api_exc.ResourceNotFound() return "" def fake_request(self, *args, **kwargs): diff --git a/neutron/tests/unit/vmware/apiclient/test_api_common.py b/neutron/tests/unit/vmware/apiclient/test_api_common.py index d15e419d7..0d03d120a 100644 --- a/neutron/tests/unit/vmware/apiclient/test_api_common.py +++ b/neutron/tests/unit/vmware/apiclient/test_api_common.py @@ -1,6 +1,5 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - # Copyright 2011 VMware, Inc. +# # All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -17,20 +16,20 @@ import httplib -import neutron.plugins.nicira.api_client.common as naco +from neutron.plugins.nicira.api_client import ctrl_conn_to_str from neutron.tests import base class ApiCommonTest(base.BaseTestCase): - def test_conn_str(self): + def test_ctrl_conn_to_str(self): conn = httplib.HTTPSConnection('localhost', 4242, timeout=0) self.assertTrue( - naco._conn_str(conn) == 'https://localhost:4242') + ctrl_conn_to_str(conn) == 'https://localhost:4242') conn = httplib.HTTPConnection('localhost', 4242, timeout=0) self.assertTrue( - naco._conn_str(conn) == 'http://localhost:4242') + ctrl_conn_to_str(conn) == 'http://localhost:4242') - self.assertRaises(TypeError, naco._conn_str, + self.assertRaises(TypeError, ctrl_conn_to_str, ('not an httplib.HTTPSConnection')) diff --git a/neutron/tests/unit/vmware/apiclient/test_api_request_eventlet.py b/neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py similarity index 92% rename from neutron/tests/unit/vmware/apiclient/test_api_request_eventlet.py rename to neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py index 6bbe06251..f0c6f9e42 100644 --- a/neutron/tests/unit/vmware/apiclient/test_api_request_eventlet.py +++ b/neutron/tests/unit/vmware/apiclient/test_api_eventlet_request.py @@ -24,8 +24,8 @@ from eventlet.green import urllib2 from mock import Mock from mock import patch -from neutron.plugins.nicira.api_client import client_eventlet as nace -from neutron.plugins.nicira.api_client import request_eventlet as nare +from neutron.plugins.nicira.api_client import eventlet_client as client +from neutron.plugins.nicira.api_client import eventlet_request as request from neutron.tests import base from neutron.tests.unit.vmware import CLIENT_NAME @@ -46,10 +46,10 @@ class ApiRequestEventletTest(base.BaseTestCase): def setUp(self): super(ApiRequestEventletTest, self).setUp() - self.client = nace.NvpApiClientEventlet( + self.client = client.EventletApiClient( [("127.0.0.1", 4401, True)], "admin", "admin") self.url = "/ws.v1/_debug" - self.req = nare.NvpApiRequestEventlet(self.client, self.url) + self.req = request.EventletApiRequest(self.client, self.url) def tearDown(self): self.client = None @@ -57,7 +57,7 @@ class ApiRequestEventletTest(base.BaseTestCase): super(ApiRequestEventletTest, self).tearDown() def test_construct_eventlet_api_request(self): - e = nare.NvpApiRequestEventlet(self.client, self.url) + e = request.EventletApiRequest(self.client, self.url) self.assertIsNotNone(e) def test_apirequest_spawn(self): @@ -66,18 +66,18 @@ class ApiRequestEventletTest(base.BaseTestCase): LOG.info('spawned: %d' % id) for i in range(10): - nare.NvpApiRequestEventlet._spawn(x, i) + request.EventletApiRequest._spawn(x, i) def test_apirequest_start(self): for i in range(10): - a = nare.NvpApiRequestEventlet( + a = request.EventletApiRequest( self.client, self.url, request_timeout=0.1) a._handle_request = Mock() a.start() eventlet.greenthread.sleep(0.1) logging.info('_handle_request called: %s' % a._handle_request.called) - nare.NvpApiRequestEventlet.joinall() + request.EventletApiRequest.joinall() def test_join_with_handle_request(self): self.req._handle_request = Mock() @@ -116,7 +116,7 @@ class ApiRequestEventletTest(base.BaseTestCase): self.req._request_timeout = REQUEST_TIMEOUT self.req._handle_request = new.instancemethod( - my_handle_request, self.req, nare.NvpApiRequestEventlet) + my_handle_request, self.req, request.EventletApiRequest) self.req.start() self.assertIsNone(self.req.join()) @@ -290,13 +290,12 @@ class ApiRequestEventletTest(base.BaseTestCase): self.req.spawn = Mock(return_value=mywaiter) self.req._handle_request() - # NvpLoginRequestEventlet tests. def test_construct_eventlet_login_request(self): - r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password') + r = request.LoginRequestEventlet(self.client, 'user', 'password') self.assertIsNotNone(r) def test_session_cookie_session_cookie_retrieval(self): - r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password') + r = request.LoginRequestEventlet(self.client, 'user', 'password') r.successful = Mock() r.successful.return_value = True r.value = Mock() @@ -305,7 +304,7 @@ class ApiRequestEventletTest(base.BaseTestCase): self.assertIsNotNone(r.session_cookie()) def test_session_cookie_not_retrieved(self): - r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password') + r = request.LoginRequestEventlet(self.client, 'user', 'password') r.successful = Mock() r.successful.return_value = False r.value = Mock() @@ -313,18 +312,17 @@ class ApiRequestEventletTest(base.BaseTestCase): r.value.get_header.return_value = 'cool' self.assertIsNone(r.session_cookie()) - # NvpGetApiProvidersRequestEventlet tests. def test_construct_eventlet_get_api_providers_request(self): - r = nare.NvpGetApiProvidersRequestEventlet(self.client) + r = request.GetApiProvidersRequestEventlet(self.client) self.assertIsNotNone(r) def test_api_providers_none_api_providers(self): - r = nare.NvpGetApiProvidersRequestEventlet(self.client) + r = request.GetApiProvidersRequestEventlet(self.client) r.successful = Mock(return_value=False) self.assertIsNone(r.api_providers()) def test_api_providers_non_none_api_providers(self): - r = nare.NvpGetApiProvidersRequestEventlet(self.client) + r = request.GetApiProvidersRequestEventlet(self.client) r.value = Mock() r.value.body = """{ "results": [ diff --git a/neutron/tests/unit/vmware/extensions/test_maclearning.py b/neutron/tests/unit/vmware/extensions/test_maclearning.py index 781ad6167..d664bf3f0 100644 --- a/neutron/tests/unit/vmware/extensions/test_maclearning.py +++ b/neutron/tests/unit/vmware/extensions/test_maclearning.py @@ -24,8 +24,8 @@ from neutron.api.v2 import attributes from neutron.common.test_lib import test_config from neutron import context from neutron.extensions import agent +from neutron.plugins.nicira.api_client.version import Version from neutron.plugins.nicira.common import sync -from neutron.plugins.nicira.NvpApiClient import NVPVersion from neutron.tests.unit import test_db_plugin from neutron.tests.unit.vmware.apiclient import fake from neutron.tests.unit.vmware import get_fake_conf @@ -74,7 +74,7 @@ class MacLearningDBTestCase(test_db_plugin.NeutronDbPluginV2TestCase): patch_sync.start() # Emulate tests against NSX 2.x - instance.return_value.get_nvp_version.return_value = NVPVersion("3.0") + instance.return_value.get_version.return_value = Version("3.0") instance.return_value.request.side_effect = self.fc.fake_request cfg.CONF.set_override('metadata_mode', None, 'NSX') self.addCleanup(self.fc.reset_all) diff --git a/neutron/tests/unit/vmware/extensions/test_networkgw.py b/neutron/tests/unit/vmware/extensions/test_networkgw.py index b61b3949f..76e143b2a 100644 --- a/neutron/tests/unit/vmware/extensions/test_networkgw.py +++ b/neutron/tests/unit/vmware/extensions/test_networkgw.py @@ -28,10 +28,10 @@ from neutron.db import api as db_api from neutron.db import db_base_plugin_v2 from neutron import manager from neutron.openstack.common import uuidutils +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.dbexts import networkgw_db from neutron.plugins.nicira.extensions import networkgw from neutron.plugins.nicira import nsxlib -from neutron.plugins.nicira import NvpApiClient from neutron import quota from neutron.tests import base from neutron.tests.unit import test_api_v2 @@ -647,7 +647,7 @@ class TestNetworkGateway(NsxPluginV2TestCase, def test_create_network_gateway_nsx_error_returns_500(self): def raise_nsx_api_exc(*args, **kwargs): - raise NvpApiClient.NvpApiException + raise api_exc.NsxApiException with mock.patch.object(nsxlib.l2gateway, 'create_l2_gw_service', @@ -660,7 +660,7 @@ class TestNetworkGateway(NsxPluginV2TestCase, def test_create_network_gateway_nsx_error_returns_409(self): with mock.patch.object(nsxlib.l2gateway, 'create_l2_gw_service', - side_effect=NvpApiClient.Conflict): + side_effect=api_exc.Conflict): res = self._create_network_gateway( self.fmt, 'xxx', name='yyy', devices=[{'id': uuidutils.generate_uuid()}]) diff --git a/neutron/tests/unit/vmware/nsxlib/base.py b/neutron/tests/unit/vmware/nsxlib/base.py index 64143adb4..7956c897d 100644 --- a/neutron/tests/unit/vmware/nsxlib/base.py +++ b/neutron/tests/unit/vmware/nsxlib/base.py @@ -18,9 +18,11 @@ import mock +from neutron.plugins.nicira.api_client import client +from neutron.plugins.nicira.api_client import exception +from neutron.plugins.nicira.api_client import version from neutron.plugins.nicira.common import config # noqa from neutron.plugins.nicira import nsx_cluster as cluster -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests import base from neutron.tests.unit import test_api_v2 from neutron.tests.unit.vmware.apiclient import fake @@ -38,14 +40,14 @@ class NsxlibTestCase(base.BaseTestCase): instance = self.mock_nsxapi.start() instance.return_value.login.return_value = "the_cookie" fake_version = getattr(self, 'fake_version', "3.0") - instance.return_value.get_nvp_version.return_value = ( - api_client.NVPVersion(fake_version)) + instance.return_value.get_version.return_value = ( + version.Version(fake_version)) instance.return_value.request.side_effect = self.fc.fake_request self.fake_cluster = cluster.NSXCluster( name='fake-cluster', nsx_controllers=['1.1.1.1:999'], default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = api_client.NVPApiHelper( + self.fake_cluster.api_client = client.NsxApiClient( ('1.1.1.1', '999', True), self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, self.fake_cluster.req_timeout, self.fake_cluster.http_timeout, @@ -70,17 +72,17 @@ class NsxlibNegativeBaseTestCase(base.BaseTestCase): # Choose 3.0, but the version is irrelevant for the aim of # these tests as calls are throwing up errors anyway fake_version = getattr(self, 'fake_version', "3.0") - instance.return_value.get_nvp_version.return_value = ( - api_client.NVPVersion(fake_version)) + instance.return_value.get_version.return_value = ( + version.Version(fake_version)) def _faulty_request(*args, **kwargs): - raise api_client.NvpApiException + raise exception.NsxApiException instance.return_value.request.side_effect = _faulty_request self.fake_cluster = cluster.NSXCluster( name='fake-cluster', nsx_controllers=['1.1.1.1:999'], default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = api_client.NVPApiHelper( + self.fake_cluster.api_client = client.NsxApiClient( ('1.1.1.1', '999', True), self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, self.fake_cluster.req_timeout, self.fake_cluster.http_timeout, diff --git a/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py b/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py index 35e4a81eb..80d2593d2 100644 --- a/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py +++ b/neutron/tests/unit/vmware/nsxlib/test_l2gateway.py @@ -14,9 +14,9 @@ # limitations under the License. # +from neutron.plugins.nicira.api_client import exception from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests.unit import test_api_v2 from neutron.tests.unit.vmware.nsxlib import base @@ -26,7 +26,7 @@ _uuid = test_api_v2._uuid class L2GatewayNegativeTestCase(base.NsxlibNegativeBaseTestCase): def test_create_l2_gw_service_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(exception.NsxApiException, l2gwlib.create_l2_gw_service, self.fake_cluster, 'fake-tenant', @@ -35,19 +35,19 @@ class L2GatewayNegativeTestCase(base.NsxlibNegativeBaseTestCase): 'interface_name': 'xxx'}]) def test_delete_l2_gw_service_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(exception.NsxApiException, l2gwlib.delete_l2_gw_service, self.fake_cluster, 'fake-gateway') def test_get_l2_gw_service_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(exception.NsxApiException, l2gwlib.get_l2_gw_service, self.fake_cluster, 'fake-gateway') def test_update_l2_gw_service_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(exception.NsxApiException, l2gwlib.update_l2_gw_service, self.fake_cluster, 'fake-gateway', diff --git a/neutron/tests/unit/vmware/nsxlib/test_lsn.py b/neutron/tests/unit/vmware/nsxlib/test_lsn.py index 0ba35e530..aa8783daa 100644 --- a/neutron/tests/unit/vmware/nsxlib/test_lsn.py +++ b/neutron/tests/unit/vmware/nsxlib/test_lsn.py @@ -17,10 +17,10 @@ import json import mock from neutron.common import exceptions +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nsx_exc from neutron.plugins.nicira.common import utils from neutron.plugins.nicira.nsxlib import lsn as lsnlib -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests import base @@ -239,7 +239,7 @@ class LSNTestCase(base.BaseTestCase): lsn_id = "foo_lsn_id" lsn_port_id = "foo_lsn_port_id" lswitch_port_id = "foo_lswitch_port_id" - self.mock_request.side_effect = api_client.Conflict + self.mock_request.side_effect = api_exc.Conflict self.assertRaises( nsx_exc.LsnConfigurationConflict, lsnlib.lsn_port_plug_network, diff --git a/neutron/tests/unit/vmware/nsxlib/test_queue.py b/neutron/tests/unit/vmware/nsxlib/test_queue.py index b274aa067..651c2c98e 100644 --- a/neutron/tests/unit/vmware/nsxlib/test_queue.py +++ b/neutron/tests/unit/vmware/nsxlib/test_queue.py @@ -17,8 +17,8 @@ import mock from neutron.common import exceptions +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.nsxlib import queue as queuelib -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests.unit.vmware.nsxlib import base @@ -44,7 +44,7 @@ class TestLogicalQueueLib(base.NsxlibTestCase): def test_create_lqueue_nsx_error_raises(self): def raise_nsx_exc(*args, **kwargs): - raise api_client.NvpApiException() + raise api_exc.NsxApiException() with mock.patch.object(queuelib, 'do_request', new=raise_nsx_exc): self.assertRaises( diff --git a/neutron/tests/unit/vmware/nsxlib/test_router.py b/neutron/tests/unit/vmware/nsxlib/test_router.py index 71e055bc5..b27314025 100644 --- a/neutron/tests/unit/vmware/nsxlib/test_router.py +++ b/neutron/tests/unit/vmware/nsxlib/test_router.py @@ -18,11 +18,12 @@ import mock from neutron.common import exceptions from neutron.openstack.common import uuidutils +from neutron.plugins.nicira.api_client import exception as api_exc +from neutron.plugins.nicira.api_client.version import Version from neutron.plugins.nicira.common import exceptions as nsx_exc from neutron.plugins.nicira.common import utils from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import switch as switchlib -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests.unit import test_api_v2 from neutron.tests.unit.vmware.nsxlib import base @@ -33,8 +34,8 @@ class TestNatRules(base.NsxlibTestCase): def _test_create_lrouter_dnat_rule(self, version): with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - new=lambda: api_client.NVPVersion(version)): + 'get_version', + new=lambda: Version(version)): tenant_id = 'pippo' lrouter = routerlib.create_lrouter(self.fake_cluster, uuidutils.generate_uuid(), @@ -196,8 +197,8 @@ class TestExplicitLRouters(base.NsxlibTestCase): with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', return_value=nsx_routes): with mock.patch.object(routerlib, 'create_explicit_route_lrouter', - side_effect=api_client.NvpApiException): - self.assertRaises(api_client.NvpApiException, + side_effect=api_exc.NsxApiException): + self.assertRaises(api_exc.NsxApiException, routerlib.update_explicit_routes_lrouter, self.fake_cluster, router_id, new_routes) @@ -237,12 +238,12 @@ class TestExplicitLRouters(base.NsxlibTestCase): with mock.patch.object(routerlib, 'get_explicit_routes_lrouter', return_value=nsx_routes): with mock.patch.object(routerlib, 'delete_explicit_route_lrouter', - side_effect=api_client.NvpApiException): + side_effect=api_exc.NsxApiException): with mock.patch.object( routerlib, 'create_explicit_route_lrouter', return_value='fake_uuid'): self.assertRaises( - api_client.NvpApiException, + api_exc.NsxApiException, routerlib.update_explicit_routes_lrouter, self.fake_cluster, router_id, new_routes) @@ -250,7 +251,7 @@ class TestExplicitLRouters(base.NsxlibTestCase): class RouterNegativeTestCase(base.NsxlibNegativeBaseTestCase): def test_create_lrouter_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(api_exc.NsxApiException, routerlib.create_lrouter, self.fake_cluster, uuidutils.generate_uuid(), @@ -259,19 +260,19 @@ class RouterNegativeTestCase(base.NsxlibNegativeBaseTestCase): 'my_hop') def test_delete_lrouter_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(api_exc.NsxApiException, routerlib.delete_lrouter, self.fake_cluster, 'fake_router') def test_get_lrouter_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(api_exc.NsxApiException, routerlib.get_lrouter, self.fake_cluster, 'fake_router') def test_update_lrouter_on_failure(self): - self.assertRaises(api_client.NvpApiException, + self.assertRaises(api_exc.NsxApiException, routerlib.update_lrouter, self.fake_cluster, 'fake_router', @@ -313,8 +314,8 @@ class TestLogicalRouters(base.NsxlibTestCase): def _create_lrouter(self, version, neutron_id=None, distributed=None): with mock.patch.object( - self.fake_cluster.api_client, 'get_nvp_version', - return_value=api_client.NVPVersion(version)): + self.fake_cluster.api_client, 'get_version', + return_value=Version(version)): if not neutron_id: neutron_id = uuidutils.generate_uuid() lrouter = routerlib.create_lrouter( @@ -374,8 +375,8 @@ class TestLogicalRouters(base.NsxlibTestCase): } with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - return_value=api_client.NVPVersion(version)): + 'get_version', + return_value=Version(version)): with mock.patch.dict(routerlib.ROUTER_FUNC_DICT, foo_func_dict, clear=True): return routerlib.update_lrouter( @@ -671,7 +672,7 @@ class TestLogicalRouters(base.NsxlibTestCase): 'name', True, ['192.168.0.1'], '00:11:22:33:44:55') def raise_nsx_exc(*args, **kwargs): - raise api_client.NvpApiException() + raise api_exc.NsxApiException() with mock.patch.object(routerlib, 'do_request', new=raise_nsx_exc): self.assertRaises( @@ -763,8 +764,8 @@ class TestLogicalRouters(base.NsxlibTestCase): 'fake-lrouter', '10.0.0.1') with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - new=lambda: api_client.NVPVersion(version)): + 'get_version', + new=lambda: Version(version)): routerlib.create_lrouter_snat_rule( self.fake_cluster, lrouter['uuid'], '10.0.0.2', '10.0.0.2', order=200, @@ -786,8 +787,8 @@ class TestLogicalRouters(base.NsxlibTestCase): 'fake-lrouter', '10.0.0.1') with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - return_value=api_client.NVPVersion(version)): + 'get_version', + return_value=Version(version)): routerlib.create_lrouter_dnat_rule( self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200, dest_port=dest_port, @@ -817,7 +818,7 @@ class TestLogicalRouters(base.NsxlibTestCase): '10.0.0.1') with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', + 'get_version', new=lambda: '2.0'): self.assertRaises(AttributeError, routerlib.create_lrouter_snat_rule, @@ -832,8 +833,8 @@ class TestLogicalRouters(base.NsxlibTestCase): 'fake-lrouter', '10.0.0.1') with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - new=lambda: api_client.NVPVersion(version)): + 'get_version', + new=lambda: Version(version)): routerlib.create_lrouter_nosnat_rule( self.fake_cluster, lrouter['uuid'], order=100, @@ -857,8 +858,8 @@ class TestLogicalRouters(base.NsxlibTestCase): '10.0.0.1') # v2 or v3 makes no difference for this test with mock.patch.object(self.fake_cluster.api_client, - 'get_nvp_version', - new=lambda: api_client.NVPVersion('2.0')): + 'get_version', + new=lambda: Version('2.0')): routerlib.create_lrouter_snat_rule( self.fake_cluster, lrouter['uuid'], '10.0.0.2', '10.0.0.2', order=220, diff --git a/neutron/tests/unit/vmware/nsxlib/test_versioning.py b/neutron/tests/unit/vmware/nsxlib/test_versioning.py index a495e6c5a..0e7e3a8dc 100644 --- a/neutron/tests/unit/vmware/nsxlib/test_versioning.py +++ b/neutron/tests/unit/vmware/nsxlib/test_versioning.py @@ -14,44 +14,45 @@ # limitations under the License. # +from neutron.plugins.nicira.api_client import exception +from neutron.plugins.nicira.api_client.version import Version from neutron.plugins.nicira.nsxlib import router as routerlib from neutron.plugins.nicira.nsxlib import versioning -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests import base class TestVersioning(base.BaseTestCase): def test_function_handling_missing_minor(self): - version = api_client.NVPVersion('2.0') + version = Version('2.0') function = versioning.get_function_by_version( routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) self.assertEqual(routerlib.create_implicit_routing_lrouter, function) def test_function_handling_with_both_major_and_minor(self): - version = api_client.NVPVersion('3.2') + version = Version('3.2') function = versioning.get_function_by_version( routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) self.assertEqual(routerlib.create_explicit_routing_lrouter, function) def test_function_handling_with_newer_major(self): - version = api_client.NVPVersion('5.2') + version = Version('5.2') function = versioning.get_function_by_version( routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) self.assertEqual(routerlib.create_explicit_routing_lrouter, function) def test_function_handling_with_obsolete_major(self): - version = api_client.NVPVersion('1.2') + version = Version('1.2') self.assertRaises(NotImplementedError, versioning.get_function_by_version, routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version) def test_function_handling_with_unknown_version(self): - self.assertRaises(api_client.ServiceUnavailable, + self.assertRaises(exception.ServiceUnavailable, versioning.get_function_by_version, routerlib.ROUTER_FUNC_DICT, 'create_lrouter', None) diff --git a/neutron/tests/unit/vmware/test_agent_scheduler.py b/neutron/tests/unit/vmware/test_agent_scheduler.py index 4b4397891..2347cd6f0 100644 --- a/neutron/tests/unit/vmware/test_agent_scheduler.py +++ b/neutron/tests/unit/vmware/test_agent_scheduler.py @@ -45,7 +45,7 @@ class DhcpAgentNotifierTestCase(test_base.OvsDhcpAgentNotifierTestCase): patch_sync.start() # Emulate tests against NSX 2.x - instance.return_value.get_nvp_version.return_value = "2.999" + instance.return_value.get_version.return_value = "2.999" instance.return_value.request.side_effect = self.fc.fake_request super(DhcpAgentNotifierTestCase, self).setUp() self.addCleanup(self.fc.reset_all) diff --git a/neutron/tests/unit/vmware/test_dhcpmeta.py b/neutron/tests/unit/vmware/test_dhcpmeta.py index 0adce9215..fed22e168 100644 --- a/neutron/tests/unit/vmware/test_dhcpmeta.py +++ b/neutron/tests/unit/vmware/test_dhcpmeta.py @@ -20,6 +20,7 @@ from oslo.config import cfg from neutron.common import exceptions as n_exc from neutron import context from neutron.db import api as db +from neutron.plugins.nicira.api_client.exception import NsxApiException from neutron.plugins.nicira.common import exceptions as p_exc from neutron.plugins.nicira.dbexts import lsn_db from neutron.plugins.nicira.dhcp_meta import constants @@ -27,7 +28,6 @@ from neutron.plugins.nicira.dhcp_meta import lsnmanager as lsn_man from neutron.plugins.nicira.dhcp_meta import migration as mig_man from neutron.plugins.nicira.dhcp_meta import nsx from neutron.plugins.nicira.dhcp_meta import rpc -from neutron.plugins.nicira.NvpApiClient import NvpApiException from neutron.tests import base @@ -289,7 +289,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_get_raise_not_found_with_exc(n_exc.NotFound) def test_lsn_get_raise_not_found_with_api_error(self): - self._test_lsn_get_raise_not_found_with_exc(NvpApiException) + self._test_lsn_get_raise_not_found_with_exc(NsxApiException) def _test_lsn_get_silent_raise_with_exc(self, exc): self.mock_lsn_api.lsn_for_network_get.side_effect = exc @@ -303,7 +303,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_get_silent_raise_with_exc(n_exc.NotFound) def test_lsn_get_silent_raise_with_api_error(self): - self._test_lsn_get_silent_raise_with_exc(NvpApiException) + self._test_lsn_get_silent_raise_with_exc(NsxApiException) def test_lsn_create(self): self.mock_lsn_api.lsn_for_network_create.return_value = self.lsn_id @@ -312,7 +312,7 @@ class LsnManagerTestCase(base.BaseTestCase): mock.ANY, self.net_id) def test_lsn_create_raise_api_error(self): - self.mock_lsn_api.lsn_for_network_create.side_effect = NvpApiException + self.mock_lsn_api.lsn_for_network_create.side_effect = NsxApiException self.assertRaises(p_exc.NvpPluginException, self.manager.lsn_create, mock.ANY, self.net_id) @@ -334,7 +334,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_delete_with_exc(n_exc.NotFound) def test_lsn_delete_api_exception(self): - self._test_lsn_delete_with_exc(NvpApiException) + self._test_lsn_delete_with_exc(NsxApiException) def test_lsn_delete_by_network(self): self.mock_lsn_api.lsn_for_network_get.return_value = self.lsn_id @@ -354,7 +354,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_delete_by_network_with_exc(n_exc.NotFound) def test_lsn_delete_by_network_with_not_api_error(self): - self._test_lsn_delete_by_network_with_exc(NvpApiException) + self._test_lsn_delete_by_network_with_exc(NsxApiException) def test_lsn_port_get(self): self.mock_lsn_api.lsn_port_by_subnet_get.return_value = ( @@ -411,7 +411,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_port_create_with_exc(n_exc.NotFound, p_exc.LsnNotFound) def test_lsn_port_create_api_exception(self): - self._test_lsn_port_create_with_exc(NvpApiException, + self._test_lsn_port_create_with_exc(NsxApiException, p_exc.NvpPluginException) def test_lsn_port_delete(self): @@ -429,7 +429,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_port_delete_with_exc(n_exc.NotFound) def test_lsn_port_delete_api_exception(self): - self._test_lsn_port_delete_with_exc(NvpApiException) + self._test_lsn_port_delete_with_exc(NsxApiException) def _test_lsn_port_dhcp_setup(self, ret_val, sub): self.mock_lsn_api.lsn_port_create.return_value = self.lsn_port_id @@ -630,7 +630,7 @@ class LsnManagerTestCase(base.BaseTestCase): self._test_lsn_port_dispose_with_values(self.lsn_id, None, 0) def test_lsn_port_dispose_api_error(self): - self.mock_lsn_api.lsn_port_delete.side_effect = NvpApiException + self.mock_lsn_api.lsn_port_delete.side_effect = NsxApiException with mock.patch.object(lsn_man.LOG, 'warn') as l: self.manager.lsn_port_dispose(mock.ANY, self.net_id, self.mac) self.assertEqual(1, l.call_count) @@ -677,7 +677,7 @@ class LsnManagerTestCase(base.BaseTestCase): def test_lsn_port_update_raise_error(self): self.mock_lsn_api.lsn_port_host_entries_update.side_effect = ( - NvpApiException) + NsxApiException) self.assertRaises(p_exc.PortConfigurationError, self.manager.lsn_port_update, mock.ANY, mock.ANY, mock.ANY, mock.ANY) diff --git a/neutron/tests/unit/vmware/test_nsx_opts.py b/neutron/tests/unit/vmware/test_nsx_opts.py index e09d307dd..c499c5be5 100644 --- a/neutron/tests/unit/vmware/test_nsx_opts.py +++ b/neutron/tests/unit/vmware/test_nsx_opts.py @@ -23,12 +23,13 @@ from oslo.config import cfg from neutron.common import config as q_config from neutron.manager import NeutronManager from neutron.openstack.common import uuidutils +from neutron.plugins.nicira.api_client import client +from neutron.plugins.nicira.api_client import version from neutron.plugins.nicira.common import config # noqa from neutron.plugins.nicira.common import exceptions from neutron.plugins.nicira.common import sync from neutron.plugins.nicira import nsx_cluster from neutron.plugins.nicira.nsxlib import lsn as lsnlib -from neutron.plugins.nicira import NvpApiClient as api_client from neutron.tests import base from neutron.tests.unit.vmware import get_fake_conf from neutron.tests.unit.vmware import PLUGIN_NAME @@ -150,9 +151,9 @@ class ConfigurationTest(base.BaseTestCase): self.assertEqual(config.AgentModes.AGENTLESS, cfg.CONF.NSX.agent_mode) # The version returned from NSX does not really matter here - with mock.patch.object(api_client.NVPApiHelper, - 'get_nvp_version', - return_value=api_client.NVPVersion("9.9")): + with mock.patch.object(client.NsxApiClient, + 'get_version', + return_value=version.Version("9.9")): with mock.patch.object(lsnlib, 'service_cluster_exists', return_value=True): @@ -168,9 +169,9 @@ class ConfigurationTest(base.BaseTestCase): cfg.CONF.set_override('core_plugin', PLUGIN_NAME) self.assertEqual(config.AgentModes.AGENTLESS, cfg.CONF.NSX.agent_mode) - with mock.patch.object(api_client.NVPApiHelper, - 'get_nvp_version', - return_value=api_client.NVPVersion("3.2")): + with mock.patch.object(client.NsxApiClient, + 'get_version', + return_value=version.Version("3.2")): self.assertRaises(exceptions.NvpPluginException, NeutronManager) def test_agentless_extensions_unmet_deps_fail(self): @@ -179,9 +180,9 @@ class ConfigurationTest(base.BaseTestCase): cfg.CONF.set_override('core_plugin', PLUGIN_NAME) self.assertEqual(config.AgentModes.AGENTLESS, cfg.CONF.NSX.agent_mode) - with mock.patch.object(api_client.NVPApiHelper, - 'get_nvp_version', - return_value=api_client.NVPVersion("3.2")): + with mock.patch.object(client.NsxApiClient, + 'get_version', + return_value=version.Version("3.2")): with mock.patch.object(lsnlib, 'service_cluster_exists', return_value=False): diff --git a/neutron/tests/unit/vmware/test_nsx_plugin.py b/neutron/tests/unit/vmware/test_nsx_plugin.py index c5882bc85..73543cddb 100644 --- a/neutron/tests/unit/vmware/test_nsx_plugin.py +++ b/neutron/tests/unit/vmware/test_nsx_plugin.py @@ -39,14 +39,14 @@ from neutron.manager import NeutronManager from neutron.openstack.common.db import exception as db_exc from neutron.openstack.common import log from neutron.openstack.common import uuidutils +from neutron.plugins.nicira.api_client import exception as api_exc +from neutron.plugins.nicira.api_client.version import Version from neutron.plugins.nicira.common import exceptions as nsx_exc from neutron.plugins.nicira.common import sync from neutron.plugins.nicira.dbexts import db as nsx_db from neutron.plugins.nicira.extensions import distributedrouter as dist_router from neutron.plugins.nicira import NeutronPlugin from neutron.plugins.nicira import nsxlib -from neutron.plugins.nicira import NvpApiClient -from neutron.plugins.nicira.NvpApiClient import NVPVersion from neutron.tests.unit import _test_extension_portbindings as test_bindings import neutron.tests.unit.test_db_plugin as test_plugin import neutron.tests.unit.test_extension_ext_gw_mode as test_ext_gw_mode @@ -106,8 +106,8 @@ class NsxPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): patch_sync.start() # Emulate tests against NSX 2.x - self.mock_instance.return_value.get_nvp_version.return_value = ( - NVPVersion("2.9")) + self.mock_instance.return_value.get_version.return_value = ( + Version("2.9")) self.mock_instance.return_value.request.side_effect = ( self.fc.fake_request) super(NsxPluginV2TestCase, self).setUp(plugin=plugin, @@ -197,7 +197,7 @@ class TestPortsV2(NsxPluginV2TestCase, def test_create_port_nsx_error_no_orphan_left(self): with mock.patch.object(nsxlib.switch, 'create_lport', - side_effect=NvpApiClient.NvpApiException): + side_effect=api_exc.NsxApiException): with self.network() as net: net_id = net['network']['id'] self._create_port(self.fmt, net_id, @@ -535,8 +535,8 @@ class TestL3NatTestCase(L3NatTest, def _test_router_create_with_distributed(self, dist_input, dist_expected, version='3.1', return_code=201): - self.mock_instance.return_value.get_nvp_version.return_value = ( - NvpApiClient.NVPVersion(version)) + self.mock_instance.return_value.get_version.return_value = ( + Version(version)) data = {'tenant_id': 'whatever'} data['name'] = 'router1' @@ -597,7 +597,7 @@ class TestL3NatTestCase(L3NatTest, def test_router_create_nsx_error_returns_500(self, vlan_id=None): with mock.patch.object(nsxlib.router, 'create_router_lport', - side_effect=NvpApiClient.NvpApiException): + side_effect=api_exc.NsxApiException): with self._create_l3_ext_network(vlan_id) as net: with self.subnet(network=net) as s: res = self._create_router_with_gw_info_for_test(s) @@ -641,7 +641,7 @@ class TestL3NatTestCase(L3NatTest, # Simulate error while fetching nsx router gw port with mock.patch.object(self._plugin_class, '_find_router_gw_port', - side_effect=NvpApiClient.NvpApiException): + side_effect=api_exc.NsxApiException): with self._create_l3_ext_network() as net: with self.subnet(network=net) as s: res = self._create_router_with_gw_info_for_test(s) @@ -819,7 +819,7 @@ class TestL3NatTestCase(L3NatTest, # do the real thing return real_func(plugin_instance, *args) # otherwise raise - raise NvpApiClient.NvpApiException() + raise api_exc.NsxApiException() with mock.patch.object(self._plugin_class, 'add_router_interface', @@ -890,7 +890,7 @@ class TestL3NatTestCase(L3NatTest, # do the real thing return real_func(plugin_instance, *args) # otherwise raise - raise NvpApiClient.NvpApiException() + raise api_exc.NsxApiException() with mock.patch.object(self._plugin_class, 'remove_router_interface', diff --git a/neutron/tests/unit/vmware/test_nsx_sync.py b/neutron/tests/unit/vmware/test_nsx_sync.py index 4ba57f1af..7a94fac43 100644 --- a/neutron/tests/unit/vmware/test_nsx_sync.py +++ b/neutron/tests/unit/vmware/test_nsx_sync.py @@ -28,9 +28,11 @@ from neutron.common import constants from neutron import context from neutron.openstack.common import jsonutils as json from neutron.openstack.common import log +from neutron.plugins.nicira.api_client import client +from neutron.plugins.nicira.api_client import exception as api_exc +from neutron.plugins.nicira.api_client import version from neutron.plugins.nicira.common import sync from neutron.plugins.nicira import nsx_cluster as cluster -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira import nvplib as nsx_utils from neutron.plugins.vmware import plugin from neutron.tests import base @@ -243,7 +245,7 @@ class SyncLoopingCallTestCase(base.BaseTestCase): # the looping call with mock.patch.object( sync.NvpSynchronizer, '_synchronize_state', return_value=0.01): - synchronizer = sync.NvpSynchronizer(None, None, + synchronizer = sync.NvpSynchronizer(mock.ANY, mock.ANY, 100, 0, 0) time.sleep(0.03) # stop looping call before asserting @@ -266,18 +268,20 @@ class SyncTestCase(base.BaseTestCase): patch_sync.start() self.mock_api.return_value.login.return_value = "the_cookie" # Emulate tests against NSX 3.x - self.mock_api.return_value.get_nvp_version.return_value = ( - NvpApiClient.NVPVersion("3.1")) + self.mock_api.return_value.get_version.return_value = ( + version.Version("3.1")) self.mock_api.return_value.request.side_effect = self.fc.fake_request self.fake_cluster = cluster.NSXCluster( name='fake-cluster', nsx_controllers=['1.1.1.1:999'], default_tz_uuid=_uuid(), nsx_user='foo', nsx_password='bar') - self.fake_cluster.api_client = NvpApiClient.NVPApiHelper( + self.fake_cluster.api_client = client.NsxApiClient( ('1.1.1.1', '999', True), self.fake_cluster.nsx_user, self.fake_cluster.nsx_password, - self.fake_cluster.req_timeout, self.fake_cluster.http_timeout, - self.fake_cluster.retries, self.fake_cluster.redirects) + request_timeout=self.fake_cluster.req_timeout, + http_timeout=self.fake_cluster.http_timeout, + retries=self.fake_cluster.retries, + redirects=self.fake_cluster.redirects) # Instantiate Neutron plugin # and setup needed config variables args = ['--config-file', get_fake_conf('neutron.conf.test'), @@ -637,8 +641,7 @@ class SyncTestCase(base.BaseTestCase): self.assertEqual(constants.NET_STATUS_DOWN, q_rtr_data['status']) def test_sync_nsx_failure_backoff(self): - self.mock_api.return_value.request.side_effect = ( - NvpApiClient.RequestTimeout) + self.mock_api.return_value.request.side_effect = api_exc.RequestTimeout # chunk size won't matter here sp = sync.SyncParameters(999) for i in range(10): diff --git a/neutron/tests/unit/vmware/test_nsx_utils.py b/neutron/tests/unit/vmware/test_nsx_utils.py index 3c199aca3..9c1607d69 100644 --- a/neutron/tests/unit/vmware/test_nsx_utils.py +++ b/neutron/tests/unit/vmware/test_nsx_utils.py @@ -19,10 +19,10 @@ import mock from neutron.db import api as db_api from neutron.openstack.common import uuidutils +from neutron.plugins.nicira.api_client import exception as api_exc from neutron.plugins.nicira.common import exceptions as nsx_exc from neutron.plugins.nicira.common import nsx_utils from neutron.plugins.nicira.common import utils -from neutron.plugins.nicira import NvpApiClient from neutron.plugins.nicira import nvplib from neutron.tests import base from neutron.tests.unit.vmware import nsx_method @@ -278,12 +278,12 @@ class ClusterManagementTestCase(nsx_base.NsxlibTestCase): def test_cluster_in_readonly_mode(self): with mock.patch.object(self.fake_cluster.api_client, 'request', - side_effect=NvpApiClient.ReadOnlyMode): + side_effect=api_exc.ReadOnlyMode): self.assertRaises(nsx_exc.MaintenanceInProgress, nvplib.do_request, cluster=self.fake_cluster) def test_cluster_method_not_implemented(self): - self.assertRaises(NvpApiClient.NvpApiException, + self.assertRaises(api_exc.NsxApiException, nvplib.do_request, nvplib.HTTP_GET, nvplib._build_uri_path('MY_FAKE_RESOURCE',