Template not required on stack-adopt

With this change, template is not required on stack-adopt and
also parameters from the original stack are adopted.

Change-Id: Id5a28400bb8e27a3b852f12d9af4c2dc7c144725
Closes-Bug: #1300336
This commit is contained in:
Vijendar Komalla 2014-09-30 13:38:52 -05:00
parent f11bbaf07a
commit 8c54f48318
4 changed files with 136 additions and 3 deletions

View File

@ -86,10 +86,24 @@ class InstantiationData(object):
def template(self):
"""
Get template file contents, either inline or from a URL, in JSON
or YAML format.
Get template file contents, either inline, from stack adopt data or
from a URL, in JSON or YAML format.
"""
if self.PARAM_TEMPLATE in self.data:
if engine_api.PARAM_ADOPT_STACK_DATA in self.data:
adopt_data = self.data[engine_api.PARAM_ADOPT_STACK_DATA]
try:
adopt_data = template_format.simple_parse(adopt_data)
if not isinstance(adopt_data, dict):
raise exc.HTTPBadRequest(
_('Adopt data %s invalid. Adopt data must be a dict.')
% adopt_data)
return adopt_data['template']
except (ValueError, KeyError) as ex:
err_reason = _('Invalid data: %s') % ex
raise exc.HTTPBadRequest(err_reason)
elif self.PARAM_TEMPLATE in self.data:
template_data = self.data[self.PARAM_TEMPLATE]
if isinstance(template_data, dict):
return template_data

View File

@ -511,7 +511,14 @@ class EngineService(service.Service):
tmpl = templatem.Template(template, files=files)
self._validate_new_stack(cnxt, stack_name, tmpl)
# If it is stack-adopt, use parameters from adopt_stack_data
common_params = api.extract_args(args)
if rpc_api.PARAM_ADOPT_STACK_DATA in common_params:
params[rpc_api.STACK_PARAMETERS] = common_params[
rpc_api.PARAM_ADOPT_STACK_DATA]['environment'][
rpc_api.STACK_PARAMETERS]
env = environment.Environment(params)
stack = parser.Stack(cnxt, stack_name, tmpl, env,
owner_id=owner_id,

View File

@ -719,6 +719,85 @@ class StackControllerTest(ControllerTest, HeatTestCase):
self.m.VerifyAll()
def test_adopt(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'create', True)
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')
template = {
"heat_template_version": "2013-05-23",
"parameters": {"app_dbx": {"type": "string"}},
"resources": {"res1": {"type": "GenericResourceType"}}}
parameters = {"app_dbx": "test"}
adopt_data = {
"status": "COMPLETE",
"name": "rtrove1",
"parameters": parameters,
"template": template,
"action": "CREATE",
"id": "8532f0d3-ea84-444e-b2bb-2543bb1496a4",
"resources": {"res1": {
"status": "COMPLETE",
"name": "database_password",
"resource_id": "yBpuUROjfGQ2gKOD",
"action": "CREATE",
"type": "GenericResourceType",
"metadata": {}}}}
body = {'template': None,
'stack_name': identity.stack_name,
'parameters': parameters,
'timeout_mins': 30,
'adopt_stack_data': str(adopt_data)}
req = self._post('/stacks', json.dumps(body))
self.m.StubOutWithMock(rpc_client.EngineClient, 'call')
rpc_client.EngineClient.call(
req.context,
('create_stack',
{'stack_name': identity.stack_name,
'template': template,
'params': {'parameters': parameters,
'resource_registry': {}},
'files': {},
'args': {'timeout_mins': 30,
'adopt_stack_data': str(adopt_data)},
'owner_id': None})
).AndReturn(dict(identity))
self.m.ReplayAll()
response = self.controller.create(req,
tenant_id=identity.tenant,
body=body)
expected = {'stack':
{'id': '1',
'links': [{'href': self._url(identity), 'rel': 'self'}]}}
self.assertEqual(expected, response)
self.m.VerifyAll()
def test_adopt_error(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'create', True)
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')
parameters = {"app_dbx": "test"}
adopt_data = ["Test"]
body = {'template': None,
'stack_name': identity.stack_name,
'parameters': parameters,
'timeout_mins': 30,
'adopt_stack_data': str(adopt_data)}
req = self._post('/stacks', json.dumps(body))
self.m.ReplayAll()
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant,
body=body)
self.assertEqual(400, resp.status_code)
self.assertEqual('400 Bad Request', resp.status)
self.assertIn('Adopt data must be a dict.', resp.text)
self.m.VerifyAll()
def test_create_with_files(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'create', True)
identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')

View File

@ -512,6 +512,39 @@ class StackServiceCreateUpdateDeleteTest(HeatTestCase):
self.assertEqual(ex.exc_info[0], exception.StackValidationFailed)
self.m.VerifyAll()
def test_stack_adopt_with_params(self):
template = {
"heat_template_version": "2013-05-23",
"parameters": {"app_dbx": {"type": "string"}},
"resources": {"res1": {"type": "GenericResourceType"}}}
environment = {'parameters': {"app_dbx": "test"}}
adopt_data = {
"status": "COMPLETE",
"name": "rtrove1",
"environment": environment,
"template": template,
"action": "CREATE",
"id": "8532f0d3-ea84-444e-b2bb-2543bb1496a4",
"resources": {"res1": {
"status": "COMPLETE",
"name": "database_password",
"resource_id": "yBpuUROjfGQ2gKOD",
"action": "CREATE",
"type": "GenericResourceType",
"metadata": {}}}}
res._register_class('GenericResourceType',
generic_rsrc.GenericResource)
result = self.man.create_stack(self.ctx, "test_adopt_stack",
template, {}, None,
{'adopt_stack_data': str(adopt_data)})
stack = db_api.stack_get(self.ctx, result['stack_id'])
self.assertEqual(template, stack.raw_template.template)
self.assertEqual(environment['parameters'],
stack.parameters['parameters'])
def test_stack_create_invalid_stack_name(self):
stack_name = 'service_create/test_stack'
stack = get_wordpress_stack('test_stack', self.ctx)