Fix image normalization when image has properties property

In the somewhat pathological case of an image having a property named
properties already that contains a non-dict value, image normalizaiton
becomes quite unhappy. Fix it.

Change-Id: I2ce4dd4e3b7a4a9b46ff2bf699d2c8517e1ce7ce
Story: 2001073
Task: 4697
This commit is contained in:
Monty Taylor 2017-06-21 02:15:12 +01:00
parent 74522a1a22
commit bc942953bc
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
3 changed files with 28 additions and 1 deletions

View File

@ -0,0 +1,4 @@
---
issues:
- Images in the cloud with a string property named "properties"
caused image normalization to bomb.

View File

@ -268,7 +268,13 @@ class Normalizer(object):
# Discard noise
self._remove_novaclient_artifacts(image)
# If someone made a property called "properties" that contains a
# string (this has happened at least one time in the wild), the
# the rest of the normalization here goes belly up.
properties = image.pop('properties', {})
if not isinstance(properties, dict):
properties = {'properties': properties}
visibility = image.pop('visibility', None)
protected = _to_bool(image.pop('protected', False))
@ -318,7 +324,8 @@ class Normalizer(object):
# Backwards compat with glance
if not self.strict_mode:
for key, val in properties.items():
new_image[key] = val
if key != 'properties':
new_image[key] = val
new_image['protected'] = protected
new_image['metadata'] = properties
new_image['created'] = new_image['created_at']

View File

@ -136,6 +136,22 @@ class TestImage(BaseTestImage):
self.cloud.list_images())
self.assert_calls()
def test_list_images_string_properties(self):
image_dict = self.fake_image_dict.copy()
image_dict['properties'] = 'list,of,properties'
self.register_uris([
dict(method='GET', uri='https://image.example.com/v2/images',
json={'images': [image_dict]}),
])
images = self.cloud.list_images()
self.assertEqual(
self.cloud._normalize_images([image_dict]),
images)
self.assertEqual(
images[0]['properties']['properties'],
'list,of,properties')
self.assert_calls()
def test_list_images_paginated(self):
marker = str(uuid.uuid4())
self.register_uris([