diff --git a/tripleo_common/actions/deployment.py b/tripleo_common/actions/deployment.py index 313b81c16..fd810f76b 100644 --- a/tripleo_common/actions/deployment.py +++ b/tripleo_common/actions/deployment.py @@ -15,10 +15,8 @@ import json import logging import os -import time import yaml -from heatclient.common import deployment_utils from heatclient import exc as heat_exc from mistral_lib import actions from swiftclient import exceptions as swiftexceptions @@ -32,102 +30,6 @@ from tripleo_common.utils import swift as swiftutils LOG = logging.getLogger(__name__) -class OrchestrationDeployAction(base.TripleOAction): - - def __init__(self, server_id, config, name, input_values=[], - action='CREATE', signal_transport='TEMP_URL_SIGNAL', - timeout=300, group='script'): - super(OrchestrationDeployAction, self).__init__() - self.server_id = server_id - self.config = config - self.input_values = input_values - self.action = action - self.name = name - self.signal_transport = signal_transport - self.timeout = timeout - self.group = group - - def _extract_container_object_from_swift_url(self, swift_url): - container_name = swift_url.split('/')[-2] - object_name = swift_url.split('/')[-1].split('?')[0] - return (container_name, object_name) - - def _build_sc_params(self, swift_url): - source = { - 'config': self.config, - 'group': self.group, - } - return deployment_utils.build_derived_config_params( - action=self.action, - source=source, - name=self.name, - input_values=self.input_values, - server_id=self.server_id, - signal_transport=self.signal_transport, - signal_id=swift_url - ) - - def _wait_for_data(self, container_name, object_name, context): - body = None - count_check = 0 - swift_client = self.get_object_client(context) - while not body: - body = swiftutils.get_object_string(swift_client, container_name, - object_name) - count_check += 3 - if body or count_check > self.timeout: - break - time.sleep(3) - - return body - - def run(self, context): - heat = self.get_orchestration_client(context) - swift_client = self.get_object_client(context) - - swift_url = deployment_utils.create_temp_url(swift_client, - self.name, - self.timeout) - container_name, object_name = \ - self._extract_container_object_from_swift_url(swift_url) - - params = self._build_sc_params(swift_url) - config = heat.software_configs.create(**params) - - sd = heat.software_deployments.create( - tenant_id='asdf', # heatclient requires this - config_id=config.id, - server_id=self.server_id, - action=self.action, - status='IN_PROGRESS' - ) - - body = self._wait_for_data(container_name, object_name, context) - - # cleanup - try: - sd.delete() - config.delete() - swift_client.delete_object(container_name, object_name) - swift_client.delete_container(container_name) - except Exception as err: - LOG.error("Error cleaning up heat deployment resources.", err) - - error = None - if not body: - body_json = {} - error = "Timeout for heat deployment '%s'" % self.name - else: - body_json = json.loads(body) - if body_json['deploy_status_code'] != 0: - error = "Heat deployment failed for '%s'" % self.name - - if error: - LOG.error(error) - - return actions.Result(data=body_json, error=error) - - class OvercloudRcAction(base.TripleOAction): """Generate the overcloudrc for a plan diff --git a/tripleo_common/tests/actions/test_deployment.py b/tripleo_common/tests/actions/test_deployment.py index 6e7152de3..acb184f59 100644 --- a/tripleo_common/tests/actions/test_deployment.py +++ b/tripleo_common/tests/actions/test_deployment.py @@ -16,191 +16,12 @@ import json import mock from heatclient import exc as heat_exc -from mistral_lib import actions from swiftclient import exceptions as swiftexceptions from tripleo_common.actions import deployment from tripleo_common.tests import base -class OrchestrationDeployActionTest(base.TestCase): - - def setUp(self,): - super(OrchestrationDeployActionTest, self).setUp() - self.server_id = 'server_id' - self.config = 'config' - self.name = 'name' - self.input_values = [] - self.action = 'CREATE' - self.signal_transport = 'TEMP_URL_SIGNAL' - self.timeout = 300 - self.group = 'script' - - def test_extract_container_object_from_swift_url(self): - swift_url = 'https://example.com' + \ - '/v1/a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object' + \ - '?temp_url_sig=da39a3ee5e6b4&temp_url_expires=1323479485' - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name, - self.timeout) - self.assertEqual(('container', 'object'), - action._extract_container_object_from_swift_url( - swift_url)) - - @mock.patch( - 'heatclient.common.deployment_utils.build_derived_config_params') - def test_build_sc_params(self, build_derived_config_params_mock): - build_derived_config_params_mock.return_value = 'built_params' - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name) - self.assertEqual('built_params', action._build_sc_params('swift_url')) - build_derived_config_params_mock.assert_called_once() - - @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') - def test_wait_for_data(self, get_obj_client_mock): - mock_ctx = mock.MagicMock() - - swift = mock.MagicMock() - swift.get_object.return_value = ({}, 'body') - get_obj_client_mock.return_value = swift - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name) - self.assertEqual('body', action._wait_for_data('container', - 'object', - context=mock_ctx)) - get_obj_client_mock.assert_called_once() - swift.get_object.assert_called_once_with('container', 'object') - - @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') - @mock.patch('time.sleep') - def test_wait_for_data_timeout(self, sleep, get_obj_client_mock): - mock_ctx = mock.MagicMock() - swift = mock.MagicMock() - swift.get_object.return_value = ({}, None) - get_obj_client_mock.return_value = swift - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name, - timeout=10) - self.assertIsNone(action._wait_for_data('container', - 'object', - context=mock_ctx)) - get_obj_client_mock.assert_called_once() - swift.get_object.assert_called_with('container', 'object') - # Trying every 3 seconds, so 4 times for a timeout of 10 seconds - self.assertEqual(swift.get_object.call_count, 4) - - @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') - @mock.patch('tripleo_common.actions.base.TripleOAction.' - 'get_orchestration_client') - @mock.patch('heatclient.common.deployment_utils.create_temp_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_extract_container_object_from_swift_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_build_sc_params') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_wait_for_data') - def test_run(self, wait_for_data_mock, build_sc_params_mock, - extract_from_swift_url_mock, create_temp_url_mock, - get_heat_mock, get_obj_client_mock): - extract_from_swift_url_mock.return_value = ('container', 'object') - mock_ctx = mock.MagicMock() - build_sc_params_mock.return_value = {'foo': 'bar'} - config = mock.MagicMock() - sd = mock.MagicMock() - get_heat_mock().software_configs.create.return_value = config - get_heat_mock().software_deployments.create.return_value = sd - wait_for_data_mock.return_value = '{"deploy_status_code": 0}' - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name) - expected = actions.Result( - data={"deploy_status_code": 0}, - error=None) - self.assertEqual(expected, action.run(context=mock_ctx)) - create_temp_url_mock.assert_called_once() - extract_from_swift_url_mock.assert_called_once() - build_sc_params_mock.assert_called_once() - get_obj_client_mock.assert_called_once() - wait_for_data_mock.assert_called_once() - - sd.delete.assert_called_once() - config.delete.assert_called_once() - get_obj_client_mock.delete_object.called_once_with('container', - 'object') - get_obj_client_mock.delete_container.called_once_with('container') - - @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') - @mock.patch('tripleo_common.actions.base.TripleOAction.' - 'get_orchestration_client') - @mock.patch('heatclient.common.deployment_utils.create_temp_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_extract_container_object_from_swift_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_build_sc_params') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_wait_for_data') - def test_run_timeout(self, wait_for_data_mock, build_sc_params_mock, - extract_from_swift_url_mock, create_temp_url_mock, - get_heat_mock, get_obj_client_mock): - extract_from_swift_url_mock.return_value = ('container', 'object') - mock_ctx = mock.MagicMock() - config = mock.MagicMock() - sd = mock.MagicMock() - get_heat_mock().software_configs.create.return_value = config - get_heat_mock().software_deployments.create.return_value = sd - wait_for_data_mock.return_value = None - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name) - expected = actions.Result( - data={}, - error="Timeout for heat deployment 'name'") - self.assertEqual(expected, action.run(mock_ctx)) - - sd.delete.assert_called_once() - config.delete.assert_called_once() - get_obj_client_mock.delete_object.called_once_with('container', - 'object') - get_obj_client_mock.delete_container.called_once_with('container') - - @mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client') - @mock.patch('tripleo_common.actions.base.TripleOAction.' - 'get_orchestration_client') - @mock.patch('heatclient.common.deployment_utils.create_temp_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_extract_container_object_from_swift_url') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_build_sc_params') - @mock.patch('tripleo_common.actions.deployment.OrchestrationDeployAction.' - '_wait_for_data') - def test_run_failed(self, wait_for_data_mock, build_sc_params_mock, - extract_from_swift_url_mock, create_temp_url_mock, - get_heat_mock, get_obj_client_mock): - extract_from_swift_url_mock.return_value = ('container', 'object') - mock_ctx = mock.MagicMock() - config = mock.MagicMock() - sd = mock.MagicMock() - get_heat_mock().software_configs.create.return_value = config - get_heat_mock().software_deployments.create.return_value = sd - wait_for_data_mock.return_value = '{"deploy_status_code": 1}' - - action = deployment.OrchestrationDeployAction(self.server_id, - self.config, self.name) - expected = actions.Result( - data={"deploy_status_code": 1}, - error="Heat deployment failed for 'name'") - self.assertEqual(expected, action.run(mock_ctx)) - - sd.delete.assert_called_once() - config.delete.assert_called_once() - get_obj_client_mock.delete_object.called_once_with('container', - 'object') - get_obj_client_mock.delete_container.called_once_with('container') - - class OvercloudRcActionTestCase(base.TestCase): @mock.patch('tripleo_common.actions.base.TripleOAction.' 'get_object_client')