Merge "Make sure endpoint validation is always performed"
This commit is contained in:
commit
235f626dbb
@ -199,7 +199,8 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
|||||||
provider.validate_connection(mock_cluster, mock_ep, mock_conn)
|
provider.validate_connection(mock_cluster, mock_ep, mock_conn)
|
||||||
mock_get.assert_not_called()
|
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_config = nsxlib_testcase.get_default_nsxlib_config()
|
||||||
nsxlib = v3.NsxLib(nsxlib_config)
|
nsxlib = v3.NsxLib(nsxlib_config)
|
||||||
nsxlib.nsx_version = nsx_version
|
nsxlib.nsx_version = nsx_version
|
||||||
@ -209,7 +210,7 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
|||||||
mock_ep.provider.url = 'https://1.2.3.4'
|
mock_ep.provider.url = 'https://1.2.3.4'
|
||||||
conf = mock.Mock()
|
conf = mock.Mock()
|
||||||
conf.url_base = 'abc'
|
conf.url_base = 'abc'
|
||||||
conf.keepalive_section = 'transport-zones'
|
conf.keepalive_section = keepalive_section
|
||||||
conf.validate_connection_method = nsxlib.validate_connection_method
|
conf.validate_connection_method = nsxlib.validate_connection_method
|
||||||
mock_cluster = mock.Mock()
|
mock_cluster = mock.Mock()
|
||||||
mock_cluster.nsxlib_config = conf
|
mock_cluster.nsxlib_config = conf
|
||||||
|
@ -284,6 +284,12 @@ class NSX3Client(JSONRESTClient):
|
|||||||
NSX_V1_API_PREFIX = 'api/v1/'
|
NSX_V1_API_PREFIX = 'api/v1/'
|
||||||
NSX_POLICY_V1_API_PREFIX = 'policy/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,
|
def __init__(self, connection, url_prefix=None,
|
||||||
default_headers=None,
|
default_headers=None,
|
||||||
nsx_api_managers=None,
|
nsx_api_managers=None,
|
||||||
|
@ -185,8 +185,8 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||||||
return "%s-%s" % (requests.__title__, requests.__version__)
|
return "%s-%s" % (requests.__title__, requests.__version__)
|
||||||
|
|
||||||
def validate_connection(self, cluster_api, endpoint, conn):
|
def validate_connection(self, cluster_api, endpoint, conn):
|
||||||
# We don't need to retry with different endpoint during validation,
|
# Retry during validation can cause retry storm, thus limit
|
||||||
# thus limit max_attempts to 1
|
# max_attempts to 1
|
||||||
# on connection level, validation will be retried according to
|
# on connection level, validation will be retried according to
|
||||||
# nsxlib 'retries' and 'http_timeout' parameters.
|
# nsxlib 'retries' and 'http_timeout' parameters.
|
||||||
client = nsx_client.NSX3Client(
|
client = nsx_client.NSX3Client(
|
||||||
@ -195,12 +195,9 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||||||
default_headers=conn.default_headers,
|
default_headers=conn.default_headers,
|
||||||
max_attempts=1)
|
max_attempts=1)
|
||||||
|
|
||||||
validation_done = False
|
|
||||||
# Check the manager state directly
|
|
||||||
if cluster_api.nsxlib_config.validate_connection_method:
|
if cluster_api.nsxlib_config.validate_connection_method:
|
||||||
cluster_api.nsxlib_config.validate_connection_method(
|
cluster_api.nsxlib_config.validate_connection_method(
|
||||||
client, endpoint.provider.url)
|
client, endpoint.provider.url)
|
||||||
validation_done = True
|
|
||||||
|
|
||||||
# If keeplive section returns a list, it is assumed to be non-empty
|
# If keeplive section returns a list, it is assumed to be non-empty
|
||||||
keepalive_section = cluster_api.nsxlib_config.keepalive_section
|
keepalive_section = cluster_api.nsxlib_config.keepalive_section
|
||||||
@ -210,7 +207,6 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||||||
result = client.get(keepalive_section,
|
result = client.get(keepalive_section,
|
||||||
silent=True,
|
silent=True,
|
||||||
with_retries=False)
|
with_retries=False)
|
||||||
validation_done = True
|
|
||||||
if not result or result.get('result_count', 1) <= 0:
|
if not result or result.get('result_count', 1) <= 0:
|
||||||
msg = _("No %(section)s found "
|
msg = _("No %(section)s found "
|
||||||
"for '%(url)s'") % {'section': keepalive_section,
|
"for '%(url)s'") % {'section': keepalive_section,
|
||||||
@ -219,8 +215,6 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||||||
raise exceptions.ResourceNotFound(
|
raise exceptions.ResourceNotFound(
|
||||||
manager=endpoint.provider.url, operation=msg)
|
manager=endpoint.provider.url, operation=msg)
|
||||||
|
|
||||||
return validation_done
|
|
||||||
|
|
||||||
def new_connection(self, cluster_api, provider):
|
def new_connection(self, cluster_api, provider):
|
||||||
config = cluster_api.nsxlib_config
|
config = cluster_api.nsxlib_config
|
||||||
session = TimeoutSession(config.http_timeout,
|
session = TimeoutSession(config.http_timeout,
|
||||||
@ -586,13 +580,9 @@ class ClusteredAPI(object):
|
|||||||
try:
|
try:
|
||||||
with endpoint.pool.item() as conn:
|
with endpoint.pool.item() as conn:
|
||||||
# with some configurations, validation will be skipped
|
# with some configurations, validation will be skipped
|
||||||
result = self._http_provider.validate_connection(self,
|
self._http_provider.validate_connection(self,
|
||||||
endpoint,
|
endpoint,
|
||||||
conn)
|
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)
|
endpoint.set_state(EndpointState.UP)
|
||||||
except exceptions.ClientCertificateNotTrusted:
|
except exceptions.ClientCertificateNotTrusted:
|
||||||
LOG.warning("Failed to validate API cluster endpoint "
|
LOG.warning("Failed to validate API cluster endpoint "
|
||||||
|
@ -138,8 +138,19 @@ class NsxPolicyLib(lib.NsxLibBase):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def validate_connection_method(self):
|
def validate_connection_method(self):
|
||||||
# TODO(asarfaty): Find an equivalent api to check policy status
|
"""Return a method that will validate the NSX policy status"""
|
||||||
pass
|
|
||||||
|
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):
|
def get_version(self):
|
||||||
"""Get the NSX Policy manager version
|
"""Get the NSX Policy manager version
|
||||||
|
Loading…
x
Reference in New Issue
Block a user