Add socket timeout to uri module.
The uri module can be configured to abort after a specified timeout if it cannot connect to the configured uri. This prevents a uri action from hanging indefinitely when the remote endpoint cannot be reached because it is unavailable, there is a firewall in place etc. The default behavior is left unchanged: timeout=None This change also introduces a new type for module_parameters: int Code was added to perform conversion from string -> int type in module_common.py. The new type was required in order to play nice with httplib2 which refuses to accept (and convert) anything other than a numeric type for the timeout value.
This commit is contained in:
parent
b130716b61
commit
cd51c7f234
2 changed files with 16 additions and 3 deletions
|
@ -597,6 +597,12 @@ class AnsibleModule(object):
|
||||||
self.params[k] = self.boolean(value)
|
self.params[k] = self.boolean(value)
|
||||||
else:
|
else:
|
||||||
is_invalid = True
|
is_invalid = True
|
||||||
|
elif wanted == 'int':
|
||||||
|
if not isinstance(value, int):
|
||||||
|
if isinstance(value, basestring):
|
||||||
|
self.params[k] = int(value)
|
||||||
|
else:
|
||||||
|
is_invalid = True
|
||||||
else:
|
else:
|
||||||
self.fail_json(msg="implementation error: unknown type %s requested for %s" % (wanted, k))
|
self.fail_json(msg="implementation error: unknown type %s requested for %s" % (wanted, k))
|
||||||
|
|
||||||
|
|
13
library/uri
13
library/uri
|
@ -103,6 +103,11 @@ options:
|
||||||
- A valid, numeric, HTTP status code that signifies success of the request.
|
- A valid, numeric, HTTP status code that signifies success of the request.
|
||||||
required: false
|
required: false
|
||||||
default: 200
|
default: 200
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- The socket level timeout in seconds
|
||||||
|
required: false
|
||||||
|
default: no timeout
|
||||||
HEADER_:
|
HEADER_:
|
||||||
description: Any parameter starting with "HEADER_" is a sent with your request as a header. For example, HEADER_Content-Type="application/json" would send the header "Content-Type" along with your request with a value of "application/json".
|
description: Any parameter starting with "HEADER_" is a sent with your request as a header. For example, HEADER_Content-Type="application/json" would send the header "Content-Type" along with your request with a value of "application/json".
|
||||||
required: false
|
required: false
|
||||||
|
@ -217,12 +222,12 @@ def url_filename(url):
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
|
||||||
def uri(module, url, dest, user, password, body, method, headers, redirects):
|
def uri(module, url, dest, user, password, body, method, headers, redirects, socket_timeout):
|
||||||
# To debug
|
# To debug
|
||||||
#httplib2.debug = 4
|
#httplib2.debug = 4
|
||||||
|
|
||||||
# Create a Http object and set some default options.
|
# Create a Http object and set some default options.
|
||||||
h = httplib2.Http(disable_ssl_certificate_validation=True)
|
h = httplib2.Http(disable_ssl_certificate_validation=True, timeout=socket_timeout)
|
||||||
h.follow_all_redirects = redirects
|
h.follow_all_redirects = redirects
|
||||||
h.forward_authorization_headers = True
|
h.forward_authorization_headers = True
|
||||||
|
|
||||||
|
@ -273,6 +278,7 @@ def main():
|
||||||
creates = dict(required=False, default=None),
|
creates = dict(required=False, default=None),
|
||||||
removes = dict(required=False, default=None),
|
removes = dict(required=False, default=None),
|
||||||
status_code = dict(required=False, default="200"),
|
status_code = dict(required=False, default="200"),
|
||||||
|
timeout = dict(required=False, default=None, type='int'),
|
||||||
),
|
),
|
||||||
check_invalid_arguments=False,
|
check_invalid_arguments=False,
|
||||||
add_file_common_args=True
|
add_file_common_args=True
|
||||||
|
@ -295,6 +301,7 @@ def main():
|
||||||
creates = module.params['creates']
|
creates = module.params['creates']
|
||||||
removes = module.params['removes']
|
removes = module.params['removes']
|
||||||
status_code = module.params['status_code']
|
status_code = module.params['status_code']
|
||||||
|
socket_timeout = module.params['timeout']
|
||||||
|
|
||||||
# Grab all the http headers. Need this hack since passing multi-values is currently a bit ugly. (e.g. headers='{"Content-Type":"application/json"}')
|
# Grab all the http headers. Need this hack since passing multi-values is currently a bit ugly. (e.g. headers='{"Content-Type":"application/json"}')
|
||||||
dict_headers = {}
|
dict_headers = {}
|
||||||
|
@ -340,7 +347,7 @@ def main():
|
||||||
dest = os.path.join(dest, url_filename(url))
|
dest = os.path.join(dest, url_filename(url))
|
||||||
|
|
||||||
# Make the request
|
# Make the request
|
||||||
resp, content = uri(module, url, dest, user, password, body, method, dict_headers, redirects)
|
resp, content = uri(module, url, dest, user, password, body, method, dict_headers, redirects, socket_timeout)
|
||||||
|
|
||||||
# Write the file out if requested
|
# Write the file out if requested
|
||||||
if dest is not None:
|
if dest is not None:
|
||||||
|
|
Loading…
Reference in a new issue