NSX|V3 fix nsxlib raised error with managers

The NSX3Client did not get the nsx managers IPs, and they where missing
from error messages.

To fix this, and also better fix a similar problem with max_attempts,
the client init method may get another instance of the client, and copy
relevant information from it.
This option is used by the copy-constructor "new_client_for" without the
RestClient class being aware of arguments relevant only to the NSXClient.

Also adding a new test for a resource error message, to make sure it contains
the nsx_manager ip.

Change-Id: I9e7e28eb5fd69ace44547d40cf8cd09e2457c5ed
This commit is contained in:
Adit Sarfaty 2016-10-06 11:32:25 +03:00
parent 990cf7475a
commit 93fa5bcb47
4 changed files with 46 additions and 12 deletions

View File

@ -39,6 +39,7 @@ class NsxLib(object):
# create the Client
self.client = client.NSX3Client(
self.cluster,
nsx_api_managers=nsxlib_config.nsx_api_managers,
max_attempts=nsxlib_config.max_attempts)
# init the api object

View File

@ -40,11 +40,10 @@ class RESTClient(object):
def __init__(self, connection, url_prefix=None,
default_headers=None,
max_attempts=utils.DEFAULT_MAX_ATTEMPTS):
client_obj=None):
self._conn = connection
self._url_prefix = url_prefix or ""
self._default_headers = default_headers or {}
self.max_attempts = max_attempts
def new_client_for(self, *uri_segments):
uri = self._build_url('/'.join(uri_segments))
@ -53,7 +52,7 @@ class RESTClient(object):
self._conn,
url_prefix=uri,
default_headers=self._default_headers,
max_attempts=self.max_attempts)
client_obj=self)
def list(self, headers=None):
return self.url_list('')
@ -93,7 +92,7 @@ class RESTClient(object):
if result.status_code not in expected:
result_msg = result.json() if result.content else ''
LOG.warning(_LW("The HTTP request returned error code "
"%(result)d, whereas %(expected)s response "
"%(result)s, whereas %(expected)s response "
"codes were expected. Response body %(body)s"),
{'result': result.status_code,
'expected': '/'.join([str(code)
@ -132,7 +131,6 @@ class RESTClient(object):
request_url = self._build_url(url)
do_request = getattr(self._conn, method.lower())
LOG.debug("REST call: %s %s\nHeaders: %s\nBody: %s",
method, request_url, request_headers, body)
@ -159,14 +157,14 @@ class JSONRESTClient(RESTClient):
def __init__(self, connection, url_prefix=None,
default_headers=None,
max_attempts=utils.DEFAULT_MAX_ATTEMPTS):
client_obj=None):
super(JSONRESTClient, self).__init__(
connection,
url_prefix=url_prefix,
default_headers=RESTClient.merge_headers(
JSONRESTClient._DEFAULT_HEADERS, default_headers),
max_attempts=max_attempts)
client_obj=client_obj)
def _rest_call(self, *args, **kwargs):
if kwargs.get('body') is not None:
@ -182,9 +180,16 @@ class NSX3Client(JSONRESTClient):
def __init__(self, connection, url_prefix=None,
default_headers=None,
nsx_api_managers=None,
max_attempts=utils.DEFAULT_MAX_ATTEMPTS):
max_attempts=utils.DEFAULT_MAX_ATTEMPTS,
client_obj=None):
self.nsx_api_managers = nsx_api_managers or []
# If the client obj is defined - copy configuration from it
if client_obj:
self.nsx_api_managers = client_obj.nsx_api_managers or []
self.max_attempts = client_obj.max_attempts
else:
self.nsx_api_managers = nsx_api_managers or []
self.max_attempts = max_attempts
url_prefix = url_prefix or NSX3Client._NSX_V1_API_PREFIX
if url_prefix and NSX3Client._NSX_V1_API_PREFIX not in url_prefix:
@ -197,7 +202,7 @@ class NSX3Client(JSONRESTClient):
super(NSX3Client, self).__init__(
connection, url_prefix=url_prefix,
default_headers=default_headers,
max_attempts=max_attempts)
client_obj=client_obj)
def _raise_error(self, status_code, operation, result_msg):
"""Override the Rest client errors to add the manager IPs"""

View File

@ -279,6 +279,7 @@ class NsxClientTestCase(NsxLibTestCase):
session_response=None):
mocked = resource_class(nsx_client.NSX3Client(
self.mock_nsx_clustered_api(session_response=session_response),
nsx_api_managers=[NSX_MANAGER],
max_attempts=NSX_MAX_ATTEMPTS))
if mock_validate:
mock.patch.object(mocked._client, '_validate_result').start()

View File

@ -19,6 +19,7 @@ import mock
from oslo_serialization import jsonutils
from vmware_nsx.nsxlib.v3 import exceptions
from vmware_nsx.nsxlib.v3 import resources
from vmware_nsx.tests.unit.nsxlib.v3 import mocks
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
@ -230,9 +231,10 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
def _mocked_lport(self, session_response=None):
def _mocked_lport(self, mock_validate=True, session_response=None):
return self.mocked_resource(
resources.LogicalPort, session_response=session_response)
resources.LogicalPort, mock_validate=mock_validate,
session_response=session_response)
def _get_profile_dicts(self, fake_port):
fake_profile_dicts = []
@ -389,6 +391,31 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
'https://1.2.3.4/api/v1/logical-ports/%s' % fake_port['id'],
data=jsonutils.dumps(fake_port, sort_keys=True))
def test_create_logical_port_fail(self):
"""
Test the failure of port creation
"""
fake_port = test_constants_v3.FAKE_PORT.copy()
profile_dicts = self._get_profile_dicts(fake_port)
pkt_classifiers, binding_repr = self._get_pktcls_bindings()
fake_port['address_bindings'] = binding_repr
mocked_resource = self._mocked_lport(mock_validate=False)
switch_profile = resources.SwitchingProfile
try:
mocked_resource.create(
fake_port['logical_switch_id'],
fake_port['attachment']['id'],
address_bindings=pkt_classifiers,
switch_profile_ids=switch_profile.build_switch_profile_ids(
mock.Mock(), *profile_dicts))
except exceptions.ManagerError as e:
self.assertIn(nsxlib_testcase.NSX_MANAGER, e.msg)
class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):