Allow empty 'config' for software deployment

Allow empty 'config' for software deployment resource.
The use case would be for custom agents where the config
is already baked into the image, so these agents would
still want to:
  read input_values to feed into the baked-in config
  signal heat that deployment is complete, including output values

Change-Id: I616640f7fa158576ca65ee7ed4075c38928a81a9
Closes-Bug: #1407387
This commit is contained in:
huangtianhua 2015-01-04 16:04:22 +08:00
parent 5d512ded26
commit 1e82f2c2c3
2 changed files with 79 additions and 8 deletions

View File

@ -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,

View File

@ -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)