From f8f6bf2a57dcf144a3360b9085d970b62372c06a Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Tue, 30 Oct 2012 21:50:00 +0100 Subject: [PATCH] Handle list properties that do not contain objects The previous implementation of schema verfication on properties required that the schema for the contents of a property list always be a map. Now this is specified explicitly, so that in theory a property could also be a list of Strings or Integers. Change-Id: Icdd9a6c9f9b1e884f959c74f0803b7f3bd2aecc4 Signed-off-by: Zane Bitter --- heat/engine/resources/autoscaling.py | 7 ++++--- heat/engine/resources/instance.py | 8 ++++++-- heat/engine/resources/loadbalancer.py | 3 ++- heat/engine/resources/properties.py | 2 +- heat/engine/resources/quantum/port.py | 3 ++- heat/engine/resources/quantum/subnet.py | 5 ++++- heat/tests/test_properties.py | 16 ++++++++++++++-- 7 files changed, 33 insertions(+), 11 deletions(-) diff --git a/heat/engine/resources/autoscaling.py b/heat/engine/resources/autoscaling.py index a5161a88..40c79189 100644 --- a/heat/engine/resources/autoscaling.py +++ b/heat/engine/resources/autoscaling.py @@ -43,8 +43,8 @@ class AutoScalingGroup(resource.Resource): 'AllowedValues': ['EC2', 'ELB'], 'Implemented': False}, 'LoadBalancerNames': {'Type': 'List'}, - 'Tags': {'Type': 'List', - 'Schema': tags_schema} + 'Tags': {'Type': 'List', 'Schema': {'Type': 'Map', + 'Schema': tags_schema}} } def __init__(self, name, json_snippet, stack): @@ -163,7 +163,8 @@ class LaunchConfiguration(resource.Resource): 'BlockDeviceMappings': {'Type': 'String', 'Implemented': False}, 'NovaSchedulerHints': {'Type': 'List', - 'Schema': tags_schema}, + 'Schema': {'Type': 'Map', + 'Schema': tags_schema}}, } def __init__(self, name, json_snippet, stack): diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index c6697a86..6f9f2264 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -94,9 +94,13 @@ class Instance(resource.Resource): 'SubnetId': {'Type': 'String', 'Implemented': False}, 'Tags': {'Type': 'List', - 'Schema': tags_schema}, + 'Schema': {'Type': 'Map', + 'Schema': tags_schema}}, 'NovaSchedulerHints': {'Type': 'List', - 'Schema': tags_schema}, + 'Schema': { + 'Type': 'Map', + 'Schema': tags_schema + }}, 'Tenancy': {'Type': 'String', 'AllowedValues': ['dedicated', 'default'], 'Implemented': False}, diff --git a/heat/engine/resources/loadbalancer.py b/heat/engine/resources/loadbalancer.py index 4e955cef..534f1f1e 100644 --- a/heat/engine/resources/loadbalancer.py +++ b/heat/engine/resources/loadbalancer.py @@ -192,7 +192,8 @@ class LoadBalancer(stack.Stack): 'Schema': healthcheck_schema}, 'Instances': {'Type': 'List'}, 'Listeners': {'Type': 'List', - 'Schema': listeners_schema}, + 'Schema': {'Type': 'Map', + 'Schema': listeners_schema}}, 'AppCookieStickinessPolicy': {'Type': 'String', 'Implemented': False}, 'LBCookieStickinessPolicy': {'Type': 'String', diff --git a/heat/engine/resources/properties.py b/heat/engine/resources/properties.py index dfd912ec..3ef80e4b 100644 --- a/heat/engine/resources/properties.py +++ b/heat/engine/resources/properties.py @@ -110,7 +110,7 @@ class Property(object): self._check_allowed(v) if SCHEMA in self.schema: - prop = Property({TYPE: MAP, SCHEMA: self.schema[SCHEMA]}) + prop = Property(self.schema[SCHEMA]) children = [prop.validate_data(d) for d in value] else: children = value diff --git a/heat/engine/resources/quantum/port.py b/heat/engine/resources/quantum/port.py index 939040f9..d12e6755 100644 --- a/heat/engine/resources/quantum/port.py +++ b/heat/engine/resources/quantum/port.py @@ -33,7 +33,8 @@ class Port(quantum.QuantumResource): 'Default': {}}, 'admin_state_up': {'Default': True}, 'fixed_ips': {'Type': 'List', - 'Schema': fixed_ip_schema}, + 'Schema': {'Type': 'Map', + 'Schema': fixed_ip_schema}}, 'mac_address': {'Type': 'String'}, 'device_id': {'Type': 'String'}, } diff --git a/heat/engine/resources/quantum/subnet.py b/heat/engine/resources/quantum/subnet.py index 90c6a02b..83f4be3b 100644 --- a/heat/engine/resources/quantum/subnet.py +++ b/heat/engine/resources/quantum/subnet.py @@ -41,7 +41,10 @@ class Subnet(quantum.QuantumResource): 'Default': 4}, 'gateway_ip': {'Type': 'String'}, 'allocation_pools': {'Type': 'List', - 'Schema': allocation_schema} + 'Schema': { + 'Type': 'Map', + 'Schema': allocation_schema + }} } def __init__(self, name, json_snippet, stack): diff --git a/heat/tests/test_properties.py b/heat/tests/test_properties.py index 361b977a..564c73a8 100644 --- a/heat/tests/test_properties.py +++ b/heat/tests/test_properties.py @@ -231,7 +231,8 @@ class PropertyTest(unittest.TestCase): def test_list_schema_good(self): map_schema = {'valid': {'Type': 'Boolean'}} - p = properties.Property({'Type': 'List', 'Schema': map_schema}) + list_schema = {'Type': 'Map', 'Schema': map_schema} + p = properties.Property({'Type': 'List', 'Schema': list_schema}) self.assertEqual(p.validate_data([{'valid': 'TRUE'}, {'valid': 'False'}]), [{'valid': 'true'}, @@ -239,10 +240,21 @@ class PropertyTest(unittest.TestCase): def test_list_schema_bad_data(self): map_schema = {'valid': {'Type': 'Boolean'}} - p = properties.Property({'Type': 'List', 'Schema': map_schema}) + list_schema = {'Type': 'Map', 'Schema': map_schema} + p = properties.Property({'Type': 'List', 'Schema': list_schema}) self.assertRaises(ValueError, p.validate_data, [{'valid': 'True'}, {'valid': 'fish'}]) + def test_list_schema_int_good(self): + list_schema = {'Type': 'Integer'} + p = properties.Property({'Type': 'List', 'Schema': list_schema}) + self.assertEqual(p.validate_data([1, 2, 3]), [1, 2, 3]) + + def test_list_schema_int_bad_data(self): + list_schema = {'Type': 'Integer'} + p = properties.Property({'Type': 'List', 'Schema': list_schema}) + self.assertRaises(TypeError, p.validate_data, [42, 'fish']) + @attr(tag=['unit', 'properties']) @attr(speed='fast') -- 2.45.2