diff --git a/vmware_nsxlib/tests/unit/v3/test_cluster.py b/vmware_nsxlib/tests/unit/v3/test_cluster.py index 2a6261da..91b01525 100644 --- a/vmware_nsxlib/tests/unit/v3/test_cluster.py +++ b/vmware_nsxlib/tests/unit/v3/test_cluster.py @@ -22,6 +22,7 @@ import six.moves.urllib.parse as urlparse from vmware_nsxlib.tests.unit.v3 import mocks from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase +from vmware_nsxlib import v3 from vmware_nsxlib.v3 import client from vmware_nsxlib.v3 import client_cert from vmware_nsxlib.v3 import cluster @@ -93,7 +94,7 @@ class RequestsHTTPProviderTestCase(unittest.TestCase): self.assertEqual(cert_provider_inst, session.cert_provider) self.assertEqual(99, session.timeout) - def test_validate_connection(self): + def test_validate_connection_keep_alive(self): mock_conn = mocks.MockRequestSessionApi() mock_conn.default_headers = {} mock_ep = mock.Mock() @@ -103,14 +104,59 @@ class RequestsHTTPProviderTestCase(unittest.TestCase): mock_cluster.nsxlib_config.url_base = 'abc' mock_cluster.nsxlib_config.keepalive_section = 'transport-zones' provider = cluster.NSXRequestsHTTPProvider() - self.assertRaises(nsxlib_exc.ResourceNotFound, - provider.validate_connection, - mock_cluster, mock_ep, mock_conn) + + with mock.patch.object(client.JSONRESTClient, "get", + return_value={'result_count': 0}): + self.assertRaises(nsxlib_exc.ResourceNotFound, + provider.validate_connection, + mock_cluster, mock_ep, mock_conn) with mock.patch.object(client.JSONRESTClient, "get", return_value={'result_count': 1}): provider.validate_connection(mock_cluster, mock_ep, mock_conn) + def _validate_con_mocks(self, nsx_version): + nsxlib_config = nsxlib_testcase.get_default_nsxlib_config() + nsxlib = v3.NsxLib(nsxlib_config) + nsxlib.nsx_version = nsx_version + mock_conn = mocks.MockRequestSessionApi() + mock_conn.default_headers = {} + mock_ep = mock.Mock() + mock_ep.provider.url = 'https://1.2.3.4' + conf = mock.Mock() + conf.url_base = 'abc' + conf.keepalive_section = 'transport-zones' + conf.validate_connection_method = nsxlib.validate_connection_method + mock_cluster = mock.Mock() + mock_cluster.nsxlib_config = conf + return (mock_cluster, mock_ep, mock_conn) + + def test_validate_connection_method_v1(self): + mock_cluster, mock_ep, mock_conn = self._validate_con_mocks('2.3.0') + provider = cluster.NSXRequestsHTTPProvider() + with mock.patch.object(client.JSONRESTClient, "get", + return_value={'application_status': 'DOWN'}): + self.assertRaises(nsxlib_exc.ResourceNotFound, + provider.validate_connection, + mock_cluster, mock_ep, mock_conn) + + with mock.patch.object(client.JSONRESTClient, "get", + return_value={'application_status': 'WORKING'}): + provider.validate_connection(mock_cluster, mock_ep, mock_conn) + + def test_validate_connection_method_v2(self): + mock_cluster, mock_ep, mock_conn = self._validate_con_mocks('2.4.0') + provider = cluster.NSXRequestsHTTPProvider() + with mock.patch.object(client.JSONRESTClient, "get", + return_value={'healthy': False}): + self.assertRaises(nsxlib_exc.ResourceNotFound, + provider.validate_connection, + mock_cluster, mock_ep, mock_conn) + + with mock.patch.object(client.JSONRESTClient, "get", + return_value={'healthy': True}): + provider.validate_connection(mock_cluster, mock_ep, mock_conn) + class NsxV3ClusteredAPITestCase(nsxlib_testcase.NsxClientTestCase): diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index ed488929..3c97805f 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -115,7 +115,8 @@ class NsxLib(lib.NsxLibBase): @property def validate_connection_method(self): """Return a method that will validate the NSX manager status""" - def check_manager_status(client, manager_url): + def check_manager_status_v1(client, manager_url): + """MP healthcheck for Version 2.3 and below""" # Try to get the cluster status silently and with no retries status = client.get('operational/application/status', silent=True, with_retries=False) @@ -125,6 +126,25 @@ class NsxLib(lib.NsxLibBase): raise exceptions.ResourceNotFound( manager=manager_url, operation=msg) + def check_manager_status_v2(client, manager_url): + """MP healthcheck for Version 2.4 and above""" + # Try to get the status silently and with no retries + status = client.get('reverse-proxy/node/health', + silent=True, with_retries=False) + if (not status or not status.get('healthy', False)): + msg = _("Manager is not in working state: %s") % status + LOG.warning(msg) + raise exceptions.ResourceNotFound( + manager=manager_url, operation=msg) + + def check_manager_status(client, manager_url): + # Decide on the healthcheck by the version (if already initialized) + if (self.nsx_version and + version.LooseVersion(self.nsx_version) >= + version.LooseVersion(nsx_constants.NSX_VERSION_2_4_0)): + return check_manager_status_v2(client, manager_url) + return check_manager_status_v1(client, manager_url) + return check_manager_status def get_version(self): diff --git a/vmware_nsxlib/v3/lib.py b/vmware_nsxlib/v3/lib.py index 073dbb36..7e8dfd89 100644 --- a/vmware_nsxlib/v3/lib.py +++ b/vmware_nsxlib/v3/lib.py @@ -31,6 +31,7 @@ LOG = log.getLogger(__name__) class NsxLibBase(object): def __init__(self, nsxlib_config): + self.nsx_version = None self.set_config(nsxlib_config) # create the Cluster @@ -47,7 +48,6 @@ class NsxLibBase(object): self.general_apis = utils.NsxLibApiBase( self.client, self.nsxlib_config) - self.nsx_version = None self.init_api() super(NsxLibBase, self).__init__()