* Added a sha256 method to module_common
* Added a sha256sum parameter to the get_url module to enable cryptographic verification of downloaded files * Fixed a few typos in the documentation
This commit is contained in:
parent
0b6570eef8
commit
2ce7f136b2
2 changed files with 58 additions and 12 deletions
|
@ -86,11 +86,18 @@ try:
|
|||
except ImportError:
|
||||
pass
|
||||
|
||||
HAVE_HASHLIB=False
|
||||
try:
|
||||
from hashlib import md5 as _md5
|
||||
HAVE_HASHLIB=True
|
||||
except ImportError:
|
||||
from md5 import md5 as _md5
|
||||
|
||||
try:
|
||||
from hashlib import sha256 as _sha256
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from systemd import journal
|
||||
has_journal = True
|
||||
|
@ -787,13 +794,13 @@ class AnsibleModule(object):
|
|||
or stat.S_IXGRP & os.stat(path)[stat.ST_MODE]
|
||||
or stat.S_IXOTH & os.stat(path)[stat.ST_MODE])
|
||||
|
||||
def md5(self, filename):
|
||||
''' Return MD5 hex digest of local file, or None if file is not present. '''
|
||||
def digest_from_file(self, filename, digest_method):
|
||||
''' Return hex digest of local file for a given digest_method, or None if file is not present. '''
|
||||
if not os.path.exists(filename):
|
||||
return None
|
||||
if os.path.isdir(filename):
|
||||
self.fail_json(msg="attempted to take md5sum of directory: %s" % filename)
|
||||
digest = _md5()
|
||||
self.fail_json(msg="attempted to take checksum of directory: %s" % filename)
|
||||
digest = digest_method
|
||||
blocksize = 64 * 1024
|
||||
infile = open(filename, 'rb')
|
||||
block = infile.read(blocksize)
|
||||
|
@ -803,6 +810,16 @@ class AnsibleModule(object):
|
|||
infile.close()
|
||||
return digest.hexdigest()
|
||||
|
||||
def md5(self, filename):
|
||||
''' Return MD5 hex digest of local file using digest_from_file(). '''
|
||||
return self.digest_from_file(filename, _md5())
|
||||
|
||||
def sha256(self, filename):
|
||||
''' Return SHA-256 hex digest of local file using digest_from_file(). '''
|
||||
if not HAVE_HASHLIB:
|
||||
self.fail_json(msg="SHA-256 checksums require hashlib, which is available in Python 2.5 and higher")
|
||||
return self.digest_from_file(filename, _sha256())
|
||||
|
||||
def backup_local(self, fn):
|
||||
'''make a date-marked backup of the specified file, return True or False on success or failure'''
|
||||
# backups named basename-YYYY-MM-DD@HH:MM~
|
||||
|
|
|
@ -33,7 +33,7 @@ description:
|
|||
server I(must) have direct access to the remote resource.
|
||||
- By default, if an environment variable C(<protocol>_proxy) is set on
|
||||
the target host, requests will be sent through that proxy. This
|
||||
behaviour can be overriden by setting a variable for this task
|
||||
behaviour can be overridden by setting a variable for this task
|
||||
(see `setting the environment
|
||||
<http://ansible.cc/docs/playbooks2.html#setting-the-environment-and-working-with-proxies>`_),
|
||||
or by using the use_proxy option.
|
||||
|
@ -53,19 +53,26 @@ options:
|
|||
default: null
|
||||
force:
|
||||
description:
|
||||
- if C(yes), will download the file every time and replace the
|
||||
- If C(yes), will download the file every time and replace the
|
||||
file if the contents change. If C(no), the file will only be downloaded if
|
||||
the destination does not exist. Generally should be C(yes) only for small
|
||||
local files. prior to 0.6, acts if C(yes) by default.
|
||||
local files. Prior to 0.6, this module behaved as if C(yes) was the default.
|
||||
version_added: "0.7"
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
aliases: [ "thirsty" ]
|
||||
sha256sum:
|
||||
description:
|
||||
- If a SHA-256 checksum is passed to this parameter, the digest of the
|
||||
destination file will be calculated after it is downloaded to ensure
|
||||
its integrity and verify that the transfer completed successfully.
|
||||
required: false
|
||||
default: null
|
||||
use_proxy:
|
||||
description:
|
||||
- if C(no), it will not use a proxy, even if one is defined by
|
||||
in an environment variable on the target hosts.
|
||||
- if C(no), it will not use a proxy, even if one is defined in
|
||||
an environment variable on the target hosts.
|
||||
required: false
|
||||
default: 'yes'
|
||||
choices: ['yes', 'no']
|
||||
|
@ -81,20 +88,30 @@ author: Jan-Piet Mens
|
|||
'''
|
||||
|
||||
EXAMPLES='''
|
||||
# Download file.conf to /etc/foo.conf with read permissions set for the user and group
|
||||
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440
|
||||
|
||||
# Download file.conf to /etc/foo.conf and ensure that it matches the specified SHA-256 checksum
|
||||
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
|
||||
'''
|
||||
|
||||
|
||||
HAS_URLLIB2 = True
|
||||
try:
|
||||
import hashlib
|
||||
HAS_HASHLIB=True
|
||||
except ImportError:
|
||||
HAS_HASHLIB=False
|
||||
|
||||
try:
|
||||
import urllib2
|
||||
HAS_URLLIB2 = True
|
||||
except ImportError:
|
||||
HAS_URLLIB2 = False
|
||||
HAS_URLPARSE = True
|
||||
|
||||
try:
|
||||
import urlparse
|
||||
import socket
|
||||
HAS_URLPARSE = True
|
||||
except ImportError:
|
||||
HAS_URLPARSE=False
|
||||
|
||||
|
@ -217,6 +234,7 @@ def main():
|
|||
url = dict(required=True),
|
||||
dest = dict(required=True),
|
||||
force = dict(default='no', aliases=['thirsty'], type='bool'),
|
||||
sha256sum = dict(default=''),
|
||||
use_proxy = dict(default='yes', type='bool')
|
||||
),
|
||||
add_file_common_args=True
|
||||
|
@ -225,6 +243,7 @@ def main():
|
|||
url = module.params['url']
|
||||
dest = os.path.expanduser(module.params['dest'])
|
||||
force = module.params['force']
|
||||
sha256sum = module.params['sha256sum']
|
||||
use_proxy = module.params['use_proxy']
|
||||
|
||||
if os.path.isdir(dest):
|
||||
|
@ -273,6 +292,16 @@ def main():
|
|||
else:
|
||||
changed = False
|
||||
|
||||
# Check the digest of the destination file and ensure that it matches the
|
||||
# sha256sum parameter if it is present
|
||||
if sha256sum != '':
|
||||
if not HAS_HASHLIB:
|
||||
os.remove(dest)
|
||||
module.fail_json(msg="The sha256sum parameter requires hashlib, which is available in Python 2.5 and higher")
|
||||
if sha256sum != module.sha256(dest):
|
||||
os.remove(dest)
|
||||
module.fail_json(msg="The SHA-256 checksum for %s did not match %s" % (dest, sha256sum))
|
||||
|
||||
os.remove(tmpsrc)
|
||||
|
||||
# allow file attribute changes
|
||||
|
@ -283,7 +312,7 @@ def main():
|
|||
|
||||
# Mission complete
|
||||
module.exit_json(url=url, dest=dest, src=tmpsrc, md5sum=md5sum_src,
|
||||
changed=changed, msg=info.get('msg', ''))
|
||||
sha256sum=sha256sum, changed=changed, msg=info.get('msg', ''))
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
|
||||
|
|
Loading…
Reference in a new issue