Merge "Initial provider template uploading"

This commit is contained in:
Jenkins 2013-06-19 17:46:18 +00:00 committed by Gerrit Code Review
commit fe8458bbb1
9 changed files with 98 additions and 26 deletions

View File

@ -324,6 +324,7 @@ class StackController(object):
args = {'template': stack, args = {'template': stack,
'params': stack_parms, 'params': stack_parms,
'files': {},
'args': create_args} 'args': create_args}
try: try:
stack_name = req.params['StackName'] stack_name = req.params['StackName']

View File

@ -45,12 +45,14 @@ class InstantiationData(object):
PARAM_TEMPLATE_URL, PARAM_TEMPLATE_URL,
PARAM_USER_PARAMS, PARAM_USER_PARAMS,
PARAM_ENVIRONMENT, PARAM_ENVIRONMENT,
PARAM_FILES,
) = ( ) = (
'stack_name', 'stack_name',
'template', 'template',
'template_url', 'template_url',
'parameters', 'parameters',
'environment', 'environment',
'files',
) )
def __init__(self, data): def __init__(self, data):
@ -129,6 +131,9 @@ class InstantiationData(object):
env[self.PARAM_USER_PARAMS].update(parameters) env[self.PARAM_USER_PARAMS].update(parameters)
return env return env
def files(self):
return self.data.get(self.PARAM_FILES, {})
def args(self): def args(self):
""" """
Get any additional arguments supplied by the user. Get any additional arguments supplied by the user.
@ -205,6 +210,7 @@ class StackController(object):
data.stack_name(), data.stack_name(),
data.template(), data.template(),
data.environment(), data.environment(),
data.files(),
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)
@ -280,6 +286,7 @@ class StackController(object):
identity, identity,
data.template(), data.template(),
data.environment(), data.environment(),
data.files(),
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)

View File

@ -184,17 +184,19 @@ class EngineService(service.Service):
return list(format_stack_details(stacks)) return list(format_stack_details(stacks))
@request_context @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 The create_stack method creates a new stack using the template
provided. provided.
Note that at this stage the template has already been fetched from the Note that at this stage the template has already been fetched from the
heat-api process if using a template-url. heat-api process if using a template-url.
arg1 -> RPC context. :param cnxt: RPC context.
arg2 -> Name of the stack you want to create. :param stack_name: Name of the stack you want to create.
arg3 -> Template of stack you want to create. :param template: Template of stack you want to create.
arg4 -> Stack Input Params :param params: Stack Input Params
arg4 -> Request parameters/args passed from API :param files: Files referenced from the template
(currently provider templates).
:param args: Request parameters/args passed from API
""" """
logger.info('template is %s' % template) logger.info('template is %s' % template)
@ -211,7 +213,7 @@ class EngineService(service.Service):
if db_api.stack_get_by_name(cnxt, stack_name): if db_api.stack_get_by_name(cnxt, stack_name):
raise exception.StackExists(stack_name=stack_name) raise exception.StackExists(stack_name=stack_name)
tmpl = parser.Template(template) tmpl = parser.Template(template, files=files)
# Extract the common query parameters # Extract the common query parameters
common_params = api.extract_args(args) common_params = api.extract_args(args)
@ -228,7 +230,8 @@ class EngineService(service.Service):
return dict(stack.identifier()) return dict(stack.identifier())
@request_context @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 The update_stack method updates an existing stack based on the
provided template and parameters. provided template and parameters.
@ -249,7 +252,7 @@ class EngineService(service.Service):
# Now parse the template and any parameters for the updated # Now parse the template and any parameters for the updated
# stack definition. # stack definition.
tmpl = parser.Template(template) tmpl = parser.Template(template, files=files)
stack_name = current_stack.name stack_name = current_stack.name
common_params = api.extract_args(args) common_params = api.extract_args(args)
env = environment.Environment(params) env = environment.Environment(params)

View File

@ -38,12 +38,13 @@ class Template(collections.Mapping):
return super(Template, cls).__new__(cls) 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 Initialise the template with a JSON object and a set of Parameters
''' '''
self.id = template_id self.id = template_id
self.t = template self.t = template
self.files = files or {}
self.maps = self[MAPPINGS] self.maps = self[MAPPINGS]
@classmethod @classmethod

View File

@ -67,7 +67,7 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
return self.call(ctxt, self.make_msg('show_stack', return self.call(ctxt, self.make_msg('show_stack',
stack_identity=stack_identity)) 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 The create_stack method creates a new stack using the template
provided. provided.
@ -78,14 +78,16 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
:param stack_name: Name of the stack you want to create. :param stack_name: Name of the stack you want to create.
:param template: Template of stack you want to create. :param template: Template of stack you want to create.
:param params: Stack Input Params/Environment :param params: Stack Input Params/Environment
:param files: files referenced from the environment.
:param args: Request parameters/args passed from API :param args: Request parameters/args passed from API
""" """
return self.call(ctxt, return self.call(ctxt,
self.make_msg('create_stack', stack_name=stack_name, self.make_msg('create_stack', stack_name=stack_name,
template=template, 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 The update_stack method updates an existing stack based on the
provided template and parameters. provided template and parameters.
@ -96,12 +98,15 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
:param stack_name: Name of the stack you want to create. :param stack_name: Name of the stack you want to create.
:param template: Template of stack you want to create. :param template: Template of stack you want to create.
:param params: Stack Input Params/Environment :param params: Stack Input Params/Environment
:param files: files referenced from the environment.
:param args: Request parameters/args passed from API :param args: Request parameters/args passed from API
""" """
return self.call(ctxt, self.make_msg('update_stack', return self.call(ctxt, self.make_msg('update_stack',
stack_identity=stack_identity, stack_identity=stack_identity,
template=template, template=template,
params=params, args=args)) params=params,
files=files,
args=args))
def validate_template(self, ctxt, template): def validate_template(self, ctxt, template):
""" """

View File

@ -474,6 +474,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, None).AndReturn(engine_resp) 'version': self.api_version}, None).AndReturn(engine_resp)
@ -537,6 +538,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, None 'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("AttributeError")) ).AndRaise(rpc_common.RemoteError("AttributeError"))
@ -546,6 +548,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, None 'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("UnknownUserParameter")) ).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
@ -588,6 +591,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, None 'version': self.api_version}, None
).AndRaise(rpc_common.RemoteError("StackExists")) ).AndRaise(rpc_common.RemoteError("StackExists"))
@ -623,6 +627,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, None).AndRaise( 'version': self.api_version}, None).AndRaise(
rpc_common.RemoteError( rpc_common.RemoteError(
@ -666,6 +671,7 @@ class CfnStackControllerTest(HeatTestCase):
'args': {'stack_identity': identity, 'args': {'stack_identity': identity,
'template': template, 'template': template,
'params': engine_parms, 'params': engine_parms,
'files': {},
'args': engine_args}, 'args': engine_args},
'version': self.api_version}, 'version': self.api_version},
None).AndReturn(identity) None).AndReturn(identity)

View File

@ -358,6 +358,43 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_name': identity.stack_name, 'args': {'stack_name': identity.stack_name,
'template': template, 'template': template,
'params': {'parameters': parameters}, '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}}, 'args': {'timeout_mins': 30}},
'version': self.api_version}, 'version': self.api_version},
None).AndReturn(dict(identity)) None).AndReturn(dict(identity))
@ -392,6 +429,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': {'parameters': parameters}, 'params': {'parameters': parameters},
'files': {},
'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"))
@ -401,6 +439,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': {'parameters': parameters}, 'params': {'parameters': parameters},
'files': {},
'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"))
@ -435,6 +474,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': {'parameters': parameters}, 'params': {'parameters': parameters},
'files': {},
'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"))
@ -464,6 +504,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_name': stack_name, 'args': {'stack_name': stack_name,
'template': template, 'template': template,
'params': {'parameters': parameters}, 'params': {'parameters': parameters},
'files': {},
'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(
@ -741,6 +782,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
parameters = {u'InstanceType': u'm1.xlarge'} parameters = {u'InstanceType': u'm1.xlarge'}
body = {'template': template, body = {'template': template,
'parameters': parameters, 'parameters': parameters,
'files': {},
'timeout_mins': 30} 'timeout_mins': 30}
req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity, req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
@ -753,6 +795,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': dict(identity), 'args': {'stack_identity': dict(identity),
'template': template, 'template': template,
'params': {'parameters': parameters}, 'params': {'parameters': parameters},
'files': {},
'args': {'timeout_mins': 30}}, 'args': {'timeout_mins': 30}},
'version': self.api_version}, 'version': self.api_version},
None).AndReturn(dict(identity)) None).AndReturn(dict(identity))
@ -773,6 +816,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
parameters = {u'InstanceType': u'm1.xlarge'} parameters = {u'InstanceType': u'm1.xlarge'}
body = {'template': template, body = {'template': template,
'parameters': parameters, 'parameters': parameters,
'files': {},
'timeout_mins': 30} 'timeout_mins': 30}
req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity, req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
@ -785,6 +829,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': dict(identity), 'args': {'stack_identity': dict(identity),
'template': template, 'template': template,
'params': {u'parameters': parameters}, 'params': {u'parameters': parameters},
'files': {},
'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"))

View File

@ -246,7 +246,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.StubOutWithMock(environment, 'Environment') self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack') 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) environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name, parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack) stack.t, stack.env).AndReturn(stack)
@ -260,7 +260,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.ReplayAll() self.m.ReplayAll()
result = self.man.create_stack(self.ctx, stack_name, result = self.man.create_stack(self.ctx, stack_name,
template, params, {}) template, params, None, {})
self.assertEqual(result, stack.identifier()) self.assertEqual(result, stack.identifier())
self.assertTrue(isinstance(result, dict)) self.assertTrue(isinstance(result, dict))
self.assertTrue(result['stack_id']) self.assertTrue(result['stack_id'])
@ -277,7 +277,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.StubOutWithMock(environment, 'Environment') self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack') 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) environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name, parser.Stack(self.ctx, stack.name,
stack.t, stack.t,
@ -293,7 +293,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
exception.StackValidationFailed, exception.StackValidationFailed,
self.man.create_stack, self.man.create_stack,
self.ctx, stack_name, self.ctx, stack_name,
template, params, {}) template, params, None, {})
self.m.VerifyAll() self.m.VerifyAll()
def test_stack_create_invalid_stack_name(self): def test_stack_create_invalid_stack_name(self):
@ -302,7 +302,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.assertRaises(ValueError, self.assertRaises(ValueError,
self.man.create_stack, 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): def test_stack_create_invalid_resource_name(self):
stack_name = 'service_create_test_stack_invalid_res' stack_name = 'service_create_test_stack_invalid_res'
@ -314,7 +314,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.assertRaises(ValueError, self.assertRaises(ValueError,
self.man.create_stack, self.man.create_stack,
self.ctx, stack_name, self.ctx, stack_name,
stack.t, {}, {}) stack.t, {}, None, {})
def test_stack_validate(self): def test_stack_validate(self):
stack_name = 'service_create_test_validate' stack_name = 'service_create_test_validate'
@ -391,7 +391,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.StubOutWithMock(parser, 'Template') self.m.StubOutWithMock(parser, 'Template')
self.m.StubOutWithMock(environment, 'Environment') 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) environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name, parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack) stack.t, stack.env).AndReturn(stack)
@ -405,7 +405,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.ReplayAll() self.m.ReplayAll()
result = self.man.update_stack(self.ctx, old_stack.identifier(), result = self.man.update_stack(self.ctx, old_stack.identifier(),
template, params, {}) template, params, None, {})
self.assertEqual(result, old_stack.identifier()) self.assertEqual(result, old_stack.identifier())
self.assertTrue(isinstance(result, dict)) self.assertTrue(isinstance(result, dict))
self.assertTrue(result['stack_id']) self.assertTrue(result['stack_id'])
@ -430,7 +430,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.m.StubOutWithMock(parser, 'Template') self.m.StubOutWithMock(parser, 'Template')
self.m.StubOutWithMock(environment, 'Environment') 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) environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name, parser.Stack(self.ctx, stack.name,
stack.t, stack.env).AndReturn(stack) stack.t, stack.env).AndReturn(stack)
@ -445,7 +445,7 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
exception.StackValidationFailed, exception.StackValidationFailed,
self.man.update_stack, self.man.update_stack,
self.ctx, old_stack.identifier(), self.ctx, old_stack.identifier(),
template, params, {}) template, params, None, {})
self.m.VerifyAll() self.m.VerifyAll()
def test_stack_update_nonexist(self): def test_stack_update_nonexist(self):
@ -458,7 +458,8 @@ class stackServiceCreateUpdateDeleteTest(HeatTestCase):
self.assertRaises(exception.StackNotFound, self.assertRaises(exception.StackNotFound,
self.man.update_stack, self.man.update_stack,
self.ctx, stack.identifier(), template, params, {}) self.ctx, stack.identifier(), template, params,
None, {})
self.m.VerifyAll() self.m.VerifyAll()
@ -508,7 +509,8 @@ class stackServiceTest(HeatTestCase):
@stack_context('service_create_existing_test_stack', False) @stack_context('service_create_existing_test_stack', False)
def test_stack_create_existing(self): def test_stack_create_existing(self):
self.assertRaises(exception.StackExists, self.eng.create_stack, 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) @stack_context('service_name_tenants_test_stack', False)
def test_stack_by_name_tenants(self): def test_stack_by_name_tenants(self):

View File

@ -92,6 +92,7 @@ class EngineRpcAPITestCase(testtools.TestCase):
self._test_engine_api('create_stack', 'call', stack_name='wordpress', self._test_engine_api('create_stack', 'call', stack_name='wordpress',
template={u'Foo': u'bar'}, template={u'Foo': u'bar'},
params={u'InstanceType': u'm1.xlarge'}, params={u'InstanceType': u'm1.xlarge'},
files={u'a_file': u'the contents'},
args={'timeout_mins': u'30'}) args={'timeout_mins': u'30'})
def test_update_stack(self): def test_update_stack(self):
@ -99,6 +100,7 @@ class EngineRpcAPITestCase(testtools.TestCase):
stack_identity=self.identity, stack_identity=self.identity,
template={u'Foo': u'bar'}, template={u'Foo': u'bar'},
params={u'InstanceType': u'm1.xlarge'}, params={u'InstanceType': u'm1.xlarge'},
files={},
args={}) args={})
def test_validate_template(self): def test_validate_template(self):