Rename/refactoring of NVP api client to NSX
Partial-implements blueprint nicira-plugin-renaming Change-Id: I7d3bc088762f53473892480b2e238fe60c2c0b74
This commit is contained in:
parent
3a6d0e421d
commit
e6c0f9c168
@ -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,
|
||||
|
@ -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'])
|
||||
|
@ -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.")
|
@ -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)
|
||||
|
246
neutron/plugins/nicira/api_client/base.py
Normal file
246
neutron/plugins/nicira/api_client/base.py
Normal 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)
|
@ -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
|
||||
|
@ -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)
|
@ -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)
|
@ -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)
|
106
neutron/plugins/nicira/api_client/exception.py
Normal file
106
neutron/plugins/nicira/api_client/exception.py
Normal 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
|
||||
}
|
@ -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)
|
||||
|
43
neutron/plugins/nicira/api_client/version.py
Normal file
43
neutron/plugins/nicira/api_client/version.py
Normal 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)
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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})
|
||||
|
@ -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 "
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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__)
|
||||
|
@ -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):
|
||||
|
@ -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'))
|
||||
|
@ -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": [
|
@ -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)
|
||||
|
@ -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()}])
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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',
|
||||
|
@ -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):
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user