API support for Environments
Support "Environment" section in the create/update body. We the roll up the parameters and the environment and send that as json using the rpc "params" argument. So no changes to the rpc layer are needed. The engine knows how to deal with both formats in the Environments class. blueprint envirnonments Change-Id: I6d6085d5c052a5f9115ecd46891b00d2fad4d1db
This commit is contained in:
parent
c28f12d94f
commit
95ac80a0d5
|
@ -142,6 +142,12 @@
|
||||||
</p></doc>
|
</p></doc>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
<param name="environment" style="plain" required="true">
|
||||||
|
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
A JSON envionment for the stack.
|
||||||
|
</p></doc>
|
||||||
|
</param>
|
||||||
|
|
||||||
<param name="param_name-n" style="plain" required="true">
|
<param name="param_name-n" style="plain" required="true">
|
||||||
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
||||||
User-defined parameter names to pass to the template.
|
User-defined parameter names to pass to the template.
|
||||||
|
@ -226,6 +232,12 @@
|
||||||
</p></doc>
|
</p></doc>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
<param name="environment" style="plain" required="true">
|
||||||
|
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
A JSON envionment for the stack.
|
||||||
|
</p></doc>
|
||||||
|
</param>
|
||||||
|
|
||||||
<param name="param_name-n" style="plain" required="true">
|
<param name="param_name-n" style="plain" required="true">
|
||||||
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
<doc><p xmlns="http://www.w3.org/1999/xhtml">
|
||||||
User-defined parameter names to pass to the template.
|
User-defined parameter names to pass to the template.
|
||||||
|
|
|
@ -44,11 +44,13 @@ class InstantiationData(object):
|
||||||
PARAM_TEMPLATE,
|
PARAM_TEMPLATE,
|
||||||
PARAM_TEMPLATE_URL,
|
PARAM_TEMPLATE_URL,
|
||||||
PARAM_USER_PARAMS,
|
PARAM_USER_PARAMS,
|
||||||
|
PARAM_ENVIRONMENT,
|
||||||
) = (
|
) = (
|
||||||
'stack_name',
|
'stack_name',
|
||||||
'template',
|
'template',
|
||||||
'template_url',
|
'template_url',
|
||||||
'parameters',
|
'parameters',
|
||||||
|
'environment',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -99,11 +101,33 @@ class InstantiationData(object):
|
||||||
|
|
||||||
return self.format_parse(template_data, 'Template')
|
return self.format_parse(template_data, 'Template')
|
||||||
|
|
||||||
def user_params(self):
|
def environment(self):
|
||||||
"""
|
"""
|
||||||
Get the user-supplied parameters for the stack in JSON format.
|
Get the user-supplied environment for the stack in YAML format.
|
||||||
|
If the user supplied Parameters then merge these into the
|
||||||
|
environment global options.
|
||||||
"""
|
"""
|
||||||
return self.data.get(self.PARAM_USER_PARAMS, {})
|
env = {}
|
||||||
|
if self.PARAM_ENVIRONMENT in self.data:
|
||||||
|
env_data = self.data[self.PARAM_ENVIRONMENT]
|
||||||
|
if isinstance(env_data, dict):
|
||||||
|
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 self.PARAM_USER_PARAMS not in env:
|
||||||
|
env[self.PARAM_USER_PARAMS] = {}
|
||||||
|
|
||||||
|
parameters = self.data.get(self.PARAM_USER_PARAMS, {})
|
||||||
|
env[self.PARAM_USER_PARAMS].update(parameters)
|
||||||
|
return env
|
||||||
|
|
||||||
def args(self):
|
def args(self):
|
||||||
"""
|
"""
|
||||||
|
@ -180,7 +204,7 @@ class StackController(object):
|
||||||
result = self.engine.create_stack(req.context,
|
result = self.engine.create_stack(req.context,
|
||||||
data.stack_name(),
|
data.stack_name(),
|
||||||
data.template(),
|
data.template(),
|
||||||
data.user_params(),
|
data.environment(),
|
||||||
data.args())
|
data.args())
|
||||||
except rpc_common.RemoteError as ex:
|
except rpc_common.RemoteError as ex:
|
||||||
return util.remote_error(ex)
|
return util.remote_error(ex)
|
||||||
|
@ -255,7 +279,7 @@ class StackController(object):
|
||||||
res = self.engine.update_stack(req.context,
|
res = self.engine.update_stack(req.context,
|
||||||
identity,
|
identity,
|
||||||
data.template(),
|
data.template(),
|
||||||
data.user_params(),
|
data.environment(),
|
||||||
data.args())
|
data.args())
|
||||||
except rpc_common.RemoteError as ex:
|
except rpc_common.RemoteError as ex:
|
||||||
return util.remote_error(ex)
|
return util.remote_error(ex)
|
||||||
|
|
|
@ -114,21 +114,54 @@ blarg: wibble
|
||||||
data = stacks.InstantiationData(body)
|
data = stacks.InstantiationData(body)
|
||||||
self.assertRaises(webob.exc.HTTPBadRequest, data.template)
|
self.assertRaises(webob.exc.HTTPBadRequest, data.template)
|
||||||
|
|
||||||
def test_user_params(self):
|
def test_parameters(self):
|
||||||
params = {'foo': 'bar', 'blarg': 'wibble'}
|
params = {'foo': 'bar', 'blarg': 'wibble'}
|
||||||
body = {'parameters': params}
|
body = {'parameters': params}
|
||||||
data = stacks.InstantiationData(body)
|
data = stacks.InstantiationData(body)
|
||||||
self.assertEqual(data.user_params(), params)
|
self.assertEqual(data.environment(), body)
|
||||||
|
|
||||||
def test_user_params_missing(self):
|
def test_environment_only_params(self):
|
||||||
params = {'foo': 'bar', 'blarg': 'wibble'}
|
env = {'parameters': {'foo': 'bar', 'blarg': 'wibble'}}
|
||||||
body = {'not the parameters': params}
|
body = {'environment': env}
|
||||||
data = stacks.InstantiationData(body)
|
data = stacks.InstantiationData(body)
|
||||||
self.assertEqual(data.user_params(), {})
|
self.assertEqual(data.environment(), env)
|
||||||
|
|
||||||
|
def test_environment_and_parameters(self):
|
||||||
|
body = {'parameters': {'foo': 'bar'},
|
||||||
|
'environment': {'parameters': {'blarg': 'wibble'}}}
|
||||||
|
expect = {'parameters': {'blarg': 'wibble',
|
||||||
|
'foo': 'bar'}}
|
||||||
|
data = stacks.InstantiationData(body)
|
||||||
|
self.assertEqual(data.environment(), expect)
|
||||||
|
|
||||||
|
def test_parameters_override_environment(self):
|
||||||
|
# This tests that the cli parameters will override
|
||||||
|
# any parameters in the environment.
|
||||||
|
body = {'parameters': {'foo': 'bar',
|
||||||
|
'tester': 'Yes'},
|
||||||
|
'environment': {'parameters': {'blarg': 'wibble',
|
||||||
|
'tester': 'fail'}}}
|
||||||
|
expect = {'parameters': {'blarg': 'wibble',
|
||||||
|
'foo': 'bar',
|
||||||
|
'tester': 'Yes'}}
|
||||||
|
data = stacks.InstantiationData(body)
|
||||||
|
self.assertEqual(data.environment(), expect)
|
||||||
|
|
||||||
|
def test_environment_bad_format(self):
|
||||||
|
body = {'environment': {'somethingnotsupported': {'blarg': 'wibble'}}}
|
||||||
|
data = stacks.InstantiationData(body)
|
||||||
|
self.assertRaises(webob.exc.HTTPBadRequest, data.environment)
|
||||||
|
|
||||||
|
def test_environment_missing(self):
|
||||||
|
env = {'foo': 'bar', 'blarg': 'wibble'}
|
||||||
|
body = {'not the environment': env}
|
||||||
|
data = stacks.InstantiationData(body)
|
||||||
|
self.assertEqual(data.environment(), {'parameters': {}})
|
||||||
|
|
||||||
def test_args(self):
|
def test_args(self):
|
||||||
body = {
|
body = {
|
||||||
'parameters': {},
|
'parameters': {},
|
||||||
|
'environment': {},
|
||||||
'stack_name': 'foo',
|
'stack_name': 'foo',
|
||||||
'template': {},
|
'template': {},
|
||||||
'template_url': 'http://example.com/',
|
'template_url': 'http://example.com/',
|
||||||
|
@ -324,7 +357,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'create_stack',
|
'method': 'create_stack',
|
||||||
'args': {'stack_name': identity.stack_name,
|
'args': {'stack_name': identity.stack_name,
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndReturn(dict(identity))
|
None).AndReturn(dict(identity))
|
||||||
|
@ -358,7 +391,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'create_stack',
|
'method': 'create_stack',
|
||||||
'args': {'stack_name': stack_name,
|
'args': {'stack_name': stack_name,
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndRaise(rpc_common.RemoteError("AttributeError"))
|
None).AndRaise(rpc_common.RemoteError("AttributeError"))
|
||||||
|
@ -367,7 +400,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'create_stack',
|
'method': 'create_stack',
|
||||||
'args': {'stack_name': stack_name,
|
'args': {'stack_name': stack_name,
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
|
None).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
|
||||||
|
@ -401,7 +434,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'create_stack',
|
'method': 'create_stack',
|
||||||
'args': {'stack_name': stack_name,
|
'args': {'stack_name': stack_name,
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndRaise(rpc_common.RemoteError("StackExists"))
|
None).AndRaise(rpc_common.RemoteError("StackExists"))
|
||||||
|
@ -430,7 +463,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'create_stack',
|
'method': 'create_stack',
|
||||||
'args': {'stack_name': stack_name,
|
'args': {'stack_name': stack_name,
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndRaise(rpc_common.RemoteError(
|
None).AndRaise(rpc_common.RemoteError(
|
||||||
|
@ -719,7 +752,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'update_stack',
|
'method': 'update_stack',
|
||||||
'args': {'stack_identity': dict(identity),
|
'args': {'stack_identity': dict(identity),
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndReturn(dict(identity))
|
None).AndReturn(dict(identity))
|
||||||
|
@ -751,7 +784,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||||
'method': 'update_stack',
|
'method': 'update_stack',
|
||||||
'args': {'stack_identity': dict(identity),
|
'args': {'stack_identity': dict(identity),
|
||||||
'template': template,
|
'template': template,
|
||||||
'params': parameters,
|
'params': {u'parameters': parameters},
|
||||||
'args': {'timeout_mins': 30}},
|
'args': {'timeout_mins': 30}},
|
||||||
'version': self.api_version},
|
'version': self.api_version},
|
||||||
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
|
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
|
||||||
|
|
Loading…
Reference in New Issue