Merge "Make sure endpoint validation is always performed"

This commit is contained in:
Zuul 2020-03-30 23:27:11 +00:00 committed by Gerrit Code Review
commit 235f626dbb
4 changed files with 28 additions and 20 deletions

View File

@ -199,7 +199,8 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
provider.validate_connection(mock_cluster, mock_ep, mock_conn)
mock_get.assert_not_called()
def _validate_con_mocks(self, nsx_version):
def _validate_con_mocks(self, nsx_version,
keepalive_section='transport-zones'):
nsxlib_config = nsxlib_testcase.get_default_nsxlib_config()
nsxlib = v3.NsxLib(nsxlib_config)
nsxlib.nsx_version = nsx_version
@ -209,7 +210,7 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
mock_ep.provider.url = 'https://1.2.3.4'
conf = mock.Mock()
conf.url_base = 'abc'
conf.keepalive_section = 'transport-zones'
conf.keepalive_section = keepalive_section
conf.validate_connection_method = nsxlib.validate_connection_method
mock_cluster = mock.Mock()
mock_cluster.nsxlib_config = conf

View File

@ -284,6 +284,12 @@ class NSX3Client(JSONRESTClient):
NSX_V1_API_PREFIX = 'api/v1/'
NSX_POLICY_V1_API_PREFIX = 'policy/api/v1/'
# NOTE: For user-facing client, NsxClusteredAPI instance
# will be passed as connection parameter below, thus all
# requests on this client will pass via cluster code to
# determine endpoint
# For validation client, TimeoutSession with specific
# endpoint parameters will be passed as connection.
def __init__(self, connection, url_prefix=None,
default_headers=None,
nsx_api_managers=None,

View File

@ -185,8 +185,8 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
return "%s-%s" % (requests.__title__, requests.__version__)
def validate_connection(self, cluster_api, endpoint, conn):
# We don't need to retry with different endpoint during validation,
# thus limit max_attempts to 1
# Retry during validation can cause retry storm, thus limit
# max_attempts to 1
# on connection level, validation will be retried according to
# nsxlib 'retries' and 'http_timeout' parameters.
client = nsx_client.NSX3Client(
@ -195,12 +195,9 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
default_headers=conn.default_headers,
max_attempts=1)
validation_done = False
# Check the manager state directly
if cluster_api.nsxlib_config.validate_connection_method:
cluster_api.nsxlib_config.validate_connection_method(
client, endpoint.provider.url)
validation_done = True
# If keeplive section returns a list, it is assumed to be non-empty
keepalive_section = cluster_api.nsxlib_config.keepalive_section
@ -210,7 +207,6 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
result = client.get(keepalive_section,
silent=True,
with_retries=False)
validation_done = True
if not result or result.get('result_count', 1) <= 0:
msg = _("No %(section)s found "
"for '%(url)s'") % {'section': keepalive_section,
@ -219,8 +215,6 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
raise exceptions.ResourceNotFound(
manager=endpoint.provider.url, operation=msg)
return validation_done
def new_connection(self, cluster_api, provider):
config = cluster_api.nsxlib_config
session = TimeoutSession(config.http_timeout,
@ -586,14 +580,10 @@ class ClusteredAPI(object):
try:
with endpoint.pool.item() as conn:
# with some configurations, validation will be skipped
result = self._http_provider.validate_connection(self,
endpoint,
conn)
if result or endpoint.state == EndpointState.INITIALIZED:
# If no endpoint validation is configured, we assume
# endpoint is UP on startup, but we shouldn't move it
# to UP from DOWN state
endpoint.set_state(EndpointState.UP)
self._http_provider.validate_connection(self,
endpoint,
conn)
endpoint.set_state(EndpointState.UP)
except exceptions.ClientCertificateNotTrusted:
LOG.warning("Failed to validate API cluster endpoint "
"'%(ep)s' due to untrusted client certificate",

View File

@ -138,8 +138,19 @@ class NsxPolicyLib(lib.NsxLibBase):
@property
def validate_connection_method(self):
# TODO(asarfaty): Find an equivalent api to check policy status
pass
"""Return a method that will validate the NSX policy status"""
def check_policy_status(client, url):
# Try to get the status silently and with no retries
infra = client.get('infra',
silent=True, with_retries=False)
if not infra or not infra.get('id'):
msg = _("Policy health check failed")
LOG.warning(msg)
raise exceptions.ResourceNotFound(
manager=url, operation=msg)
return check_policy_status
def get_version(self):
"""Get the NSX Policy manager version