From bc942953bc4a39c7696624dab6b59d06ad4f3298 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Wed, 21 Jun 2017 02:15:12 +0100 Subject: [PATCH] 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 --- ...properties-key-conflict-2161ca1faaad6731.yaml | 4 ++++ shade/_normalize.py | 9 ++++++++- shade/tests/unit/test_image.py | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/fix-properties-key-conflict-2161ca1faaad6731.yaml diff --git a/releasenotes/notes/fix-properties-key-conflict-2161ca1faaad6731.yaml b/releasenotes/notes/fix-properties-key-conflict-2161ca1faaad6731.yaml new file mode 100644 index 000000000..d681f93ca --- /dev/null +++ b/releasenotes/notes/fix-properties-key-conflict-2161ca1faaad6731.yaml @@ -0,0 +1,4 @@ +--- +issues: + - Images in the cloud with a string property named "properties" + caused image normalization to bomb. diff --git a/shade/_normalize.py b/shade/_normalize.py index 825a20d25..b8e242b56 100644 --- a/shade/_normalize.py +++ b/shade/_normalize.py @@ -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'] diff --git a/shade/tests/unit/test_image.py b/shade/tests/unit/test_image.py index 4d16fc01d..0b2032bce 100644 --- a/shade/tests/unit/test_image.py +++ b/shade/tests/unit/test_image.py @@ -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([