Parse stack_adopt_data
The patch parses the argument passed to stack_create, and validates that it's a dictionary, preventing engine failures in the future. Closes-Bug: #1277106 Change-Id: I88cbf933ddac5776d5ffc0151bc7a0b296048777
This commit is contained in:
parent
b54558569b
commit
b7fa93a03c
|
@ -51,16 +51,7 @@ yaml_loader.add_constructor(u'tag:yaml.org,2002:timestamp',
|
|||
_construct_yaml_str)
|
||||
|
||||
|
||||
def parse(tmpl_str):
|
||||
'''
|
||||
Takes a string and returns a dict containing the parsed structure.
|
||||
This includes determination of whether the string is using the
|
||||
JSON or YAML format.
|
||||
'''
|
||||
if len(tmpl_str) > cfg.CONF.max_template_size:
|
||||
msg = (_('Template exceeds maximum allowed size (%s bytes)') %
|
||||
cfg.CONF.max_template_size)
|
||||
raise exception.RequestLimitExceeded(message=msg)
|
||||
def simple_parse(tmpl_str):
|
||||
try:
|
||||
tpl = json.loads(tmpl_str)
|
||||
except ValueError:
|
||||
|
@ -71,6 +62,20 @@ def parse(tmpl_str):
|
|||
else:
|
||||
if tpl is None:
|
||||
tpl = {}
|
||||
return tpl
|
||||
|
||||
|
||||
def parse(tmpl_str):
|
||||
'''
|
||||
Takes a string and returns a dict containing the parsed structure.
|
||||
This includes determination of whether the string is using the
|
||||
JSON or YAML format.
|
||||
'''
|
||||
if len(tmpl_str) > cfg.CONF.max_template_size:
|
||||
msg = (_('Template exceeds maximum allowed size (%s bytes)') %
|
||||
cfg.CONF.max_template_size)
|
||||
raise exception.RequestLimitExceeded(message=msg)
|
||||
tpl = simple_parse(tmpl_str)
|
||||
if not isinstance(tpl, dict):
|
||||
raise ValueError(_('The template is not a JSON object '
|
||||
'or YAML mapping.'))
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from heat.common import template_format
|
||||
from heat.rpc import api
|
||||
from heat.openstack.common import timeutils
|
||||
from heat.engine import constraints as constr
|
||||
|
@ -49,9 +50,14 @@ def extract_args(params):
|
|||
dict(name=api.PARAM_DISABLE_ROLLBACK,
|
||||
value=disable_rollback))
|
||||
|
||||
if api.PARAM_ADOPT_STACK_DATA in params:
|
||||
kwargs[api.PARAM_ADOPT_STACK_DATA] = params.get(
|
||||
api.PARAM_ADOPT_STACK_DATA)
|
||||
adopt_data = params.get(api.PARAM_ADOPT_STACK_DATA)
|
||||
if adopt_data:
|
||||
adopt_data = template_format.simple_parse(adopt_data)
|
||||
if not isinstance(adopt_data, dict):
|
||||
raise ValueError(
|
||||
_('Unexpected adopt data "%s". Adopt data must be a dict.')
|
||||
% adopt_data)
|
||||
kwargs[api.PARAM_ADOPT_STACK_DATA] = adopt_data
|
||||
|
||||
return kwargs
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import mock
|
||||
import uuid
|
||||
|
||||
|
@ -55,10 +56,17 @@ class EngineApiTest(HeatTestCase):
|
|||
self.assertNotIn('timeout_mins', args)
|
||||
|
||||
def test_adopt_stack_data_extract_present(self):
|
||||
p = {'adopt_stack_data': {'Resources': {}}}
|
||||
p = {'adopt_stack_data': json.dumps({'Resources': {}})}
|
||||
args = api.extract_args(p)
|
||||
self.assertTrue(args.get('adopt_stack_data'))
|
||||
|
||||
def test_invalid_adopt_stack_data(self):
|
||||
p = {'adopt_stack_data': json.dumps("foo")}
|
||||
error = self.assertRaises(ValueError, api.extract_args, p)
|
||||
self.assertEqual(
|
||||
'Unexpected adopt data "foo". Adopt data must be a dict.',
|
||||
str(error))
|
||||
|
||||
def test_adopt_stack_data_extract_not_present(self):
|
||||
args = api.extract_args({})
|
||||
self.assertNotIn('adopt_stack_data', args)
|
||||
|
|
Loading…
Reference in New Issue