Add src parameter for uri module that can be used in place of body. Supports binary files (#33689)

* First pass at a src parameter that can be used in place of body. Supports binary files

* Add test for uri src body

* Bump version_added to 2.6

* Close the open file handle

* Add uri action plugin that handles src/remote_src

* Document remote_src

* Remove duplicate info about remote_src

* Bump version_added to 2.7
This commit is contained in:
Matt Martz 2018-05-31 11:43:00 -05:00 committed by GitHub
parent 0fd7d7500a
commit 961484e00d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 137 additions and 3 deletions

View file

@ -133,6 +133,17 @@ options:
client authentication. If I(client_cert) contains both the certificate
and key, this option is not required.
version_added: '2.4'
src:
description:
- Path to file to be submitted to the remote server. Cannot be used with I(body).
version_added: '2.7'
remote_src:
description:
- If C(no), the module will search for src on originating/master machine, if C(yes) the
module will use the C(src) path on the remote/target machine.
type: bool
default: 'no'
version_added: '2.7'
notes:
- The dependency on httplib2 was removed in Ansible 2.1.
- The module returns all the HTTP headers in lower-case.
@ -206,6 +217,19 @@ EXAMPLES = r'''
password: "{{ jenkins.password }}"
force_basic_auth: yes
status_code: 201
- name: POST from contents of local file
uri:
url: "https://httpbin.org/post"
method: POST
src: file.json
- name: POST from contents of remote file
uri:
url: "https://httpbin.org/post"
method: POST
src: /path/to/my/file.json
remote_src: true
'''
RETURN = r'''
@ -367,6 +391,19 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
redirected = False
redir_info = {}
r = {}
src = module.params['src']
if src:
try:
headers.update({
'Content-Length': os.stat(src).st_size
})
data = open(src, 'rb')
except OSError:
module.fail_json(msg='Unable to open source file %s' % src, exception=traceback.format_exc())
else:
data = body
if dest is not None:
# Stash follow_redirects, in this block we don't want to follow
# we'll reset back to the supplied value soon
@ -393,7 +430,7 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
# Reset follow_redirects back to the stashed value
module.params['follow_redirects'] = follow_redirects
resp, info = fetch_url(module, url, data=body, headers=headers,
resp, info = fetch_url(module, url, data=data, headers=headers,
method=method, timeout=socket_timeout)
try:
@ -403,6 +440,13 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
# may have been stored in the info as 'body'
content = info.pop('body', '')
if src:
# Try to close the open file handle
try:
data.close()
except Exception:
pass
r['redirected'] = redirected or info['url'] != url
r.update(redir_info)
r.update(info)
@ -418,6 +462,7 @@ def main():
url_password=dict(type='str', aliases=['password'], no_log=True),
body=dict(type='raw'),
body_format=dict(type='str', default='raw', choices=['form-urlencoded', 'json', 'raw']),
src=dict(type='path'),
method=dict(type='str', default='GET', choices=['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'PATCH', 'TRACE', 'CONNECT', 'REFRESH']),
return_content=dict(type='bool', default=False),
follow_redirects=dict(type='str', default='safe', choices=['all', 'no', 'none', 'safe', 'urllib2', 'yes']),
@ -432,7 +477,8 @@ def main():
argument_spec=argument_spec,
# TODO: Remove check_invalid_arguments in 2.9
check_invalid_arguments=False,
add_file_common_args=True
add_file_common_args=True,
mutually_exclusive=[['body', 'src']],
)
url = module.params['url']