diff --git a/heat/engine/resources/software_config/software_deployment.py b/heat/engine/resources/software_config/software_deployment.py index 496d732e59..aa9e8a94df 100644 --- a/heat/engine/resources/software_config/software_deployment.py +++ b/heat/engine/resources/software_config/software_deployment.py @@ -211,12 +211,15 @@ class SoftwareDeployment(signal_responder.SignalResponder): return derived_config[rpc_api.SOFTWARE_CONFIG_ID] def _handle_action(self, action): - config_id = self.properties.get(self.CONFIG) - config = self.rpc_client().show_software_config( - self.context, config_id) + if self.properties.get(self.CONFIG): + config = self.rpc_client().show_software_config( + self.context, self.properties.get(self.CONFIG)) + else: + config = {} if (action not in self.properties[self.DEPLOY_ACTIONS] - and not config[rpc_api.SOFTWARE_CONFIG_GROUP] == 'component'): + and not config.get( + rpc_api.SOFTWARE_CONFIG_GROUP) == 'component'): return props = self._build_properties( @@ -266,14 +269,14 @@ class SoftwareDeployment(signal_responder.SignalResponder): derived_options = self._build_derived_options(action, source) derived_config = self._build_derived_config( action, source, derived_inputs, derived_options) - derived_name = self.properties.get(self.NAME) or source[scl.NAME] + derived_name = self.properties.get(self.NAME) or source.get(scl.NAME) return { - scl.GROUP: source[scl.GROUP], - scl.CONFIG: derived_config, + scl.GROUP: source.get(scl.GROUP) or 'Heat::Ungrouped', + scl.CONFIG: derived_config or '', scl.OPTIONS: derived_options, scl.INPUTS: derived_inputs, scl.OUTPUTS: source.get(scl.OUTPUTS), - scl.NAME: derived_name + scl.NAME: derived_name or self.physical_resource_name() } def _build_derived_config(self, action, source, diff --git a/heat/tests/test_software_deployment.py b/heat/tests/test_software_deployment.py index a4163e737b..812d03634b 100644 --- a/heat/tests/test_software_deployment.py +++ b/heat/tests/test_software_deployment.py @@ -96,6 +96,20 @@ class SoftwareDeploymentTest(common.HeatTestCase): } } + template_no_config = { + 'HeatTemplateFormatVersion': '2012-12-12', + 'Resources': { + 'deployment_mysql': { + 'Type': 'OS::Heat::SoftwareDeployment', + 'Properties': { + 'server': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', + 'input_values': {'foo': 'bar', 'bink': 'bonk'}, + 'signal_transport': 'NO_SIGNAL', + } + } + } + } + def setUp(self): super(SoftwareDeploymentTest, self).setUp() self.ctx = utils.dummy_context() @@ -295,6 +309,60 @@ class SoftwareDeploymentTest(common.HeatTestCase): 'status_reason': 'Not waiting for outputs signal'}, self.rpc_client.create_software_deployment.call_args[1]) + def test_handle_create_without_config(self): + self._create_stack(self.template_no_config) + sd = self.mock_deployment() + derived_sc = self.mock_derived_software_config() + self.deployment.handle_create() + + self.assertEqual(sd['id'], self.deployment.resource_id) + self.assertEqual({ + 'config': '', + 'group': 'Heat::Ungrouped', + 'name': self.deployment.physical_resource_name(), + 'inputs': [{ + 'name': 'foo', + 'type': 'String', + 'value': 'bar' + }, { + 'name': 'bink', + 'type': 'String', + 'value': 'bonk' + }, { + 'description': 'ID of the server being deployed to', + 'name': 'deploy_server_id', + 'type': 'String', + 'value': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0' + }, { + 'description': 'Name of the current action being deployed', + 'name': 'deploy_action', + 'type': 'String', + 'value': 'CREATE' + }, { + 'description': 'ID of the stack this deployment belongs to', + 'name': 'deploy_stack_id', + 'type': 'String', + 'value': ('software_deployment_test_stack' + '/42f6f66b-631a-44e7-8d01-e22fb54574a9') + }, { + 'description': 'Name of this deployment resource in the stack', + 'name': 'deploy_resource_name', + 'type': 'String', + 'value': 'deployment_mysql' + }], + 'options': None, + 'outputs': None + }, self.rpc_client.create_software_config.call_args[1]) + + self.assertEqual( + {'action': 'CREATE', + 'config_id': derived_sc['id'], + 'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0', + 'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591', + 'status': 'COMPLETE', + 'status_reason': 'Not waiting for outputs signal'}, + self.rpc_client.create_software_deployment.call_args[1]) + def test_handle_create_for_component(self): self._create_stack(self.template_no_signal)