args = {'template': stack,
'params': stack_parms,
+ 'files': {},
'args': create_args}
try:
stack_name = req.params['StackName']
PARAM_TEMPLATE_URL,
PARAM_USER_PARAMS,
PARAM_ENVIRONMENT,
+ PARAM_FILES,
) = (
'stack_name',
'template',
'template_url',
'parameters',
'environment',
+ 'files',
)
def __init__(self, data):
env[self.PARAM_USER_PARAMS].update(parameters)
return env
+ def files(self):
+ return self.data.get(self.PARAM_FILES, {})
+
def args(self):
"""
Get any additional arguments supplied by the user.
data.stack_name(),
data.template(),
data.environment(),
+ data.files(),
data.args())
except rpc_common.RemoteError as ex:
return util.remote_error(ex)
identity,
data.template(),
data.environment(),
+ data.files(),
data.args())
except rpc_common.RemoteError as ex:
return util.remote_error(ex)
return list(format_stack_details(stacks))
@request_context
- def create_stack(self, cnxt, stack_name, template, params, args):
+ def create_stack(self, cnxt, stack_name, template, params, files, args):
"""
The create_stack method creates a new stack using the template
provided.
Note that at this stage the template has already been fetched from the
heat-api process if using a template-url.
- arg1 -> RPC context.
- arg2 -> Name of the stack you want to create.
- arg3 -> Template of stack you want to create.
- arg4 -> Stack Input Params
- arg4 -> Request parameters/args passed from API
+ :param cnxt: RPC context.
+ :param stack_name: Name of the stack you want to create.
+ :param template: Template of stack you want to create.
+ :param params: Stack Input Params
+ :param files: Files referenced from the template
+ (currently provider templates).
+ :param args: Request parameters/args passed from API
"""
logger.info('template is %s' % template)
if db_api.stack_get_by_name(cnxt, stack_name):
raise exception.StackExists(stack_name=stack_name)
- tmpl = parser.Template(template)
+ tmpl = parser.Template(template, files=files)
# Extract the common query parameters
common_params = api.extract_args(args)
return dict(stack.identifier())
@request_context
- def update_stack(self, cnxt, stack_identity, template, params, args):
+ def update_stack(self, cnxt, stack_identity, template, params,
+ files, args):
"""
The update_stack method updates an existing stack based on the
provided template and parameters.
# Now parse the template and any parameters for the updated
# stack definition.
- tmpl = parser.Template(template)
+ tmpl = parser.Template(template, files=files)
stack_name = current_stack.name
common_params = api.extract_args(args)
env = environment.Environment(params)
return super(Template, cls).__new__(cls)
- def __init__(self, template, template_id=None):
+ def __init__(self, template, template_id=None, files=None):
'''
Initialise the template with a JSON object and a set of Parameters
'''
self.id = template_id
self.t = template
+ self.files = files or {}
self.maps = self[MAPPINGS]
@classmethod
return self.call(ctxt, self.make_msg('show_stack',
stack_identity=stack_identity))
- def create_stack(self, ctxt, stack_name, template, params, args):
+ def create_stack(self, ctxt, stack_name, template, params, files, args):
"""
The create_stack method creates a new stack using the template
provided.
:param stack_name: Name of the stack you want to create.
:param template: Template of stack you want to create.
:param params: Stack Input Params/Environment
+ :param files: files referenced from the environment.
:param args: Request parameters/args passed from API
"""
return self.call(ctxt,
self.make_msg('create_stack', stack_name=stack_name,
template=template,
- params=params, args=args))
+ params=params, files=files, args=args))
- def update_stack(self, ctxt, stack_identity, template, params, args):
+ def update_stack(self, ctxt, stack_identity, template, params,
+ files, args):
"""
The update_stack method updates an existing stack based on the
provided template and parameters.
:param stack_name: Name of the stack you want to create.
:param template: Template of stack you want to create.
:param params: Stack Input Params/Environment
+ :param files: files referenced from the environment.
:param args: Request parameters/args passed from API
"""
return self.call(ctxt, self.make_msg('update_stack',
stack_identity=stack_identity,
template=template,
- params=params, args=args))
+ params=params,
+ files=files,
+ args=args))
def validate_template(self, ctxt, template):
"""
'args': {'stack_name': stack_name,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version}, None).AndReturn(engine_resp)
'args': {'stack_name': stack_name,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError"))
'args': {'stack_name': stack_name,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
'args': {'stack_name': stack_name,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("StackExists"))
'args': {'stack_name': stack_name,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version}, None).AndRaise(
rpc_common.RemoteError(
'args': {'stack_identity': identity,
'template': template,
'params': engine_parms,
+ 'files': {},
'args': engine_args},
'version': self.api_version},
None).AndReturn(identity)
'args': {'stack_name': identity.stack_name,
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
+ 'args': {'timeout_mins': 30}},
+ 'version': self.api_version},
+ None).AndReturn(dict(identity))
+ self.m.ReplayAll()
+
+ try:
+ response = self.controller.create(req,
+ tenant_id=identity.tenant,
+ body=body)
+ except webob.exc.HTTPCreated as created:
+ self.assertEqual(created.location, self._url(identity))
+ else:
+ self.fail('HTTPCreated not raised')
+ self.m.VerifyAll()
+
+ def test_create_with_files(self):
+ identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')
+ template = {u'Foo': u'bar'}
+ json_template = json.dumps(template)
+ parameters = {u'InstanceType': u'm1.xlarge'}
+ body = {'template': template,
+ 'stack_name': identity.stack_name,
+ 'parameters': parameters,
+ 'files': {'my.yaml': 'This is the file contents.'},
+ 'timeout_mins': 30}
+
+ req = self._post('/stacks', json.dumps(body))
+
+ self.m.StubOutWithMock(rpc, 'call')
+ rpc.call(req.context, self.topic,
+ {'namespace': None,
+ 'method': 'create_stack',
+ 'args': {'stack_name': identity.stack_name,
+ 'template': template,
+ 'params': {'parameters': parameters},
+ 'files': {'my.yaml': 'This is the file contents.'},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndReturn(dict(identity))
'args': {'stack_name': stack_name,
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("AttributeError"))
'args': {'stack_name': stack_name,
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
'args': {'stack_name': stack_name,
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackExists"))
'args': {'stack_name': stack_name,
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError(
parameters = {u'InstanceType': u'm1.xlarge'}
body = {'template': template,
'parameters': parameters,
+ 'files': {},
'timeout_mins': 30}
req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
'args': {'stack_identity': dict(identity),
'template': template,
'params': {'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndReturn(dict(identity))
parameters = {u'InstanceType': u'm1.xlarge'}
body = {'template': template,
'parameters': parameters,
+ 'files': {},
'timeout_mins': 30}
req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
'args': {'stack_identity': dict(identity),
'template': template,
'params': {u'parameters': parameters},
+ 'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
- parser.Template(template).AndReturn(stack.t)
+ parser.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack)
self.m.ReplayAll()
result = self.man.create_stack(self.ctx, stack_name,
- template, params, {})
+ template, params, None, {})
self.assertEqual(result, stack.identifier())
self.assertTrue(isinstance(result, dict))
self.assertTrue(result['stack_id'])
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
- parser.Template(template).AndReturn(stack.t)
+ parser.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t,
exception.StackValidationFailed,
self.man.create_stack,
self.ctx, stack_name,
- template, params, {})
+ template, params, None, {})
self.m.VerifyAll()
def test_stack_create_invalid_stack_name(self):
self.assertRaises(ValueError,
self.man.create_stack,
- self.ctx, stack_name, stack.t, {}, {})
+ self.ctx, stack_name, stack.t, {}, None, {})
def test_stack_create_invalid_resource_name(self):
stack_name = 'service_create_test_stack_invalid_res'
self.assertRaises(ValueError,
self.man.create_stack,
self.ctx, stack_name,
- stack.t, {}, {})
+ stack.t, {}, None, {})
def test_stack_validate(self):
stack_name = 'service_create_test_validate'
self.m.StubOutWithMock(parser, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
- parser.Template(template).AndReturn(stack.t)
+ parser.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack)
self.m.ReplayAll()
result = self.man.update_stack(self.ctx, old_stack.identifier(),
- template, params, {})
+ template, params, None, {})
self.assertEqual(result, old_stack.identifier())
self.assertTrue(isinstance(result, dict))
self.assertTrue(result['stack_id'])
self.m.StubOutWithMock(parser, 'Template')
self.m.StubOutWithMock(environment, 'Environment')
- parser.Template(template).AndReturn(stack.t)
+ parser.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack)
exception.StackValidationFailed,
self.man.update_stack,
self.ctx, old_stack.identifier(),
- template, params, {})
+ template, params, None, {})
self.m.VerifyAll()
def test_stack_update_nonexist(self):
self.assertRaises(exception.StackNotFound,
self.man.update_stack,
- self.ctx, stack.identifier(), template, params, {})
+ self.ctx, stack.identifier(), template, params,
+ None, {})
self.m.VerifyAll()
@stack_context('service_create_existing_test_stack', False)
def test_stack_create_existing(self):
self.assertRaises(exception.StackExists, self.eng.create_stack,
- self.ctx, self.stack.name, self.stack.t, {}, {})
+ self.ctx, self.stack.name, self.stack.t, {},
+ None, {})
@stack_context('service_name_tenants_test_stack', False)
def test_stack_by_name_tenants(self):
self._test_engine_api('create_stack', 'call', stack_name='wordpress',
template={u'Foo': u'bar'},
params={u'InstanceType': u'm1.xlarge'},
+ files={u'a_file': u'the contents'},
args={'timeout_mins': u'30'})
def test_update_stack(self):
stack_identity=self.identity,
template={u'Foo': u'bar'},
params={u'InstanceType': u'm1.xlarge'},
+ files={},
args={})
def test_validate_template(self):