Rename/refactoring of NVP api client to NSX

Partial-implements blueprint nicira-plugin-renaming

Change-Id: I7d3bc088762f53473892480b2e238fe60c2c0b74
This commit is contained in:
armando-migliaccio 2014-02-12 13:39:48 -08:00 committed by Gerrit Code Review
parent 3a6d0e421d
commit e6c0f9c168
41 changed files with 819 additions and 839 deletions

View File

@ -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,

View File

@ -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'])

View File

@ -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.")

View File

@ -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)

View File

@ -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)

View File

@ -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 <dlapsley@nicira.com>, Nicira Networks, Inc.
# @author: Aaron Rosen, Nicira Networks, Inc.
from abc import ABCMeta
import httplib
import logging
import time
import six
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
from neutron.plugins.nicira.api_client.common import (
_conn_str)
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.
class NsxApiClient(eventlet_client.EventletApiClient):
"""The Nsx API Client."""
This defines the interface and property structure for synchronous and
coroutine-based classes.
'''
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:
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.
: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)
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.
'''
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
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
if not self._version:
self._version = version.find_version(response.headers)
return response.body
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': _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().
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)
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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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})

View File

@ -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 "

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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__)

View File

@ -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):

View File

@ -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'))

View File

@ -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": [

View File

@ -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)

View File

@ -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()}])

View File

@ -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,

View File

@ -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',

View File

@ -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,

View File

@ -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(

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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',

View File

@ -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):

View File

@ -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',