Add an environment_format.py like the template one
This to make the section checking mechanism less spread out and more consistent. This can also be used by the global environment loader. Change-Id: I7ca7ad754fb702877dedc416a30f573d239933ad
This commit is contained in:
parent
044a8aaf69
commit
4034963bd7
|
@ -24,6 +24,7 @@ from heat.api.openstack.v1 import util
|
|||
from heat.common import identifier
|
||||
from heat.common import wsgi
|
||||
from heat.common import template_format
|
||||
from heat.common import environment_format
|
||||
from heat.rpc import api as engine_api
|
||||
from heat.rpc import client as rpc_client
|
||||
from heat.common import urlfetch
|
||||
|
@ -59,15 +60,17 @@ class InstantiationData(object):
|
|||
self.data = data
|
||||
|
||||
@staticmethod
|
||||
def format_parse(data, data_type, add_template_sections=True):
|
||||
def format_parse(data, data_type):
|
||||
"""
|
||||
Parse the supplied data as JSON or YAML, raising the appropriate
|
||||
exception if it is in the wrong format.
|
||||
"""
|
||||
|
||||
try:
|
||||
return template_format.parse(data,
|
||||
add_template_sections)
|
||||
if data_type == 'Environment':
|
||||
return environment_format.parse(data)
|
||||
else:
|
||||
return template_format.parse(data)
|
||||
except ValueError:
|
||||
err_reason = _("%s not in valid format") % data_type
|
||||
raise exc.HTTPBadRequest(err_reason)
|
||||
|
@ -115,17 +118,9 @@ class InstantiationData(object):
|
|||
env = env_data
|
||||
else:
|
||||
env = self.format_parse(env_data,
|
||||
'Environment',
|
||||
add_template_sections=False)
|
||||
|
||||
for field in env:
|
||||
if field not in ('parameters', 'resource_registry'):
|
||||
reason = _("%s not in valid in the environment") % field
|
||||
raise exc.HTTPBadRequest(reason)
|
||||
|
||||
if not env.get(self.PARAM_USER_PARAMS):
|
||||
env[self.PARAM_USER_PARAMS] = {}
|
||||
'Environment')
|
||||
|
||||
environment_format.default_for_missing(env)
|
||||
parameters = self.data.get(self.PARAM_USER_PARAMS, {})
|
||||
env[self.PARAM_USER_PARAMS].update(parameters)
|
||||
return env
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from heat.common.template_format import yaml
|
||||
|
||||
|
||||
SECTIONS = (PARAMETERS, RESOURCE_REGISTRY) = \
|
||||
('parameters', 'resource_registry')
|
||||
|
||||
|
||||
def parse(env_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.
|
||||
'''
|
||||
try:
|
||||
env = yaml.safe_load(env_str)
|
||||
except (yaml.scanner.ScannerError, yaml.parser.ParserError) as e:
|
||||
raise ValueError(e)
|
||||
else:
|
||||
if env is None:
|
||||
env = {}
|
||||
|
||||
for param in env:
|
||||
if param not in SECTIONS:
|
||||
raise ValueError('environment has wrong section "%s"' % param)
|
||||
|
||||
return env
|
||||
|
||||
|
||||
def default_for_missing(env):
|
||||
'''
|
||||
Checks a parsed environment for missing sections.
|
||||
'''
|
||||
for param in SECTIONS:
|
||||
if param not in env:
|
||||
env[param] = {}
|
|
@ -37,7 +37,7 @@ yaml.SafeLoader.add_constructor(u'tag:yaml.org,2002:timestamp',
|
|||
_construct_yaml_str)
|
||||
|
||||
|
||||
def parse(tmpl_str, add_template_sections=True):
|
||||
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
|
||||
|
@ -53,7 +53,7 @@ def parse(tmpl_str, add_template_sections=True):
|
|||
else:
|
||||
if tpl is None:
|
||||
tpl = {}
|
||||
if add_template_sections and u'heat_template_version' not in tpl:
|
||||
if u'heat_template_version' not in tpl:
|
||||
default_for_missing(tpl, u'HeatTemplateFormatVersion',
|
||||
HEAT_VERSIONS)
|
||||
return tpl
|
||||
|
|
|
@ -142,7 +142,8 @@ blarg: wibble
|
|||
|
||||
def test_parameters(self):
|
||||
params = {'foo': 'bar', 'blarg': 'wibble'}
|
||||
body = {'parameters': params}
|
||||
body = {'parameters': params,
|
||||
'resource_registry': {}}
|
||||
data = stacks.InstantiationData(body)
|
||||
self.assertEqual(data.environment(), body)
|
||||
|
||||
|
@ -156,7 +157,8 @@ blarg: wibble
|
|||
body = {'parameters': {'foo': 'bar'},
|
||||
'environment': {'parameters': {'blarg': 'wibble'}}}
|
||||
expect = {'parameters': {'blarg': 'wibble',
|
||||
'foo': 'bar'}}
|
||||
'foo': 'bar'},
|
||||
'resource_registry': {}}
|
||||
data = stacks.InstantiationData(body)
|
||||
self.assertEqual(data.environment(), expect)
|
||||
|
||||
|
@ -169,12 +171,14 @@ blarg: wibble
|
|||
'tester': 'fail'}}}
|
||||
expect = {'parameters': {'blarg': 'wibble',
|
||||
'foo': 'bar',
|
||||
'tester': 'Yes'}}
|
||||
'tester': 'Yes'},
|
||||
'resource_registry': {}}
|
||||
data = stacks.InstantiationData(body)
|
||||
self.assertEqual(data.environment(), expect)
|
||||
|
||||
def test_environment_bad_format(self):
|
||||
body = {'environment': {'somethingnotsupported': {'blarg': 'wibble'}}}
|
||||
env = {'somethingnotsupported': {'blarg': 'wibble'}}
|
||||
body = {'environment': json.dumps(env)}
|
||||
data = stacks.InstantiationData(body)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, data.environment)
|
||||
|
||||
|
@ -182,7 +186,9 @@ blarg: wibble
|
|||
env = {'foo': 'bar', 'blarg': 'wibble'}
|
||||
body = {'not the environment': env}
|
||||
data = stacks.InstantiationData(body)
|
||||
self.assertEqual(data.environment(), {'parameters': {}})
|
||||
self.assertEqual(data.environment(),
|
||||
{'parameters': {},
|
||||
'resource_registry': {}})
|
||||
|
||||
def test_args(self):
|
||||
body = {
|
||||
|
@ -443,7 +449,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': identity.stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -480,7 +487,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': identity.stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {'my.yaml': 'This is the file contents.'},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -517,7 +525,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -527,7 +536,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -537,7 +547,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -584,7 +595,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -618,7 +630,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'create_stack',
|
||||
'args': {'stack_name': stack_name,
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -957,7 +970,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'update_stack',
|
||||
'args': {'stack_identity': dict(identity),
|
||||
'template': template,
|
||||
'params': {'parameters': parameters},
|
||||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
@ -992,7 +1006,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'method': 'update_stack',
|
||||
'args': {'stack_identity': dict(identity),
|
||||
'template': template,
|
||||
'params': {u'parameters': parameters},
|
||||
'params': {u'parameters': parameters,
|
||||
u'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}},
|
||||
'version': self.api_version},
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from heat.common import environment_format
|
||||
from heat.tests import common
|
||||
|
||||
|
||||
class YamlEnvironmentTest(common.HeatTestCase):
|
||||
|
||||
def test_minimal_yaml(self):
|
||||
yaml1 = ''
|
||||
yaml2 = '''
|
||||
parameters: {}
|
||||
resource_registry: {}
|
||||
'''
|
||||
tpl1 = environment_format.parse(yaml1)
|
||||
environment_format.default_for_missing(tpl1)
|
||||
tpl2 = environment_format.parse(yaml2)
|
||||
self.assertEqual(tpl1, tpl2)
|
||||
|
||||
def test_wrong_sections(self):
|
||||
env = '''
|
||||
parameters: {}
|
||||
resource_regis: {}
|
||||
'''
|
||||
self.assertRaises(ValueError, environment_format.parse, env)
|
||||
|
||||
def test_bad_yaml(self):
|
||||
env = '''
|
||||
parameters: }
|
||||
'''
|
||||
self.assertRaises(ValueError, environment_format.parse, env)
|
|
@ -90,24 +90,6 @@ Outputs: {}
|
|||
self.assertEqual(tpl1, tpl2)
|
||||
|
||||
|
||||
class YamlEnvironmentTest(HeatTestCase):
|
||||
|
||||
def test_no_template_sections(self):
|
||||
env = '''
|
||||
parameters: {}
|
||||
resource_registry: {}
|
||||
'''
|
||||
parsed_env = template_format.parse(env, add_template_sections=False)
|
||||
|
||||
self.assertEqual('parameters' in parsed_env, True)
|
||||
self.assertEqual('resource_registry' in parsed_env, True)
|
||||
|
||||
self.assertEqual('Parameters' in parsed_env, False)
|
||||
self.assertEqual('Mappings' in parsed_env, False)
|
||||
self.assertEqual('Resources' in parsed_env, False)
|
||||
self.assertEqual('Outputs' in parsed_env, False)
|
||||
|
||||
|
||||
class JsonYamlResolvedCompareTest(HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue