Merge "Changing MD5 hash to SHA512"
This commit is contained in:
commit
d4ddf39183
|
@ -277,3 +277,5 @@ UPDATE_NO = _('User did not confirm update, so exiting. '
|
|||
|
||||
DEFAULT_PARTITION_IMAGE = 'overcloud-full.qcow2'
|
||||
DEFAULT_WHOLE_DISK_IMAGE = 'overcloud-hardened-uefi-full.qcow2'
|
||||
|
||||
FIPS_COMPLIANT_HASHES = {'sha1', 'sha224', 'sha256', 'sha384', 'sha512'}
|
||||
|
|
|
@ -958,8 +958,13 @@ class TestWaitForStackUtil(TestCase):
|
|||
def test_empty_file_checksum(self):
|
||||
# Used a NamedTemporaryFile since it's deleted when the file is closed.
|
||||
with tempfile.NamedTemporaryFile() as empty_temp_file:
|
||||
self.assertEqual(utils.file_checksum(empty_temp_file.name),
|
||||
'd41d8cd98f00b204e9800998ecf8427e')
|
||||
self.assertEqual(
|
||||
utils.file_checksum(empty_temp_file.name),
|
||||
(
|
||||
'cf83e1357eefb8bdf1542850d66d8007'
|
||||
'd620e4050b5715dc83f4a921d36ce9ce47'
|
||||
'd0d13c5d85f2b0ff8318d2877eec2f63b'
|
||||
'931bd47417a81a538327af927da3e'))
|
||||
|
||||
def test_non_empty_file_checksum(self):
|
||||
# Used a NamedTemporaryFile since it's deleted when the file is closed.
|
||||
|
@ -967,8 +972,39 @@ class TestWaitForStackUtil(TestCase):
|
|||
temp_file.write(b'foo')
|
||||
temp_file.flush()
|
||||
|
||||
self.assertEqual(utils.file_checksum(temp_file.name),
|
||||
'acbd18db4cc2f85cedef654fccc4a4d8')
|
||||
self.assertEqual(
|
||||
utils.file_checksum(temp_file.name),
|
||||
(
|
||||
'f7fbba6e0636f890e56fbbf3283e52'
|
||||
'4c6fa3204ae298382d624741d0dc663'
|
||||
'8326e282c41be5e4254d8820772c55'
|
||||
'18a2c5a8c0c7f7eda19594a7eb539453e1ed7'))
|
||||
|
||||
def test_non_empty_file_checksum_SHA256(self):
|
||||
"""Test 'file_checksum' function with an alternative algorithm.
|
||||
"""
|
||||
# Used a NamedTemporaryFile since it's deleted when the file is closed.
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
temp_file.write(b'foo')
|
||||
temp_file.flush()
|
||||
|
||||
self.assertEqual(
|
||||
utils.file_checksum(temp_file.name, 'sha256'),
|
||||
(
|
||||
'2c26b46b68ffc68ff99b453c1d304134'
|
||||
'13422d706483bfa0f98a5e886266e7ae'))
|
||||
|
||||
def test_non_empty_file_checksum_non_compliant(self):
|
||||
"""Test 'file_checksum' function with an alternative algorithm
|
||||
that isn't permitted by the FIPS.
|
||||
"""
|
||||
# Used a NamedTemporaryFile since it's deleted when the file is closed.
|
||||
with tempfile.NamedTemporaryFile() as temp_file:
|
||||
temp_file.write(b'foo')
|
||||
temp_file.flush()
|
||||
|
||||
self.assertRaises(RuntimeError, utils.file_checksum,
|
||||
temp_file.name, 'md5')
|
||||
|
||||
def test_shouldnt_checksum_open_special_files(self):
|
||||
self.assertRaises(ValueError, utils.file_checksum, '/dev/random')
|
||||
|
|
|
@ -1255,17 +1255,29 @@ def remove_known_hosts(overcloud_ip):
|
|||
subprocess.check_call(command)
|
||||
|
||||
|
||||
def file_checksum(filepath):
|
||||
"""Calculate md5 checksum on file
|
||||
|
||||
def file_checksum(filepath, hash_algo='sha512'):
|
||||
"""Calculate sha512 checksum on file
|
||||
:param filepath: Full path to file (e.g. /home/stack/image.qcow2)
|
||||
:type filepath: string
|
||||
:param hash_algo: name of the hash algorithm, 'sha512' by default
|
||||
:type hash_algo: string
|
||||
|
||||
:returns: hexadecimal hash of the file
|
||||
|
||||
:raises:
|
||||
RuntimeError if the 'hash_algo' value isn't supported.
|
||||
ValueError if the path isn't pointing to a regular file.
|
||||
"""
|
||||
if not os.path.isfile(filepath):
|
||||
raise ValueError(_("The given file {0} is not a regular "
|
||||
"file").format(filepath))
|
||||
checksum = hashlib.md5()
|
||||
|
||||
if hash_algo not in constants.FIPS_COMPLIANT_HASHES:
|
||||
raise RuntimeError(
|
||||
"The requested hash algorithm (%s) is not supported." % hash_algo)
|
||||
|
||||
checksum = hashlib.new(hash_algo)
|
||||
|
||||
with open(filepath, 'rb') as f:
|
||||
while True:
|
||||
fragment = f.read(65536)
|
||||
|
|
|
@ -314,12 +314,34 @@ class GlanceClientAdapter(BaseClientAdapter):
|
|||
print(table, file=sys.stdout)
|
||||
|
||||
def _get_image(self, name):
|
||||
"""Retrieves 'openstack.image.v2.image.Image' object.
|
||||
Uses 'openstack.image.v2._proxy.Proxy.find_image' method.
|
||||
|
||||
:param name: name or ID of an image
|
||||
:type name: `string`
|
||||
|
||||
:returns: Requested image object if one exists, otherwise `None`
|
||||
:rtype: `openstack.image.v2.image.Image` or `NoneType`
|
||||
"""
|
||||
# This would return None by default for an non-existent resorurce
|
||||
# And DuplicateResource exception if there more than one.
|
||||
return self.client.find_image(name)
|
||||
|
||||
def _image_changed(self, image, filename):
|
||||
return image.checksum != plugin_utils.file_checksum(filename)
|
||||
"""Compare the precomputed hash value with the one derived here.
|
||||
:param image: Image resource
|
||||
:type image: `openstack.image.v2.image.Image`
|
||||
:param filename: path to the image file
|
||||
:type filname: `string`
|
||||
|
||||
:returns: True if image hashes don't match, false otherwise
|
||||
:rtype: `bool`
|
||||
"""
|
||||
if not hasattr(image, 'hash_value'):
|
||||
raise RuntimeError(
|
||||
("The supplied image does not have a hash value set."))
|
||||
return image.hash_value != plugin_utils.file_checksum(
|
||||
filename, image.hash_algo)
|
||||
|
||||
def _image_try_update(self, image_name, image_file):
|
||||
image = self._get_image(image_name)
|
||||
|
|
Loading…
Reference in New Issue