From fb7f9d867489f4b51ca352f61f0364201acf6e1d Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Thu, 13 Oct 2016 15:54:05 +0300 Subject: [PATCH] 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. (Cherry picked from : I9e7e28eb5fd69ace44547d40cf8cd09e2457c5ed) Change-Id: I5066ae12aadd286ff880c8545df99a567aeddbeb --- .../tests/unit/v3/nsxlib_testcase.py | 1 + vmware_nsxlib/tests/unit/v3/test_resources.py | 31 +++++++++++++++++-- vmware_nsxlib/v3/__init__.py | 1 + vmware_nsxlib/v3/client.py | 25 +++++++++------ 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py b/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py index 32a77cd5..161dcfdc 100644 --- a/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py +++ b/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py @@ -280,6 +280,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() diff --git a/vmware_nsxlib/tests/unit/v3/test_resources.py b/vmware_nsxlib/tests/unit/v3/test_resources.py index 347f6832..22430f1d 100644 --- a/vmware_nsxlib/tests/unit/v3/test_resources.py +++ b/vmware_nsxlib/tests/unit/v3/test_resources.py @@ -23,6 +23,7 @@ from vmware_nsxlib.tests.unit.v3 import mocks from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase from vmware_nsxlib.tests.unit.v3 import test_client from vmware_nsxlib.tests.unit.v3 import test_constants +from vmware_nsxlib.v3 import exceptions from vmware_nsxlib.v3 import resources @@ -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=True, + session_response=session_response) def _get_profile_dicts(self, fake_port): fake_profile_dicts = [] @@ -386,6 +388,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.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): diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index f1ba264f..4d73df79 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -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 diff --git a/vmware_nsxlib/v3/client.py b/vmware_nsxlib/v3/client.py index 2496c366..589f91a0 100644 --- a/vmware_nsxlib/v3/client.py +++ b/vmware_nsxlib/v3/client.py @@ -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=None) 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: @@ -198,7 +203,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"""