Convert props form delimited params to lists
Use allow_conversion flag to convert comma_delimited_list to list before validation when using from_parameter. Change-Id: Id144aade23eee13df227acdb728906c8dd345337 Closes-Bug: #1617019
This commit is contained in:
parent
a495438c9c
commit
80bc4fbebd
@ -28,6 +28,16 @@ def extract_bool(name, value):
|
|||||||
return strutils.bool_from_string(value, strict=True)
|
return strutils.bool_from_string(value, strict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def delim_string_to_list(value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if value == '':
|
||||||
|
return []
|
||||||
|
|
||||||
|
return value.split(',')
|
||||||
|
|
||||||
|
|
||||||
def extract_int(name, value, allow_zero=True, allow_negative=False):
|
def extract_int(name, value, allow_zero=True, allow_negative=False):
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
@ -21,6 +21,7 @@ import six
|
|||||||
|
|
||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
|
from heat.common import param_utils
|
||||||
from heat.engine import constraints as constr
|
from heat.engine import constraints as constr
|
||||||
|
|
||||||
|
|
||||||
@ -376,10 +377,7 @@ class CommaDelimitedListParam(ParsedParameter, collections.Sequence):
|
|||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
return [(six.text_type(x)) for x in value]
|
return [(six.text_type(x)) for x in value]
|
||||||
try:
|
try:
|
||||||
if value is not None:
|
return param_utils.delim_string_to_list(value)
|
||||||
if value == '':
|
|
||||||
return []
|
|
||||||
return value.split(',')
|
|
||||||
except (KeyError, AttributeError) as err:
|
except (KeyError, AttributeError) as err:
|
||||||
message = _('Value must be a comma-delimited list string: %s')
|
message = _('Value must be a comma-delimited list string: %s')
|
||||||
raise ValueError(message % six.text_type(err))
|
raise ValueError(message % six.text_type(err))
|
||||||
|
@ -18,6 +18,7 @@ import six
|
|||||||
|
|
||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
|
from heat.common import param_utils
|
||||||
from heat.engine import constraints as constr
|
from heat.engine import constraints as constr
|
||||||
from heat.engine import function
|
from heat.engine import function
|
||||||
from heat.engine.hot import parameters as hot_param
|
from heat.engine.hot import parameters as hot_param
|
||||||
@ -162,7 +163,8 @@ class Schema(constr.Schema):
|
|||||||
# a json parameter value is passed via a Map property, which requires
|
# a json parameter value is passed via a Map property, which requires
|
||||||
# some coercion to pass strings or lists (which are both valid for
|
# some coercion to pass strings or lists (which are both valid for
|
||||||
# Json parameters but not for Map properties).
|
# Json parameters but not for Map properties).
|
||||||
allow_conversion = param.type == param.MAP
|
allow_conversion = (param.type == param.MAP
|
||||||
|
or param.type == param.LIST)
|
||||||
|
|
||||||
# make update_allowed true by default on TemplateResources
|
# make update_allowed true by default on TemplateResources
|
||||||
# as the template should deal with this.
|
# as the template should deal with this.
|
||||||
@ -299,6 +301,9 @@ class Property(object):
|
|||||||
def _get_list(self, value, validate=False):
|
def _get_list(self, value, validate=False):
|
||||||
if value is None:
|
if value is None:
|
||||||
value = self.has_default() and self.default() or []
|
value = self.has_default() and self.default() or []
|
||||||
|
if self.schema.allow_conversion and isinstance(value,
|
||||||
|
six.string_types):
|
||||||
|
value = param_utils.delim_string_to_list(value)
|
||||||
if (not isinstance(value, collections.Sequence) or
|
if (not isinstance(value, collections.Sequence) or
|
||||||
isinstance(value, six.string_types)):
|
isinstance(value, six.string_types)):
|
||||||
raise TypeError(_('"%s" is not a list') % repr(value))
|
raise TypeError(_('"%s" is not a list') % repr(value))
|
||||||
|
@ -598,7 +598,7 @@ class PropertySchemaTest(common.HeatTestCase):
|
|||||||
self.assertEqual(properties.Schema.LIST, schema.type)
|
self.assertEqual(properties.Schema.LIST, schema.type)
|
||||||
self.assertIsNone(schema.default)
|
self.assertIsNone(schema.default)
|
||||||
self.assertFalse(schema.required)
|
self.assertFalse(schema.required)
|
||||||
self.assertFalse(schema.allow_conversion)
|
self.assertTrue(schema.allow_conversion)
|
||||||
|
|
||||||
props = properties.Properties({'test': schema}, {})
|
props = properties.Properties({'test': schema}, {})
|
||||||
props.validate()
|
props.validate()
|
||||||
@ -903,6 +903,13 @@ class PropertyTest(common.HeatTestCase):
|
|||||||
p = properties.Property({'Type': 'List'})
|
p = properties.Property({'Type': 'List'})
|
||||||
self.assertRaises(TypeError, p.get_value, {'foo': 'bar'})
|
self.assertRaises(TypeError, p.get_value, {'foo': 'bar'})
|
||||||
|
|
||||||
|
def test_list_is_delimited(self):
|
||||||
|
p = properties.Property({'Type': 'List'})
|
||||||
|
self.assertRaises(TypeError, p.get_value, 'foo,bar')
|
||||||
|
p.schema.allow_conversion = True
|
||||||
|
self.assertEqual(['foo', 'bar'], p.get_value('foo,bar'))
|
||||||
|
self.assertEqual(['foo'], p.get_value('foo'))
|
||||||
|
|
||||||
def test_list_maxlength_good(self):
|
def test_list_maxlength_good(self):
|
||||||
schema = {'Type': 'List',
|
schema = {'Type': 'List',
|
||||||
'MaxLength': '3'}
|
'MaxLength': '3'}
|
||||||
|
Loading…
Reference in New Issue
Block a user