diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py b/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py index fd7aba27..5144691c 100644 --- a/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py +++ b/vmware_nsxlib/tests/unit/v3/policy/test_lb_resources.py @@ -807,6 +807,39 @@ class TestPolicyLBService(test_resources.NsxPolicyLibTestCase): lbs_id, max_attempts=5, sleep=0.1, tenant=TEST_TENANT) + def test_wait_until_realized_error(self): + lbs_id = 'test_lbs' + error_code = 23500 + related_error_code = 23707 + error_msg = 'Found errors in the request.' + related_error_msg = 'Exceed maximum number of load balancer.' + info = {'state': constants.STATE_ERROR, + 'realization_specific_identifier': lbs_id, + 'entity_type': 'LbServiceDto', + 'alarms': [{ + 'message': error_msg, + 'error_details': { + 'related_errors': [{ + 'error_code': related_error_code, + 'module_name': 'LOAD-BALANCER', + 'error_message': related_error_msg + }], + 'error_code': error_code, + 'module_name': 'LOAD-BALANCER', + 'error_message': error_msg + } + }]} + with mock.patch.object(self.resourceApi, "_get_realization_info", + return_value=info): + with self.assertRaises(nsxlib_exc.RealizationErrorStateError) as e: + self.resourceApi.wait_until_realized( + lbs_id, tenant=TEST_TENANT) + error_msg_tail = "%s: %s" % (error_msg, related_error_msg) + self.assertTrue(e.exception.msg.endswith(error_msg_tail)) + self.assertEqual(e.exception.error_code, error_code) + self.assertEqual(e.exception.related_error_codes, + [related_error_code]) + def test_wait_until_realized_succeed(self): lbs_id = 'test_lbs' info = {'state': constants.STATE_REALIZED, diff --git a/vmware_nsxlib/tests/unit/v3/policy/test_resources.py b/vmware_nsxlib/tests/unit/v3/policy/test_resources.py index cc4e6cee..b30d5905 100644 --- a/vmware_nsxlib/tests/unit/v3/policy/test_resources.py +++ b/vmware_nsxlib/tests/unit/v3/policy/test_resources.py @@ -4034,6 +4034,30 @@ class TestPolicyIpPool(NsxPolicyLibTestCase): ip_pool_id, max_attempts=5, sleep=0.1, tenant=TEST_TENANT) + def test_wait_until_realized_error(self): + ip_alloc_id = 'ip_alloc_1' + error_code = 5109 + error_msg = 'Insufficient free IP addresses.' + info = {'state': constants.STATE_ERROR, + 'realization_specific_identifier': ip_alloc_id, + 'entity_type': 'AllocationIpAddress', + 'alarms': [{ + 'message': error_msg, + 'error_details': { + 'error_code': error_code, + 'module_name': 'id-allocation service', + 'error_message': error_msg + } + }]} + with mock.patch.object(self.resourceApi, "_get_realization_info", + return_value=info): + with self.assertRaises(nsxlib_exc.RealizationErrorStateError) as e: + self.resourceApi.wait_until_realized( + ip_alloc_id, tenant=TEST_TENANT) + self.assertTrue(e.exception.msg.endswith(error_msg)) + self.assertEqual(e.exception.error_code, error_code) + self.assertEqual(e.exception.related_error_codes, []) + def test_wait_until_realized_succeed(self): ip_pool_id = 'p1' info = {'state': constants.STATE_REALIZED, diff --git a/vmware_nsxlib/v3/policy/core_resources.py b/vmware_nsxlib/v3/policy/core_resources.py index bc986e63..5145086b 100644 --- a/vmware_nsxlib/v3/policy/core_resources.py +++ b/vmware_nsxlib/v3/policy/core_resources.py @@ -223,17 +223,23 @@ class NsxPolicyResourceBase(object): realization_info.get('realization_specific_identifier')): return realization_info['realization_specific_identifier'] - def _get_realization_error_message(self, info): + def _get_realization_error_message_and_code(self, info): error_msg = 'unknown' + error_code = None + related_error_codes = [] if info.get('alarms'): alarm = info['alarms'][0] error_msg = alarm.get('message') - if (alarm.get('error_details') and - alarm['error_details'].get('related_errors')): - related = alarm['error_details']['related_errors'][0] - error_msg = '%s: %s' % (error_msg, - related.get('error_message')) - return error_msg + if alarm.get('error_details'): + error_code = alarm['error_details'].get('error_code') + if alarm['error_details'].get('related_errors'): + related = alarm['error_details']['related_errors'] + for err_obj in related: + error_msg = '%s: %s' % (error_msg, + err_obj.get('error_message')) + if err_obj.get('error_code'): + related_error_codes.append(err_obj['error_code']) + return error_msg, error_code, related_error_codes def _wait_until_realized(self, resource_def, entity_type=None, sleep=None, max_attempts=None): @@ -254,11 +260,13 @@ class NsxPolicyResourceBase(object): if info['state'] == constants.STATE_REALIZED: return info if info['state'] == constants.STATE_ERROR: - error_msg = self._get_realization_error_message(info) + error_msg, error_code, related_error_codes = \ + self._get_realization_error_message_and_code(info) raise exceptions.RealizationErrorStateError( resource_type=resource_def.resource_type(), resource_id=resource_def.get_id(), - error=error_msg) + error=error_msg, error_code=error_code, + related_error_codes=related_error_codes) try: return get_info() @@ -302,11 +310,13 @@ class NsxPolicyResourceBase(object): if resource_def and test_num % check_status == (check_status - 1): info = self._get_realization_info(resource_def) if info and info['state'] == constants.STATE_ERROR: - error_msg = self._get_realization_error_message(info) + error_msg, error_code, related_error_codes = \ + self._get_realization_error_message_and_code(info) raise exceptions.RealizationErrorStateError( resource_type=resource_def.resource_type(), resource_id=resource_def.get_id(), - error=error_msg) + error=error_msg, error_code=error_code, + related_error_codes=related_error_codes) if (info and info['state'] == constants.STATE_REALIZED and info.get('realization_specific_identifier')): LOG.warning("Realization ID for %s was not found via "