Use RPC directly for software config operations
This change replaces heatclient REST calls with RPC calls when creating, fetching or deleting software configs. All resources can now request and RPC client with self.rpc_client() which will create and memoize an EngineClient instance. Change-Id: Id23749e672fd4154e3d9986e22b46fc038579d8e Partial-blueprint: software-config-trigger
This commit is contained in:
parent
bf437d3372
commit
7e1721dff3
|
@ -39,6 +39,7 @@ from heat.engine import rsrc_defn
|
||||||
from heat.engine import scheduler
|
from heat.engine import scheduler
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
from heat.openstack.common import log as logging
|
from heat.openstack.common import log as logging
|
||||||
|
from heat.rpc import client as rpc_client
|
||||||
|
|
||||||
cfg.CONF.import_opt('action_retry_limit', 'heat.common.config')
|
cfg.CONF.import_opt('action_retry_limit', 'heat.common.config')
|
||||||
|
|
||||||
|
@ -177,11 +178,18 @@ class Resource(object):
|
||||||
self._stored_properties_data = None
|
self._stored_properties_data = None
|
||||||
self.created_time = None
|
self.created_time = None
|
||||||
self.updated_time = None
|
self.updated_time = None
|
||||||
|
self._rpc_client = None
|
||||||
|
|
||||||
resource = stack.db_resource_get(name)
|
resource = stack.db_resource_get(name)
|
||||||
if resource:
|
if resource:
|
||||||
self._load_data(resource)
|
self._load_data(resource)
|
||||||
|
|
||||||
|
def rpc_client(self):
|
||||||
|
'''Return a client for making engine RPC calls.'''
|
||||||
|
if not self._rpc_client:
|
||||||
|
self._rpc_client = rpc_client.EngineClient()
|
||||||
|
return self._rpc_client
|
||||||
|
|
||||||
def _load_data(self, resource):
|
def _load_data(self, resource):
|
||||||
'''Load the resource state from its DB representation.'''
|
'''Load the resource state from its DB representation.'''
|
||||||
self.resource_id = resource.nova_instance
|
self.resource_id = resource.nova_instance
|
||||||
|
|
|
@ -30,6 +30,7 @@ from heat.engine import stack_user
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
from heat.openstack.common import log as logging
|
from heat.openstack.common import log as logging
|
||||||
from heat.openstack.common import uuidutils
|
from heat.openstack.common import uuidutils
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
cfg.CONF.import_opt('instance_user', 'heat.common.config')
|
cfg.CONF.import_opt('instance_user', 'heat.common.config')
|
||||||
|
|
||||||
|
@ -469,6 +470,14 @@ class Server(stack_user.StackUser):
|
||||||
return self.properties.get(
|
return self.properties.get(
|
||||||
self.SOFTWARE_CONFIG_TRANSPORT) == self.POLL_TEMP_URL
|
self.SOFTWARE_CONFIG_TRANSPORT) == self.POLL_TEMP_URL
|
||||||
|
|
||||||
|
def get_software_config(self, ud_content):
|
||||||
|
try:
|
||||||
|
sc = self.rpc_client().show_software_config(
|
||||||
|
self.context, ud_content)
|
||||||
|
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||||
|
except exception.NotFound:
|
||||||
|
return ud_content
|
||||||
|
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
security_groups = self.properties.get(self.SECURITY_GROUPS)
|
security_groups = self.properties.get(self.SECURITY_GROUPS)
|
||||||
|
|
||||||
|
@ -477,11 +486,7 @@ class Server(stack_user.StackUser):
|
||||||
if self.user_data_software_config() or self.user_data_raw():
|
if self.user_data_software_config() or self.user_data_raw():
|
||||||
if uuidutils.is_uuid_like(ud_content):
|
if uuidutils.is_uuid_like(ud_content):
|
||||||
# attempt to load the userdata from software config
|
# attempt to load the userdata from software config
|
||||||
try:
|
ud_content = self.get_software_config(ud_content)
|
||||||
ud_content = self.heat().software_configs.get(
|
|
||||||
ud_content).config
|
|
||||||
except Exception as ex:
|
|
||||||
self.client_plugin('heat').ignore_not_found(ex)
|
|
||||||
|
|
||||||
metadata = self.metadata_get(True) or {}
|
metadata = self.metadata_get(True) or {}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from heat.common.template_format import yaml_dumper
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
from heat.engine.resources.software_config import software_config
|
from heat.engine.resources.software_config import software_config
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
|
|
||||||
class CloudConfig(software_config.SoftwareConfig):
|
class CloudConfig(software_config.SoftwareConfig):
|
||||||
|
@ -54,8 +55,8 @@ class CloudConfig(software_config.SoftwareConfig):
|
||||||
cloud_config = yaml.dump(self.properties.get(
|
cloud_config = yaml.dump(self.properties.get(
|
||||||
self.CLOUD_CONFIG), Dumper=yaml_dumper)
|
self.CLOUD_CONFIG), Dumper=yaml_dumper)
|
||||||
props[self.CONFIG] = '#cloud-config\n%s' % cloud_config
|
props[self.CONFIG] = '#cloud-config\n%s' % cloud_config
|
||||||
sc = self.heat().software_configs.create(**props)
|
sc = self.rpc_client().create_software_config(self.context, **props)
|
||||||
self.resource_id_set(sc.id)
|
self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID])
|
||||||
|
|
||||||
|
|
||||||
def resource_mapping():
|
def resource_mapping():
|
||||||
|
|
|
@ -16,11 +16,13 @@ from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from heat.common import exception
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
from heat.engine import constraints
|
from heat.engine import constraints
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
from heat.engine.resources.software_config import software_config
|
from heat.engine.resources.software_config import software_config
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
|
|
||||||
class MultipartMime(software_config.SoftwareConfig):
|
class MultipartMime(software_config.SoftwareConfig):
|
||||||
|
@ -95,8 +97,8 @@ class MultipartMime(software_config.SoftwareConfig):
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
props = {self.NAME: self.physical_resource_name()}
|
props = {self.NAME: self.physical_resource_name()}
|
||||||
props[self.CONFIG] = self.get_message()
|
props[self.CONFIG] = self.get_message()
|
||||||
sc = self.heat().software_configs.create(**props)
|
sc = self.rpc_client().create_software_config(self.context, **props)
|
||||||
self.resource_id_set(sc.id)
|
self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID])
|
||||||
|
|
||||||
def get_message(self):
|
def get_message(self):
|
||||||
if self.message:
|
if self.message:
|
||||||
|
@ -107,10 +109,14 @@ class MultipartMime(software_config.SoftwareConfig):
|
||||||
config = item.get(self.CONFIG)
|
config = item.get(self.CONFIG)
|
||||||
part_type = item.get(self.TYPE, self.TEXT)
|
part_type = item.get(self.TYPE, self.TEXT)
|
||||||
part = config
|
part = config
|
||||||
|
|
||||||
try:
|
try:
|
||||||
part = self.heat().software_configs.get(config).config
|
sc = self.rpc_client().show_software_config(
|
||||||
except Exception as ex:
|
self.context, self.resource_id)
|
||||||
self.client_plugin().ignore_not_found(ex)
|
except exception.NotFound:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
part = sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||||
|
|
||||||
if part_type == self.MULTIPART:
|
if part_type == self.MULTIPART:
|
||||||
self._append_multiparts(subparts, part)
|
self._append_multiparts(subparts, part)
|
||||||
|
|
|
@ -18,6 +18,7 @@ from heat.engine import properties
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
from heat.engine.resources.software_config import software_config as sc
|
from heat.engine.resources.software_config import software_config as sc
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
|
|
||||||
class SoftwareComponent(sc.SoftwareConfig):
|
class SoftwareComponent(sc.SoftwareConfig):
|
||||||
|
@ -116,8 +117,8 @@ class SoftwareComponent(sc.SoftwareConfig):
|
||||||
# set 'group' to enable component processing by in-instance hook
|
# set 'group' to enable component processing by in-instance hook
|
||||||
props[self.GROUP] = 'component'
|
props[self.GROUP] = 'component'
|
||||||
|
|
||||||
sc = self.heat().software_configs.create(**props)
|
sc = self.rpc_client().create_software_config(self.context, **props)
|
||||||
self.resource_id_set(sc.id)
|
self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID])
|
||||||
|
|
||||||
def _resolve_attribute(self, name):
|
def _resolve_attribute(self, name):
|
||||||
'''
|
'''
|
||||||
|
@ -129,14 +130,13 @@ class SoftwareComponent(sc.SoftwareConfig):
|
||||||
'''
|
'''
|
||||||
if name == self.CONFIGS_ATTR and self.resource_id:
|
if name == self.CONFIGS_ATTR and self.resource_id:
|
||||||
try:
|
try:
|
||||||
config = self.heat().software_configs.get(self.resource_id).\
|
sc = self.rpc_client().show_software_config(
|
||||||
config
|
self.context, self.resource_id)
|
||||||
# configs list is stored in 'config' property of parent class
|
# configs list is stored in 'config' property of parent class
|
||||||
# (see handle_create)
|
# (see handle_create)
|
||||||
return config.get(self.CONFIGS)
|
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG].get(self.CONFIGS)
|
||||||
except Exception as ex:
|
except exception.NotFound:
|
||||||
if self.client_plugin().is_not_found(ex):
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
'''Validate SoftwareComponent properties consistency.'''
|
'''Validate SoftwareComponent properties consistency.'''
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from heat.common import exception
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
from heat.engine import attributes
|
from heat.engine import attributes
|
||||||
from heat.engine import constraints
|
from heat.engine import constraints
|
||||||
|
@ -18,6 +19,7 @@ from heat.engine import properties
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
from heat.openstack.common import log as logging
|
from heat.openstack.common import log as logging
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -152,14 +154,12 @@ class SoftwareConfig(resource.Resource):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
default_client_name = 'heat'
|
|
||||||
|
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
props = dict(self.properties)
|
props = dict(self.properties)
|
||||||
props[self.NAME] = self.physical_resource_name()
|
props[self.NAME] = self.physical_resource_name()
|
||||||
|
|
||||||
sc = self.heat().software_configs.create(**props)
|
sc = self.rpc_client().create_software_config(self.context, **props)
|
||||||
self.resource_id_set(sc.id)
|
self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID])
|
||||||
|
|
||||||
def handle_delete(self):
|
def handle_delete(self):
|
||||||
|
|
||||||
|
@ -167,9 +167,10 @@ class SoftwareConfig(resource.Resource):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.heat().software_configs.delete(self.resource_id)
|
self.rpc_client().delete_software_config(
|
||||||
except Exception as ex:
|
self.context, self.resource_id)
|
||||||
self.client_plugin().ignore_not_found(ex)
|
except exception.NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
def _resolve_attribute(self, name):
|
def _resolve_attribute(self, name):
|
||||||
'''
|
'''
|
||||||
|
@ -178,11 +179,11 @@ class SoftwareConfig(resource.Resource):
|
||||||
'''
|
'''
|
||||||
if name == self.CONFIG_ATTR and self.resource_id:
|
if name == self.CONFIG_ATTR and self.resource_id:
|
||||||
try:
|
try:
|
||||||
return self.heat().software_configs.get(
|
sc = self.rpc_client().show_software_config(
|
||||||
self.resource_id).config
|
self.context, self.resource_id)
|
||||||
except Exception as ex:
|
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
|
||||||
if self.client_plugin().is_not_found(ex):
|
except exception.NotFound:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def resource_mapping():
|
def resource_mapping():
|
||||||
|
|
|
@ -26,6 +26,7 @@ from heat.engine.resources.software_config import software_config as sc
|
||||||
from heat.engine import signal_responder
|
from heat.engine import signal_responder
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
from heat.openstack.common import log as logging
|
from heat.openstack.common import log as logging
|
||||||
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -194,23 +195,26 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||||
|
|
||||||
def _delete_derived_config(self, derived_config_id):
|
def _delete_derived_config(self, derived_config_id):
|
||||||
try:
|
try:
|
||||||
self.heat().software_configs.delete(derived_config_id)
|
self.rpc_client().delete_software_config(
|
||||||
except Exception as ex:
|
self.context, derived_config_id)
|
||||||
self.client_plugin().ignore_not_found(ex)
|
except exception.NotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
def _get_derived_config(self, action, source_config):
|
def _get_derived_config(self, action, source_config):
|
||||||
|
|
||||||
derived_params = self._build_derived_config_params(
|
derived_params = self._build_derived_config_params(
|
||||||
action, source_config.to_dict())
|
action, source_config)
|
||||||
derived_config = self.heat().software_configs.create(**derived_params)
|
derived_config = self.rpc_client().create_software_config(
|
||||||
return derived_config.id
|
self.context, **derived_params)
|
||||||
|
return derived_config[rpc_api.SOFTWARE_CONFIG_ID]
|
||||||
|
|
||||||
def _handle_action(self, action):
|
def _handle_action(self, action):
|
||||||
config_id = self.properties.get(self.CONFIG)
|
config_id = self.properties.get(self.CONFIG)
|
||||||
config = self.heat().software_configs.get(config_id)
|
config = self.rpc_client().show_software_config(
|
||||||
|
self.context, config_id)
|
||||||
|
|
||||||
if action not in self.properties[self.DEPLOY_ACTIONS]\
|
if action not in self.properties[self.DEPLOY_ACTIONS]\
|
||||||
and not config.group == 'component':
|
and not config[rpc_api.SOFTWARE_CONFIG_GROUP] == 'component':
|
||||||
return
|
return
|
||||||
|
|
||||||
props = self._build_properties(
|
props = self._build_properties(
|
||||||
|
@ -430,7 +434,8 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||||
|
|
||||||
def handle_signal(self, details):
|
def handle_signal(self, details):
|
||||||
sd = self.heat().software_deployments.get(self.resource_id)
|
sd = self.heat().software_deployments.get(self.resource_id)
|
||||||
sc = self.heat().software_configs.get(self.properties[self.CONFIG])
|
sc = self.rpc_client().show_software_config(
|
||||||
|
self.context, self.properties[self.CONFIG])
|
||||||
if not sd.status == self.IN_PROGRESS:
|
if not sd.status == self.IN_PROGRESS:
|
||||||
# output values are only expected when in an IN_PROGRESS state
|
# output values are only expected when in an IN_PROGRESS state
|
||||||
return
|
return
|
||||||
|
@ -450,7 +455,7 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||||
else:
|
else:
|
||||||
event_reason = 'deployment succeeded'
|
event_reason = 'deployment succeeded'
|
||||||
|
|
||||||
for output in sc.outputs or []:
|
for output in sc[rpc_api.SOFTWARE_CONFIG_OUTPUTS] or []:
|
||||||
out_key = output['name']
|
out_key = output['name']
|
||||||
if out_key in details:
|
if out_key in details:
|
||||||
ov[out_key] = details[out_key]
|
ov[out_key] = details[out_key]
|
||||||
|
@ -486,8 +491,10 @@ class SoftwareDeployment(signal_responder.SignalResponder):
|
||||||
|
|
||||||
# Since there is no value for this key yet, check the output schemas
|
# Since there is no value for this key yet, check the output schemas
|
||||||
# to find out if the key is valid
|
# to find out if the key is valid
|
||||||
sc = self.heat().software_configs.get(self.properties[self.CONFIG])
|
sc = self.rpc_client().show_software_config(
|
||||||
output_keys = [output['name'] for output in sc.outputs]
|
self.context, self.properties[self.CONFIG])
|
||||||
|
outputs = sc[rpc_api.SOFTWARE_CONFIG_OUTPUTS] or []
|
||||||
|
output_keys = [output['name'] for output in outputs]
|
||||||
if key not in output_keys and key not in self.ATTRIBUTES:
|
if key not in output_keys and key not in self.ATTRIBUTES:
|
||||||
raise exception.InvalidTemplateAttribute(resource=self.name,
|
raise exception.InvalidTemplateAttribute(resource=self.name,
|
||||||
key=key)
|
key=key)
|
||||||
|
|
|
@ -38,9 +38,8 @@ class CloudConfigTest(common.HeatTestCase):
|
||||||
'Properties': self.properties
|
'Properties': self.properties
|
||||||
}}}))
|
}}}))
|
||||||
self.config = self.stack['config_mysql']
|
self.config = self.stack['config_mysql']
|
||||||
heat = mock.MagicMock()
|
self.rpc_client = mock.MagicMock()
|
||||||
self.config.heat = heat
|
self.config._rpc_client = self.rpc_client
|
||||||
self.software_configs = heat.return_value.software_configs
|
|
||||||
|
|
||||||
def test_resource_mapping(self):
|
def test_resource_mapping(self):
|
||||||
mapping = cc.resource_mapping()
|
mapping = cc.resource_mapping()
|
||||||
|
@ -50,11 +49,10 @@ class CloudConfigTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.config, cc.CloudConfig)
|
self.assertIsInstance(self.config, cc.CloudConfig)
|
||||||
|
|
||||||
def test_handle_create(self):
|
def test_handle_create(self):
|
||||||
sc = mock.MagicMock()
|
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
sc.id = config_id
|
value = {'id': config_id}
|
||||||
self.software_configs.create.return_value = sc
|
self.rpc_client.create_software_config.return_value = value
|
||||||
self.config.handle_create()
|
self.config.handle_create()
|
||||||
self.assertEqual(config_id, self.config.resource_id)
|
self.assertEqual(config_id, self.config.resource_id)
|
||||||
kwargs = self.software_configs.create.call_args[1]
|
kwargs = self.rpc_client.create_software_config.call_args[1]
|
||||||
self.assertEqual('#cloud-config\n{foo: bar}\n', kwargs['config'])
|
self.assertEqual('#cloud-config\n{foo: bar}\n', kwargs['config'])
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
|
|
||||||
import email
|
import email
|
||||||
|
|
||||||
import heatclient.exc as exc
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from heat.common import exception as exc
|
||||||
from heat.engine import parser
|
from heat.engine import parser
|
||||||
from heat.engine.resources.software_config import multi_part as mp
|
from heat.engine.resources.software_config import multi_part as mp
|
||||||
from heat.engine import template
|
from heat.engine import template
|
||||||
|
@ -43,9 +43,8 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
'parts': parts
|
'parts': parts
|
||||||
}}}}))
|
}}}}))
|
||||||
self.config = stack['config_mysql']
|
self.config = stack['config_mysql']
|
||||||
heat = mock.MagicMock()
|
self.rpc_client = mock.MagicMock()
|
||||||
self.config.heat = heat
|
self.config._rpc_client = self.rpc_client
|
||||||
self.software_configs = heat.return_value.software_configs
|
|
||||||
|
|
||||||
def test_resource_mapping(self):
|
def test_resource_mapping(self):
|
||||||
mapping = mp.resource_mapping()
|
mapping = mp.resource_mapping()
|
||||||
|
@ -55,13 +54,12 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.config, mp.MultipartMime)
|
self.assertIsInstance(self.config, mp.MultipartMime)
|
||||||
|
|
||||||
def test_handle_create(self):
|
def test_handle_create(self):
|
||||||
sc = mock.MagicMock()
|
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
sc.id = config_id
|
sc = {'id': config_id}
|
||||||
self.software_configs.create.return_value = sc
|
self.rpc_client.create_software_config.return_value = sc
|
||||||
self.config.handle_create()
|
self.config.handle_create()
|
||||||
self.assertEqual(config_id, self.config.resource_id)
|
self.assertEqual(config_id, self.config.resource_id)
|
||||||
args = self.software_configs.create.call_args[1]
|
args = self.rpc_client.create_software_config.call_args[1]
|
||||||
self.assertEqual(self.config.message, args['config'])
|
self.assertEqual(self.config.message, args['config'])
|
||||||
|
|
||||||
def test_get_message_not_none(self):
|
def test_get_message_not_none(self):
|
||||||
|
@ -82,7 +80,9 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
'type': 'text'
|
'type': 'text'
|
||||||
}]
|
}]
|
||||||
self.init_config(parts=parts)
|
self.init_config(parts=parts)
|
||||||
self.software_configs.get.return_value.config = '#!/bin/bash'
|
self.rpc_client.show_software_config.return_value = {
|
||||||
|
'config': '#!/bin/bash'
|
||||||
|
}
|
||||||
result = self.config.get_message()
|
result = self.config.get_message()
|
||||||
message = email.message_from_string(result)
|
message = email.message_from_string(result)
|
||||||
self.assertTrue(message.is_multipart())
|
self.assertTrue(message.is_multipart())
|
||||||
|
@ -96,7 +96,7 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
'type': 'text'
|
'type': 'text'
|
||||||
}]
|
}]
|
||||||
self.init_config(parts=parts)
|
self.init_config(parts=parts)
|
||||||
self.software_configs.get.side_effect = exc.HTTPNotFound()
|
self.rpc_client.show_software_config.side_effect = exc.NotFound()
|
||||||
result = self.config.get_message()
|
result = self.config.get_message()
|
||||||
message = email.message_from_string(result)
|
message = email.message_from_string(result)
|
||||||
self.assertTrue(message.is_multipart())
|
self.assertTrue(message.is_multipart())
|
||||||
|
@ -111,7 +111,9 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
'filename': '/opt/stack/configure.d/55-heat-config'
|
'filename': '/opt/stack/configure.d/55-heat-config'
|
||||||
}]
|
}]
|
||||||
self.init_config(parts=parts)
|
self.init_config(parts=parts)
|
||||||
self.software_configs.get.return_value.config = '#!/bin/bash'
|
self.rpc_client.show_software_config.return_value = {
|
||||||
|
'config': '#!/bin/bash'
|
||||||
|
}
|
||||||
result = self.config.get_message()
|
result = self.config.get_message()
|
||||||
message = email.message_from_string(result)
|
message = email.message_from_string(result)
|
||||||
self.assertTrue(message.is_multipart())
|
self.assertTrue(message.is_multipart())
|
||||||
|
@ -138,7 +140,11 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
'type': 'multipart'
|
'type': 'multipart'
|
||||||
}]
|
}]
|
||||||
self.init_config(parts=parts)
|
self.init_config(parts=parts)
|
||||||
self.software_configs.get.return_value.config = multipart
|
|
||||||
|
self.rpc_client.show_software_config.return_value = {
|
||||||
|
'config': multipart
|
||||||
|
}
|
||||||
|
|
||||||
result = self.config.get_message()
|
result = self.config.get_message()
|
||||||
message = email.message_from_string(result)
|
message = email.message_from_string(result)
|
||||||
self.assertTrue(message.is_multipart())
|
self.assertTrue(message.is_multipart())
|
||||||
|
@ -155,7 +161,9 @@ class MultipartMimeTest(common.HeatTestCase):
|
||||||
{'config': '9cab10ef-16ce-4be9-8b25-a67b7313eddb',
|
{'config': '9cab10ef-16ce-4be9-8b25-a67b7313eddb',
|
||||||
'type': 'text'}]
|
'type': 'text'}]
|
||||||
self.init_config(parts=parts)
|
self.init_config(parts=parts)
|
||||||
self.software_configs.get.return_value.config = '#!/bin/bash'
|
self.rpc_client.show_software_config.return_value = {
|
||||||
|
'config': '#!/bin/bash'
|
||||||
|
}
|
||||||
result = self.config.get_message()
|
result = self.config.get_message()
|
||||||
message = email.message_from_string(result)
|
message = email.message_from_string(result)
|
||||||
self.assertTrue(message.is_multipart())
|
self.assertTrue(message.is_multipart())
|
||||||
|
|
|
@ -26,7 +26,6 @@ from heat.common.i18n import _
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
from heat.db import api as db_api
|
from heat.db import api as db_api
|
||||||
from heat.engine.clients.os import glance
|
from heat.engine.clients.os import glance
|
||||||
from heat.engine.clients.os import heat_plugin
|
|
||||||
from heat.engine.clients.os import nova
|
from heat.engine.clients.os import nova
|
||||||
from heat.engine.clients.os import swift
|
from heat.engine.clients.os import swift
|
||||||
from heat.engine import environment
|
from heat.engine import environment
|
||||||
|
@ -531,12 +530,11 @@ class ServersTest(common.HeatTestCase):
|
||||||
server = servers.Server('WebServer',
|
server = servers.Server('WebServer',
|
||||||
resource_defns['WebServer'], stack)
|
resource_defns['WebServer'], stack)
|
||||||
|
|
||||||
self.m.StubOutWithMock(heat_plugin.HeatClientPlugin, '_create')
|
self.rpc_client = mock.MagicMock()
|
||||||
heat_client = mock.Mock()
|
server._rpc_client = self.rpc_client
|
||||||
heat_plugin.HeatClientPlugin._create().AndReturn(heat_client)
|
|
||||||
sc = mock.Mock()
|
sc = {'config': 'wordpress from config'}
|
||||||
sc.config = 'wordpress from config'
|
self.rpc_client.show_software_config.return_value = sc
|
||||||
heat_client.software_configs.get.return_value = sc
|
|
||||||
|
|
||||||
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
|
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
|
||||||
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
||||||
|
@ -572,11 +570,10 @@ class ServersTest(common.HeatTestCase):
|
||||||
server = servers.Server('WebServer',
|
server = servers.Server('WebServer',
|
||||||
resource_defns['WebServer'], stack)
|
resource_defns['WebServer'], stack)
|
||||||
|
|
||||||
self.m.StubOutWithMock(heat_plugin.HeatClientPlugin, '_create')
|
self.rpc_client = mock.MagicMock()
|
||||||
heat_client = mock.Mock()
|
server._rpc_client = self.rpc_client
|
||||||
heat_plugin.HeatClientPlugin._create().AndReturn(heat_client)
|
|
||||||
heat_client.software_configs.get.side_effect = \
|
self.rpc_client.show_software_config.side_effect = exception.NotFound
|
||||||
heat_plugin.exc.HTTPNotFound()
|
|
||||||
|
|
||||||
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
|
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
|
||||||
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
nova.NovaClientPlugin._create().AndReturn(self.fc)
|
||||||
|
|
|
@ -14,14 +14,13 @@
|
||||||
import mock
|
import mock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from heat.common import exception
|
from heat.common import exception as exc
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
from heat.engine.resources.software_config import software_component as sc
|
from heat.engine.resources.software_config import software_component as sc
|
||||||
from heat.engine import stack
|
from heat.engine import stack
|
||||||
from heat.engine import template
|
from heat.engine import template
|
||||||
from heat.tests import common
|
from heat.tests import common
|
||||||
from heat.tests import utils
|
from heat.tests import utils
|
||||||
from heatclient.exc import HTTPNotFound
|
|
||||||
|
|
||||||
|
|
||||||
class SoftwareComponentTest(common.HeatTestCase):
|
class SoftwareComponentTest(common.HeatTestCase):
|
||||||
|
@ -58,11 +57,8 @@ class SoftwareComponentTest(common.HeatTestCase):
|
||||||
self.ctx, 'software_component_test_stack',
|
self.ctx, 'software_component_test_stack',
|
||||||
template.Template(self.template))
|
template.Template(self.template))
|
||||||
self.component = self.stack['mysql_component']
|
self.component = self.stack['mysql_component']
|
||||||
heat = mock.MagicMock()
|
self.rpc_client = mock.MagicMock()
|
||||||
self.heatclient = mock.MagicMock()
|
self.component._rpc_client = self.rpc_client
|
||||||
self.component.heat = heat
|
|
||||||
heat.return_value = self.heatclient
|
|
||||||
self.software_configs = self.heatclient.software_configs
|
|
||||||
|
|
||||||
def test_resource_mapping(self):
|
def test_resource_mapping(self):
|
||||||
mapping = sc.resource_mapping()
|
mapping = sc.resource_mapping()
|
||||||
|
@ -72,10 +68,9 @@ class SoftwareComponentTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.component, sc.SoftwareComponent)
|
self.assertIsInstance(self.component, sc.SoftwareComponent)
|
||||||
|
|
||||||
def test_handle_create(self):
|
def test_handle_create(self):
|
||||||
value = mock.MagicMock()
|
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
value.id = config_id
|
value = {'id': config_id}
|
||||||
self.software_configs.create.return_value = value
|
self.rpc_client.create_software_config.return_value = value
|
||||||
self.component.handle_create()
|
self.component.handle_create()
|
||||||
self.assertEqual(config_id, self.component.resource_id)
|
self.assertEqual(config_id, self.component.resource_id)
|
||||||
|
|
||||||
|
@ -84,9 +79,9 @@ class SoftwareComponentTest(common.HeatTestCase):
|
||||||
self.assertIsNone(self.component.handle_delete())
|
self.assertIsNone(self.component.handle_delete())
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
self.component.resource_id = config_id
|
self.component.resource_id = config_id
|
||||||
self.software_configs.delete.return_value = None
|
self.rpc_client.delete_software_config.return_value = None
|
||||||
self.assertIsNone(self.component.handle_delete())
|
self.assertIsNone(self.component.handle_delete())
|
||||||
self.software_configs.delete.side_effect = HTTPNotFound()
|
self.rpc_client.delete_software_config.side_effect = exc.NotFound
|
||||||
self.assertIsNone(self.component.handle_delete())
|
self.assertIsNone(self.component.handle_delete())
|
||||||
|
|
||||||
def test_resolve_attribute(self):
|
def test_resolve_attribute(self):
|
||||||
|
@ -94,14 +89,13 @@ class SoftwareComponentTest(common.HeatTestCase):
|
||||||
self.component.resource_id = None
|
self.component.resource_id = None
|
||||||
self.assertIsNone(self.component._resolve_attribute('configs'))
|
self.assertIsNone(self.component._resolve_attribute('configs'))
|
||||||
self.component.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
self.component.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
value = mock.MagicMock()
|
|
||||||
configs = self.\
|
configs = self.\
|
||||||
template['resources']['mysql_component']['properties']['configs']
|
template['resources']['mysql_component']['properties']['configs']
|
||||||
# configs list is stored in 'config' property of SoftwareConfig
|
# configs list is stored in 'config' property of SoftwareConfig
|
||||||
value.config = {'configs': configs}
|
value = {'config': {'configs': configs}}
|
||||||
self.software_configs.get.return_value = value
|
self.rpc_client.show_software_config.return_value = value
|
||||||
self.assertEqual(configs, self.component._resolve_attribute('configs'))
|
self.assertEqual(configs, self.component._resolve_attribute('configs'))
|
||||||
self.software_configs.get.side_effect = HTTPNotFound()
|
self.rpc_client.show_software_config.side_effect = exc.NotFound
|
||||||
self.assertIsNone(self.component._resolve_attribute('configs'))
|
self.assertIsNone(self.component._resolve_attribute('configs'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +154,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
echo CREATE $foo
|
echo CREATE $foo
|
||||||
tool: script
|
tool: script
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='Unknown Property config')
|
err_msg='Unknown Property config')
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -172,7 +166,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
inputs:
|
inputs:
|
||||||
- name: foo
|
- name: foo
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='Property configs not assigned')
|
err_msg='Property configs not assigned')
|
||||||
),
|
),
|
||||||
# do not test until bug #1350840
|
# do not test until bug #1350840
|
||||||
|
@ -199,7 +193,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
config: #!/bin/bash
|
config: #!/bin/bash
|
||||||
tool: script
|
tool: script
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='is not a list')
|
err_msg='is not a list')
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -213,7 +207,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
config: #!/bin/bash
|
config: #!/bin/bash
|
||||||
tool: script
|
tool: script
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='actions length (0) is out of range '
|
err_msg='actions length (0) is out of range '
|
||||||
'(min: 1, max: None)')
|
'(min: 1, max: None)')
|
||||||
),
|
),
|
||||||
|
@ -231,7 +225,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
config: #!/bin/bash
|
config: #!/bin/bash
|
||||||
tool: script
|
tool: script
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='Defining more than one configuration for the same '
|
err_msg='Defining more than one configuration for the same '
|
||||||
'action in SoftwareComponent "component" is not '
|
'action in SoftwareComponent "component" is not '
|
||||||
'allowed.')
|
'allowed.')
|
||||||
|
@ -250,7 +244,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
config: #!/bin/bash
|
config: #!/bin/bash
|
||||||
tool: script
|
tool: script
|
||||||
''',
|
''',
|
||||||
err=exception.StackValidationFailed,
|
err=exc.StackValidationFailed,
|
||||||
err_msg='Defining more than one configuration for the same '
|
err_msg='Defining more than one configuration for the same '
|
||||||
'action in SoftwareComponent "component" is not '
|
'action in SoftwareComponent "component" is not '
|
||||||
'allowed.')
|
'allowed.')
|
||||||
|
@ -272,11 +266,7 @@ class SoftwareComponentValidationTest(common.HeatTestCase):
|
||||||
self.ctx, 'software_component_test_stack',
|
self.ctx, 'software_component_test_stack',
|
||||||
template.Template(self.template))
|
template.Template(self.template))
|
||||||
self.component = self.stack['component']
|
self.component = self.stack['component']
|
||||||
heat = mock.MagicMock()
|
self.component._rpc_client = mock.MagicMock()
|
||||||
self.heatclient = mock.MagicMock()
|
|
||||||
self.component.heat = heat
|
|
||||||
heat.return_value = self.heatclient
|
|
||||||
self.software_configs = self.heatclient.software_configs
|
|
||||||
|
|
||||||
def test_properties_schema(self):
|
def test_properties_schema(self):
|
||||||
if self.err:
|
if self.err:
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from heatclient.exc import HTTPNotFound
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from heat.common import exception as exc
|
||||||
from heat.engine import parser
|
from heat.engine import parser
|
||||||
from heat.engine.resources.software_config import software_config as sc
|
from heat.engine.resources.software_config import software_config as sc
|
||||||
from heat.engine import template
|
from heat.engine import template
|
||||||
|
@ -43,11 +43,8 @@ class SoftwareConfigTest(common.HeatTestCase):
|
||||||
'Properties': self.properties
|
'Properties': self.properties
|
||||||
}}}))
|
}}}))
|
||||||
self.config = self.stack['config_mysql']
|
self.config = self.stack['config_mysql']
|
||||||
heat = mock.MagicMock()
|
self.rpc_client = mock.MagicMock()
|
||||||
self.heatclient = mock.MagicMock()
|
self.config._rpc_client = self.rpc_client
|
||||||
self.config.heat = heat
|
|
||||||
heat.return_value = self.heatclient
|
|
||||||
self.software_configs = self.heatclient.software_configs
|
|
||||||
|
|
||||||
def test_resource_mapping(self):
|
def test_resource_mapping(self):
|
||||||
mapping = sc.resource_mapping()
|
mapping = sc.resource_mapping()
|
||||||
|
@ -57,10 +54,9 @@ class SoftwareConfigTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.config, sc.SoftwareConfig)
|
self.assertIsInstance(self.config, sc.SoftwareConfig)
|
||||||
|
|
||||||
def test_handle_create(self):
|
def test_handle_create(self):
|
||||||
value = mock.MagicMock()
|
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
value.id = config_id
|
value = {'id': config_id}
|
||||||
self.software_configs.create.return_value = value
|
self.rpc_client.create_software_config.return_value = value
|
||||||
self.config.handle_create()
|
self.config.handle_create()
|
||||||
self.assertEqual(config_id, self.config.resource_id)
|
self.assertEqual(config_id, self.config.resource_id)
|
||||||
|
|
||||||
|
@ -69,9 +65,9 @@ class SoftwareConfigTest(common.HeatTestCase):
|
||||||
self.assertIsNone(self.config.handle_delete())
|
self.assertIsNone(self.config.handle_delete())
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
self.config.resource_id = config_id
|
self.config.resource_id = config_id
|
||||||
self.software_configs.delete.return_value = None
|
self.rpc_client.delete_software_config.return_value = None
|
||||||
self.assertIsNone(self.config.handle_delete())
|
self.assertIsNone(self.config.handle_delete())
|
||||||
self.software_configs.delete.side_effect = HTTPNotFound()
|
self.rpc_client.delete_software_config.side_effect = exc.NotFound
|
||||||
self.assertIsNone(self.config.handle_delete())
|
self.assertIsNone(self.config.handle_delete())
|
||||||
|
|
||||||
def test_resolve_attribute(self):
|
def test_resolve_attribute(self):
|
||||||
|
@ -79,10 +75,9 @@ class SoftwareConfigTest(common.HeatTestCase):
|
||||||
self.config.resource_id = None
|
self.config.resource_id = None
|
||||||
self.assertIsNone(self.config._resolve_attribute('config'))
|
self.assertIsNone(self.config._resolve_attribute('config'))
|
||||||
self.config.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
self.config.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
value = mock.MagicMock()
|
value = {'config': '#!/bin/bash'}
|
||||||
value.config = '#!/bin/bash'
|
self.rpc_client.show_software_config.return_value = value
|
||||||
self.software_configs.get.return_value = value
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'#!/bin/bash', self.config._resolve_attribute('config'))
|
'#!/bin/bash', self.config._resolve_attribute('config'))
|
||||||
self.software_configs.get.side_effect = HTTPNotFound()
|
self.rpc_client.show_software_config.side_effect = exc.NotFound
|
||||||
self.assertEqual(None, self.config._resolve_attribute('config'))
|
self.assertEqual(None, self.config._resolve_attribute('config'))
|
||||||
|
|
|
@ -17,7 +17,7 @@ import copy
|
||||||
import mock
|
import mock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from heat.common import exception
|
from heat.common import exception as exc
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
from heat.engine import parser
|
from heat.engine import parser
|
||||||
from heat.engine.resources.software_config import software_deployment as sd
|
from heat.engine.resources.software_config import software_deployment as sd
|
||||||
|
@ -117,10 +117,13 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
get_signed_url.return_value = 'http://192.0.2.2/signed_url'
|
get_signed_url.return_value = 'http://192.0.2.2/signed_url'
|
||||||
|
|
||||||
self.deployment = self.stack['deployment_mysql']
|
self.deployment = self.stack['deployment_mysql']
|
||||||
|
|
||||||
|
self.rpc_client = mock.MagicMock()
|
||||||
|
self.deployment._rpc_client = self.rpc_client
|
||||||
|
|
||||||
heat = mock.MagicMock()
|
heat = mock.MagicMock()
|
||||||
self.deployment.heat = heat
|
self.deployment.heat = heat
|
||||||
self.deployments = heat.return_value.software_deployments
|
self.deployments = heat.return_value.software_deployments
|
||||||
self.software_configs = heat.return_value.software_configs
|
|
||||||
|
|
||||||
def test_validate(self):
|
def test_validate(self):
|
||||||
template = dict(self.template_with_server)
|
template = dict(self.template_with_server)
|
||||||
|
@ -138,7 +141,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
props['user_data_format'] = 'RAW'
|
props['user_data_format'] = 'RAW'
|
||||||
self._create_stack(template)
|
self._create_stack(template)
|
||||||
sd = self.deployment
|
sd = self.deployment
|
||||||
err = self.assertRaises(exception.StackValidationFailed, sd.validate)
|
err = self.assertRaises(exc.StackValidationFailed, sd.validate)
|
||||||
self.assertEqual("Resource server's property "
|
self.assertEqual("Resource server's property "
|
||||||
"user_data_format should be set to "
|
"user_data_format should be set to "
|
||||||
"SOFTWARE_CONFIG since there are "
|
"SOFTWARE_CONFIG since there are "
|
||||||
|
@ -149,7 +152,6 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.deployment, sd.SoftwareDeployment)
|
self.assertIsInstance(self.deployment, sd.SoftwareDeployment)
|
||||||
|
|
||||||
def mock_software_config(self):
|
def mock_software_config(self):
|
||||||
sc = mock.MagicMock()
|
|
||||||
config = {
|
config = {
|
||||||
'id': '48e8ade1-9196-42d5-89a2-f709fde42632',
|
'id': '48e8ade1-9196-42d5-89a2-f709fde42632',
|
||||||
'group': 'Test::Group',
|
'group': 'Test::Group',
|
||||||
|
@ -167,14 +169,10 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
}],
|
}],
|
||||||
'outputs': [],
|
'outputs': [],
|
||||||
}
|
}
|
||||||
sc.to_dict.return_value = config
|
self.rpc_client.show_software_config.return_value = config
|
||||||
sc.group = 'Test::Group'
|
return config
|
||||||
sc.config = config['config']
|
|
||||||
self.software_configs.get.return_value = sc
|
|
||||||
return sc
|
|
||||||
|
|
||||||
def mock_software_component(self):
|
def mock_software_component(self):
|
||||||
sc = mock.MagicMock()
|
|
||||||
config = {
|
config = {
|
||||||
'id': '48e8ade1-9196-42d5-89a2-f709fde42632',
|
'id': '48e8ade1-9196-42d5-89a2-f709fde42632',
|
||||||
'group': 'component',
|
'group': 'component',
|
||||||
|
@ -220,16 +218,12 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
}],
|
}],
|
||||||
'outputs': [],
|
'outputs': [],
|
||||||
}
|
}
|
||||||
sc.to_dict.return_value = config
|
self.rpc_client.show_software_config.return_value = config
|
||||||
sc.group = 'component'
|
return config
|
||||||
sc.config = config['config']
|
|
||||||
self.software_configs.get.return_value = sc
|
|
||||||
return sc
|
|
||||||
|
|
||||||
def mock_derived_software_config(self):
|
def mock_derived_software_config(self):
|
||||||
sc = mock.MagicMock()
|
sc = {'id': '9966c8e7-bc9c-42de-aa7d-f2447a952cb2'}
|
||||||
sc.id = '9966c8e7-bc9c-42de-aa7d-f2447a952cb2'
|
self.rpc_client.create_software_config.return_value = sc
|
||||||
self.software_configs.create.return_value = sc
|
|
||||||
return sc
|
return sc
|
||||||
|
|
||||||
def mock_deployment(self):
|
def mock_deployment(self):
|
||||||
|
@ -290,11 +284,11 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
}],
|
}],
|
||||||
'options': {},
|
'options': {},
|
||||||
'outputs': []
|
'outputs': []
|
||||||
}, self.software_configs.create.call_args[1])
|
}, self.rpc_client.create_software_config.call_args[1])
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'action': 'CREATE',
|
{'action': 'CREATE',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'COMPLETE',
|
'status': 'COMPLETE',
|
||||||
|
@ -381,11 +375,11 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
}],
|
}],
|
||||||
'options': {},
|
'options': {},
|
||||||
'outputs': []
|
'outputs': []
|
||||||
}, self.software_configs.create.call_args[1])
|
}, self.rpc_client.create_software_config.call_args[1])
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'action': 'CREATE',
|
{'action': 'CREATE',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'COMPLETE',
|
'status': 'COMPLETE',
|
||||||
|
@ -404,7 +398,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
args = self.deployments.create.call_args[1]
|
args = self.deployments.create.call_args[1]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'action': 'CREATE',
|
{'action': 'CREATE',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'IN_PROGRESS',
|
'status': 'IN_PROGRESS',
|
||||||
|
@ -449,7 +443,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
sd.status = self.deployment.FAILED
|
sd.status = self.deployment.FAILED
|
||||||
sd.status_reason = 'something wrong'
|
sd.status_reason = 'something wrong'
|
||||||
err = self.assertRaises(
|
err = self.assertRaises(
|
||||||
exception.Error, self.deployment.check_create_complete, sd)
|
exc.Error, self.deployment.check_create_complete, sd)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'Deployment to server failed: something wrong', six.text_type(err))
|
'Deployment to server failed: something wrong', six.text_type(err))
|
||||||
|
|
||||||
|
@ -479,7 +473,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
args = sd.update.call_args[1]
|
args = sd.update.call_args[1]
|
||||||
self.assertEqual({
|
self.assertEqual({
|
||||||
'action': 'DELETE',
|
'action': 'DELETE',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'IN_PROGRESS',
|
'status': 'IN_PROGRESS',
|
||||||
|
@ -499,14 +493,15 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
self.mock_software_config()
|
self.mock_software_config()
|
||||||
derived_sc = self.mock_derived_software_config()
|
derived_sc = self.mock_derived_software_config()
|
||||||
sd = self.mock_deployment()
|
sd = self.mock_deployment()
|
||||||
sd.config_id = derived_sc.id
|
sd.config_id = derived_sc['id']
|
||||||
self.deployments.get.return_value = sd
|
self.deployments.get.return_value = sd
|
||||||
|
|
||||||
sd.delete.side_effect = HTTPNotFound()
|
sd.delete.side_effect = HTTPNotFound()
|
||||||
self.software_configs.delete.side_effect = HTTPNotFound()
|
self.rpc_client.delete_software_config.side_effect = exc.NotFound
|
||||||
self.assertIsNone(self.deployment.handle_delete())
|
self.assertIsNone(self.deployment.handle_delete())
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
(derived_sc.id,), self.software_configs.delete.call_args[0])
|
(self.ctx, derived_sc['id']),
|
||||||
|
self.rpc_client.delete_software_config.call_args[0])
|
||||||
|
|
||||||
def test_handle_delete_none(self):
|
def test_handle_delete_none(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
|
@ -539,13 +534,14 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
self.deployment.handle_update(
|
self.deployment.handle_update(
|
||||||
json_snippet=snippet, tmpl_diff=None, prop_diff=prop_diff)
|
json_snippet=snippet, tmpl_diff=None, prop_diff=prop_diff)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
(config_id,), self.software_configs.get.call_args[0])
|
(self.ctx, config_id),
|
||||||
|
self.rpc_client.show_software_config.call_args[0])
|
||||||
|
|
||||||
args = self.deployments.get.call_args[0]
|
args = self.deployments.get.call_args[0]
|
||||||
self.assertEqual(1, len(args))
|
self.assertEqual(1, len(args))
|
||||||
self.assertIn(sd.id, args)
|
self.assertIn(sd.id, args)
|
||||||
args = sd.update.call_args[1]
|
args = sd.update.call_args[1]
|
||||||
self.assertEqual(derived_sc.id, args['config_id'])
|
self.assertEqual(derived_sc['id'], args['config_id'])
|
||||||
|
|
||||||
def test_handle_suspend_resume(self):
|
def test_handle_suspend_resume(self):
|
||||||
self._create_stack(self.template_delete_suspend_resume)
|
self._create_stack(self.template_delete_suspend_resume)
|
||||||
|
@ -564,7 +560,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
args = sd.update.call_args[1]
|
args = sd.update.call_args[1]
|
||||||
self.assertEqual({
|
self.assertEqual({
|
||||||
'action': 'SUSPEND',
|
'action': 'SUSPEND',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'IN_PROGRESS',
|
'status': 'IN_PROGRESS',
|
||||||
|
@ -583,7 +579,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
args = sd.update.call_args[1]
|
args = sd.update.call_args[1]
|
||||||
self.assertEqual({
|
self.assertEqual({
|
||||||
'action': 'RESUME',
|
'action': 'RESUME',
|
||||||
'config_id': derived_sc.id,
|
'config_id': derived_sc['id'],
|
||||||
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
'server_id': '9f1f0e00-05d2-4ca5-8602-95021f19c9d0',
|
||||||
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
'stack_user_project_id': '65728b74-cfe7-4f17-9c15-11d4f686e591',
|
||||||
'status': 'IN_PROGRESS',
|
'status': 'IN_PROGRESS',
|
||||||
|
@ -599,16 +595,18 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
def test_handle_signal_ok_zero(self):
|
def test_handle_signal_ok_zero(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = mock.MagicMock()
|
sd = mock.MagicMock()
|
||||||
sc = mock.MagicMock()
|
sc = {
|
||||||
sc.outputs = [{'name': 'foo'},
|
'outputs': [
|
||||||
{'name': 'foo2'},
|
{'name': 'foo'},
|
||||||
{'name': 'failed',
|
{'name': 'foo2'},
|
||||||
'error_output': True}]
|
{'name': 'failed', 'error_output': True}
|
||||||
|
]
|
||||||
|
}
|
||||||
sd.output_values = {}
|
sd.output_values = {}
|
||||||
sd.status = self.deployment.IN_PROGRESS
|
sd.status = self.deployment.IN_PROGRESS
|
||||||
sd.update.return_value = None
|
sd.update.return_value = None
|
||||||
self.deployments.get.return_value = sd
|
self.deployments.get.return_value = sd
|
||||||
self.software_configs.get.return_value = sc
|
self.rpc_client.show_software_config.return_value = sc
|
||||||
details = {
|
details = {
|
||||||
'foo': 'bar',
|
'foo': 'bar',
|
||||||
'deploy_status_code': 0
|
'deploy_status_code': 0
|
||||||
|
@ -630,16 +628,18 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
def test_handle_signal_ok_str_zero(self):
|
def test_handle_signal_ok_str_zero(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = mock.MagicMock()
|
sd = mock.MagicMock()
|
||||||
sc = mock.MagicMock()
|
sc = {
|
||||||
sc.outputs = [{'name': 'foo'},
|
'outputs': [
|
||||||
{'name': 'foo2'},
|
{'name': 'foo'},
|
||||||
{'name': 'failed',
|
{'name': 'foo2'},
|
||||||
'error_output': True}]
|
{'name': 'failed', 'error_output': True}
|
||||||
|
]
|
||||||
|
}
|
||||||
sd.output_values = {}
|
sd.output_values = {}
|
||||||
sd.status = self.deployment.IN_PROGRESS
|
sd.status = self.deployment.IN_PROGRESS
|
||||||
sd.update.return_value = None
|
sd.update.return_value = None
|
||||||
self.deployments.get.return_value = sd
|
self.deployments.get.return_value = sd
|
||||||
self.software_configs.get.return_value = sc
|
self.rpc_client.show_software_config.return_value = sc
|
||||||
details = {
|
details = {
|
||||||
'foo': 'bar',
|
'foo': 'bar',
|
||||||
'deploy_status_code': '0'
|
'deploy_status_code': '0'
|
||||||
|
@ -661,16 +661,18 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
def test_handle_signal_failed(self):
|
def test_handle_signal_failed(self):
|
||||||
self._create_stack(self.template)
|
self._create_stack(self.template)
|
||||||
sd = mock.MagicMock()
|
sd = mock.MagicMock()
|
||||||
sc = mock.MagicMock()
|
sc = {
|
||||||
sc.outputs = [{'name': 'foo'},
|
'outputs': [
|
||||||
{'name': 'foo2'},
|
{'name': 'foo'},
|
||||||
{'name': 'failed',
|
{'name': 'foo2'},
|
||||||
'error_output': True}]
|
{'name': 'failed', 'error_output': True}
|
||||||
|
]
|
||||||
|
}
|
||||||
sd.output_values = {}
|
sd.output_values = {}
|
||||||
sd.status = self.deployment.IN_PROGRESS
|
sd.status = self.deployment.IN_PROGRESS
|
||||||
sd.update.return_value = None
|
sd.update.return_value = None
|
||||||
self.deployments.get.return_value = sd
|
self.deployments.get.return_value = sd
|
||||||
self.software_configs.get.return_value = sc
|
self.rpc_client.show_software_config.return_value = sc
|
||||||
details = {'failed': 'no enough memory found.'}
|
details = {'failed': 'no enough memory found.'}
|
||||||
ret = self.deployment.handle_signal(details)
|
ret = self.deployment.handle_signal(details)
|
||||||
self.assertEqual('deployment failed', ret)
|
self.assertEqual('deployment failed', ret)
|
||||||
|
@ -760,7 +762,7 @@ class SoftwareDeploymentTest(common.HeatTestCase):
|
||||||
sd.outputs = []
|
sd.outputs = []
|
||||||
sd.output_values = {'foo': 'bar'}
|
sd.output_values = {'foo': 'bar'}
|
||||||
err = self.assertRaises(
|
err = self.assertRaises(
|
||||||
exception.InvalidTemplateAttribute,
|
exc.InvalidTemplateAttribute,
|
||||||
self.deployment.FnGetAtt, 'foo2')
|
self.deployment.FnGetAtt, 'foo2')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'The Referenced Attribute (deployment_mysql foo2) is incorrect.',
|
'The Referenced Attribute (deployment_mysql foo2) is incorrect.',
|
||||||
|
|
|
@ -44,9 +44,8 @@ class StructuredConfigTestJSON(common.HeatTestCase):
|
||||||
self.ctx, 'software_config_test_stack',
|
self.ctx, 'software_config_test_stack',
|
||||||
template.Template(self.template))
|
template.Template(self.template))
|
||||||
self.config = self.stack['config_mysql']
|
self.config = self.stack['config_mysql']
|
||||||
heat = mock.MagicMock()
|
self.rpc_client = mock.MagicMock()
|
||||||
self.config.heat = heat
|
self.config._rpc_client = self.rpc_client
|
||||||
self.software_configs = heat.return_value.software_configs
|
|
||||||
|
|
||||||
def test_resource_mapping(self):
|
def test_resource_mapping(self):
|
||||||
mapping = sc.resource_mapping()
|
mapping = sc.resource_mapping()
|
||||||
|
@ -60,13 +59,12 @@ class StructuredConfigTestJSON(common.HeatTestCase):
|
||||||
self.assertIsInstance(self.config, sc.StructuredConfig)
|
self.assertIsInstance(self.config, sc.StructuredConfig)
|
||||||
|
|
||||||
def test_handle_create(self):
|
def test_handle_create(self):
|
||||||
stc = mock.MagicMock()
|
|
||||||
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
config_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
|
||||||
stc.id = config_id
|
value = {'id': config_id}
|
||||||
self.software_configs.create.return_value = stc
|
self.rpc_client.create_software_config.return_value = value
|
||||||
self.config.handle_create()
|
self.config.handle_create()
|
||||||
self.assertEqual(config_id, self.config.resource_id)
|
self.assertEqual(config_id, self.config.resource_id)
|
||||||
kwargs = self.software_configs.create.call_args[1]
|
kwargs = self.rpc_client.create_software_config.call_args[1]
|
||||||
self.assertEqual(self.stored_config, kwargs['config'])
|
self.assertEqual(self.stored_config, kwargs['config'])
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue