diff --git a/winrm/protocol.py b/winrm/protocol.py index a645e4d6..4f5a4449 100644 --- a/winrm/protocol.py +++ b/winrm/protocol.py @@ -26,6 +26,8 @@ class Protocol(object): DEFAULT_OPERATION_TIMEOUT_SEC = 20 DEFAULT_MAX_ENV_SIZE = 153600 DEFAULT_LOCALE = 'en-US' + DEFAULT_RECONNECTION_RETRIES = 5 + DEFAULT_RECONNECTION_SLEEP = 5 def __init__( self, endpoint, transport='plaintext', username=None, @@ -39,6 +41,8 @@ def __init__( message_encryption='auto', credssp_disable_tlsv1_2=False, send_cbt=True, + reconnection_retries = DEFAULT_RECONNECTION_RETRIES, + reconnection_sleep = DEFAULT_RECONNECTION_SLEEP, ): """ @param string endpoint: the WinRM webservice endpoint @@ -57,6 +61,8 @@ def __init__( @param int operation_timeout_sec: maximum allowed time in seconds for any single wsman HTTP operation (default 20). Note that operation timeouts while receiving output (the only wsman operation that should take any significant time, and where these timeouts are expected) will be silently retried indefinitely. # NOQA @param string kerberos_hostname_override: the hostname to use for the kerberos exchange (defaults to the hostname in the endpoint URL) @param bool message_encryption_enabled: Will encrypt the WinRM messages if set to True and the transport auth supports message encryption (Default True). + @param int reconnection_retries: Number of retries on Connection Refused + @param int reconnection_sleep: Number of seconds to sleep between reconnection attempts """ try: @@ -88,7 +94,9 @@ def __init__( auth_method=transport, message_encryption=message_encryption, credssp_disable_tlsv1_2=credssp_disable_tlsv1_2, - send_cbt=send_cbt + send_cbt=send_cbt, + reconnection_retries=reconnection_retries, + reconnection_sleep=reconnection_sleep, ) self.username = username @@ -100,6 +108,8 @@ def __init__( self.kerberos_delegation = kerberos_delegation self.kerberos_hostname_override = kerberos_hostname_override self.credssp_disable_tlsv1_2 = credssp_disable_tlsv1_2 + self.reconnection_retries = reconnection_retries + self.reconnection_sleep = reconnection_sleep def open_shell(self, i_stream='stdin', o_stream='stdout stderr', working_directory=None, env_vars=None, noprofile=False, diff --git a/winrm/transport.py b/winrm/transport.py index 9ca02d42..b67157f5 100644 --- a/winrm/transport.py +++ b/winrm/transport.py @@ -1,5 +1,4 @@ from __future__ import unicode_literals -import errno import inspect import os import sys @@ -64,7 +63,10 @@ def __init__( auth_method='auto', message_encryption='auto', credssp_disable_tlsv1_2=False, - send_cbt=True): + send_cbt=True, + reconnection_retries=5, + reconnection_sleep=5, + ): self.endpoint = endpoint self.username = username self.password = password @@ -80,6 +82,8 @@ def __init__( self.message_encryption = message_encryption self.credssp_disable_tlsv1_2 = credssp_disable_tlsv1_2 self.send_cbt = send_cbt + self.reconnection_retries = reconnection_retries + self.reconnection_sleep = reconnection_sleep if self.server_cert_validation not in [None, 'validate', 'ignore']: raise WinRMError('invalid server_cert_validation mode: %s' % self.server_cert_validation) @@ -115,7 +119,7 @@ def __init__( from requests.packages.urllib3.exceptions import InsecureRequestWarning warnings.simplefilter('ignore', category=InsecureRequestWarning) except: pass # oh well, we tried... - + try: from urllib3.exceptions import InsecureRequestWarning warnings.simplefilter('ignore', category=InsecureRequestWarning) @@ -264,14 +268,17 @@ def _send_message_request(self, prepared_request, message): try: # Retry connection on 'Connection refused' - for attempt in range(5): + for attempt in range(self.reconnection_retries): try: response = self.session.send(prepared_request, timeout=self.read_timeout_sec) + except requests.packages.urllib3.exceptions.NewConnectionError as e: + time.sleep(self.reconnection_sleep) +# except requests.exceptions.ConnectionError as e: +# if attempt == 4 or 'connection refused' not in str(e).lower(): +# raise +# time.sleep(self.reconnection_sleep) + else: break - except requests.exceptions.ConnectionError as e: - if attempt == 4 or 'connection refused' not in str(e).lower(): - raise - time.sleep(5) response.raise_for_status() return response @@ -283,7 +290,6 @@ def _send_message_request(self, prepared_request, message): else: response_text = '' - raise WinRMTransportError('http', ex.response.status_code, response_text) def _get_message_response_text(self, response):