Add option for retry number of connection attempts
This patch adds a new option (-r | --retries) to specify how many times the client should attempt to connect to the Neutron server when using idempotent methods (GET, PUT and DELETE). The patch also provides more user-friendly message when it's impossible to connect to Neutron server from CLI and ensures that connection-related exceptions are raised to the caller by default when neutronclient is used as a library. DocImpact Closes-Bug: #1312225 Change-Id: Id74d7cf9a0e8c5d2cd3ee4851c883d5286bea19d
This commit is contained in:
parent
b4f4544eaa
commit
65883ba4eb
neutronclient
@ -64,7 +64,9 @@ class ClientManager(object):
|
||||
ca_cert=None,
|
||||
log_credentials=False,
|
||||
service_type=None,
|
||||
timeout=None
|
||||
timeout=None,
|
||||
retries=0,
|
||||
raise_errors=True
|
||||
):
|
||||
self._token = token
|
||||
self._url = url
|
||||
@ -84,7 +86,8 @@ class ClientManager(object):
|
||||
self._ca_cert = ca_cert
|
||||
self._log_credentials = log_credentials
|
||||
self._timeout = timeout
|
||||
return
|
||||
self._retries = retries
|
||||
self._raise_errors = raise_errors
|
||||
|
||||
def initialize(self):
|
||||
if not self._url:
|
||||
|
@ -46,7 +46,9 @@ def make_client(instance):
|
||||
token=instance._token,
|
||||
auth_strategy=instance._auth_strategy,
|
||||
insecure=instance._insecure,
|
||||
ca_cert=instance._ca_cert)
|
||||
ca_cert=instance._ca_cert,
|
||||
retries=instance._retries,
|
||||
raise_errors=instance._raise_errors)
|
||||
return client
|
||||
else:
|
||||
raise exceptions.UnsupportedVersion(_("API version %s is not "
|
||||
|
@ -97,6 +97,17 @@ def env(*_vars, **kwargs):
|
||||
return kwargs.get('default', '')
|
||||
|
||||
|
||||
def check_non_negative_int(value):
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError(_("invalid int value: %r") % value)
|
||||
if value < 0:
|
||||
raise argparse.ArgumentTypeError(_("input value %d is negative") %
|
||||
value)
|
||||
return value
|
||||
|
||||
|
||||
COMMAND_V2 = {
|
||||
'net-list': network.ListNetwork,
|
||||
'net-external-list': network.ListExternalNetwork,
|
||||
@ -368,6 +379,13 @@ class NeutronShell(app.App):
|
||||
nargs=0,
|
||||
default=self, # tricky
|
||||
help=_("Show this help message and exit."))
|
||||
parser.add_argument(
|
||||
'-r', '--retries',
|
||||
metavar="NUM",
|
||||
type=check_non_negative_int,
|
||||
default=0,
|
||||
help=_("How many times the request to the Neutron server should "
|
||||
"be retried if it fails."))
|
||||
# Global arguments
|
||||
parser.add_argument(
|
||||
'--os-auth-strategy', metavar='<auth-strategy>',
|
||||
@ -650,6 +668,8 @@ class NeutronShell(app.App):
|
||||
insecure=self.options.insecure,
|
||||
ca_cert=self.options.os_cacert,
|
||||
timeout=self.options.timeout,
|
||||
retries=self.options.retries,
|
||||
raise_errors=False,
|
||||
log_credentials=True)
|
||||
return
|
||||
|
||||
|
@ -128,8 +128,8 @@ class ShellTest(testtools.TestCase):
|
||||
username='test', user_id='',
|
||||
password='test', region_name='', api_version={'network': '2.0'},
|
||||
auth_strategy='keystone', service_type='network',
|
||||
endpoint_type='publicURL', insecure=False, ca_cert=None,
|
||||
log_credentials=True, timeout=None)
|
||||
endpoint_type='publicURL', insecure=False, ca_cert=None, retries=0,
|
||||
raise_errors=False, log_credentials=True, timeout=None)
|
||||
neutron_shell.run_subcommand(['quota-list'])
|
||||
self.mox.ReplayAll()
|
||||
cmdline = ('--os-username test '
|
||||
|
@ -62,6 +62,8 @@ class TestSSL(testtools.TestCase):
|
||||
url=mox.IgnoreArg(),
|
||||
username=mox.IgnoreArg(),
|
||||
user_id=mox.IgnoreArg(),
|
||||
retries=mox.IgnoreArg(),
|
||||
raise_errors=mox.IgnoreArg(),
|
||||
log_credentials=mox.IgnoreArg(),
|
||||
timeout=mox.IgnoreArg(),
|
||||
)
|
||||
@ -94,6 +96,8 @@ class TestSSL(testtools.TestCase):
|
||||
url=mox.IgnoreArg(),
|
||||
username=mox.IgnoreArg(),
|
||||
user_id=mox.IgnoreArg(),
|
||||
retries=mox.IgnoreArg(),
|
||||
raise_errors=mox.IgnoreArg(),
|
||||
log_credentials=mox.IgnoreArg(),
|
||||
timeout=mox.IgnoreArg(),
|
||||
)
|
||||
@ -117,6 +121,8 @@ class TestSSL(testtools.TestCase):
|
||||
tenant_name=mox.IgnoreArg(),
|
||||
token=mox.IgnoreArg(),
|
||||
username=mox.IgnoreArg(),
|
||||
retries=mox.IgnoreArg(),
|
||||
raise_errors=mox.IgnoreArg(),
|
||||
)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
@ -129,6 +129,12 @@ class Client(object):
|
||||
http requests. (optional)
|
||||
:param bool insecure: SSL certificate validation. (optional)
|
||||
:param string ca_cert: SSL CA bundle file to use. (optional)
|
||||
:param integer retries: How many times idempotent (GET, PUT, DELETE)
|
||||
requests to Neutron server should be retried if
|
||||
they fail (default: 0).
|
||||
:param bool raise_errors: If True then exceptions caused by connection
|
||||
failure are propagated to the caller.
|
||||
(default: True)
|
||||
|
||||
Example::
|
||||
|
||||
@ -1194,7 +1200,8 @@ class Client(object):
|
||||
self.version = '2.0'
|
||||
self.format = 'json'
|
||||
self.action_prefix = "/v%s" % (self.version)
|
||||
self.retries = 0
|
||||
self.retries = kwargs.get('retries', 0)
|
||||
self.raise_errors = kwargs.get('raise_errors', True)
|
||||
self.retry_interval = 1
|
||||
|
||||
def _handle_fault_response(self, status_code, response_body):
|
||||
@ -1303,8 +1310,16 @@ class Client(object):
|
||||
if i < self.retries:
|
||||
_logger.debug('Retrying connection to Neutron service')
|
||||
time.sleep(self.retry_interval)
|
||||
elif self.raise_errors:
|
||||
raise
|
||||
|
||||
raise exceptions.ConnectionFailed(reason=_("Maximum attempts reached"))
|
||||
if self.retries:
|
||||
msg = (_("Failed to connect to Neutron server after %d attempts")
|
||||
% max_attempts)
|
||||
else:
|
||||
msg = _("Failed to connect Neutron server")
|
||||
|
||||
raise exceptions.ConnectionFailed(reason=msg)
|
||||
|
||||
def delete(self, action, body=None, headers=None, params=None):
|
||||
return self.retry_request("DELETE", action, body=body,
|
||||
|
Loading…
x
Reference in New Issue
Block a user