diff --git a/tripleoclient/tests/v1/overcloud_update/fakes.py b/tripleoclient/tests/v1/overcloud_update/fakes.py index be2ec392b..03295dbc6 100644 --- a/tripleoclient/tests/v1/overcloud_update/fakes.py +++ b/tripleoclient/tests/v1/overcloud_update/fakes.py @@ -16,11 +16,27 @@ import mock from osc_lib.tests import utils +from tripleoclient.tests import fakes + class FakeClientWrapper(object): def __init__(self): self._instance = mock.Mock() + self.object_store = FakeObjectClient() + + def messaging_websocket(self, queue_name): + return fakes.FakeWebSocket() + + +class FakeObjectClient(object): + + def __init__(self): + self._instance = mock.Mock() + self.put_object = mock.Mock() + + def get_object(self, *args): + return class TestOvercloudUpdate(utils.TestCommand): @@ -31,3 +47,4 @@ class TestOvercloudUpdate(utils.TestCommand): self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN") self.app.client_manager.orchestration = mock.Mock() self.app.client_manager.tripleoclient = FakeClientWrapper() + self.app.client_manager.workflow_engine = mock.Mock() diff --git a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py index 56047fcd8..4797214e4 100644 --- a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py +++ b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py @@ -14,7 +14,6 @@ # import mock -import tempfile from tripleoclient import exceptions from tripleoclient.tests.v1.overcloud_update import fakes @@ -29,8 +28,10 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate): # Get the command object to test self.cmd = overcloud_update.UpdateOvercloud(self.app, None) + @mock.patch('tripleoclient.workflows.templates.process_templates', + autospec=True) @mock.patch('tripleo_common.update.PackageUpdateManager') - def test_update_out(self, update_manager): + def test_update_out(self, update_manager, mock_process_templates): update_manager.return_value.get_status.return_value = ( 'COMPLETE', {}) argslist = ['overcloud', '-i', '--templates'] @@ -39,45 +40,23 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate): ('interactive', True), ('templates', '/usr/share/openstack-tripleo-heat-templates/') ] + + mock_process_templates.return_value = { + 'stack_name': 'mystack', + 'environment': {}, + 'files': {}, + 'templates': 'template body', + } parsed_args = self.check_parser(self.cmd, argslist, verifylist) self.cmd.take_action(parsed_args) update_manager.get_status.called_once() update_manager.update.called_once() update_manager.do_interactive_update.called_once() + @mock.patch('tripleoclient.workflows.templates.process_templates', + autospec=True) @mock.patch('tripleo_common.update.PackageUpdateManager') - def test_update_answerfile(self, update_manager): - answers = ("templates: {templates}\n" - "environments:\n" - " - {environment}\n") - - with tempfile.NamedTemporaryFile(mode="w+t") as answerfile: - answerfile.write(answers.format( - templates='/dev/null', - environment='/dev/null')) - answerfile.flush() - - update_manager.return_value.get_status.return_value = ( - 'COMPLETE', {}) - argslist = ['overcloud', '-i', '--answers-file', answerfile.name] - verifylist = [ - ('stack', 'overcloud'), - ('interactive', True), - ('answers_file', answerfile.name) - ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - self.cmd.take_action(parsed_args) - - update_manager.get_status.called_once() - update_manager.update.called_once() - update_manager.do_interactive_update.called_once() - - called_args = update_manager.call_args[1] - self.assertEqual(called_args['tht_dir'], '/dev/null') - self.assertEqual(called_args['environment_files'], ['/dev/null']) - - @mock.patch('tripleo_common.update.PackageUpdateManager') - def test_update_failed(self, update_manager): + def test_update_failed(self, update_manager, mock_process_templates): update_manager.return_value.get_status.return_value = ( 'FAILED', {}) argslist = ['overcloud', '-i', '--templates'] @@ -87,5 +66,12 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate): ('templates', '/usr/share/openstack-tripleo-heat-templates/') ] parsed_args = self.check_parser(self.cmd, argslist, verifylist) + mock_process_templates.return_value = { + 'stack_name': 'mystack', + 'environment': {}, + 'files': {}, + 'templates': 'template body', + } + self.assertRaises(exceptions.DeploymentError, self.cmd.take_action, parsed_args) diff --git a/tripleoclient/v1/overcloud_update.py b/tripleoclient/v1/overcloud_update.py index 0b79302c3..695ab3fd4 100644 --- a/tripleoclient/v1/overcloud_update.py +++ b/tripleoclient/v1/overcloud_update.py @@ -14,22 +14,20 @@ # import logging -import yaml from osc_lib.command import command -from osc_lib import exceptions as oscexc from osc_lib.i18n import _ from osc_lib import utils from tripleo_common import update from tripleoclient import constants from tripleoclient import exceptions +from tripleoclient.workflows import templates class UpdateOvercloud(command.Command): """Updates packages on overcloud nodes""" - auth_required = False log = logging.getLogger(__name__ + ".UpdateOvercloud") def get_parser(self, prog_name): @@ -40,7 +38,11 @@ class UpdateOvercloud(command.Command): default=utils.env('OVERCLOUD_STACK_NAME')) parser.add_argument( '--templates', nargs='?', const=constants.TRIPLEO_HEAT_TEMPLATES, - help=_("The directory containing the Heat templates to deploy"), + help=_("The directory containing the Heat templates to deploy. " + "This argument is deprecated. The command now utilizes " + "a deployment plan, which should be updated prior to " + "running this command, should that be required. Otherwise " + "this argument will be silently ignored."), ) parser.add_argument('-i', '--interactive', dest='interactive', action='store_true') @@ -49,9 +51,12 @@ class UpdateOvercloud(command.Command): parser.add_argument( '-e', '--environment-file', metavar='', action='append', dest='environment_files', - help=_('Environment files to be passed to the heat stack-create ' - 'or heat stack-update command. (Can be specified more than ' - 'once.)') + help=_("Environment files to be passed to the heat stack-create " + "or heat stack-update command. (Can be specified more than " + "once.) This argument is deprecated. The command now " + "utilizes a deployment plan, which should be updated prior " + "to running this command, should that be required. " + "Otherwise this argument will be silently ignored."), ) parser.add_argument( '--answers-file', @@ -60,31 +65,18 @@ class UpdateOvercloud(command.Command): return parser def take_action(self, parsed_args): - if parsed_args.templates is None and parsed_args.answers_file is None: - raise oscexc.CommandError( - "You must specify either --templates or --answers-file") - - if parsed_args.answers_file is not None: - with open(parsed_args.answers_file, 'r') as answers_file: - answers = yaml.load(answers_file) - - if parsed_args.templates is None: - parsed_args.templates = answers['templates'] - if 'environments' in answers: - if parsed_args.environment_files is not None: - answers.environments.extend( - parsed_args.environment_files) - parsed_args.environment_files = answers['environments'] - self.log.debug("take_action(%s)" % parsed_args) clients = self.app.client_manager + workflow = clients.workflow_engine + stack_fields = templates.process_templates( + workflow, container=parsed_args.stack) + update_manager = update.PackageUpdateManager( heatclient=clients.orchestration, novaclient=clients.compute, stack_id=parsed_args.stack, - tht_dir=parsed_args.templates, - environment_files=parsed_args.environment_files) + stack_fields=stack_fields) if parsed_args.abort_update: print("cancelling package update on stack {0}".format( parsed_args.stack)) @@ -102,4 +94,6 @@ class UpdateOvercloud(command.Command): if status not in ['COMPLETE']: raise exceptions.DeploymentError("Stack update failed.") else: - print("stack {0} status: {1}".format(parsed_args.stack, status)) + status, _ = update_manager.get_status() + print("stack {0} status: {1}".format(parsed_args.stack, + status)) diff --git a/tripleoclient/workflows/templates.py b/tripleoclient/workflows/templates.py new file mode 100644 index 000000000..652cb8dfc --- /dev/null +++ b/tripleoclient/workflows/templates.py @@ -0,0 +1,17 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from tripleoclient.workflows import base + + +def process_templates(workflow_client, **workflow_input): + return base.call_action(workflow_client, 'tripleo.templates.process', + **workflow_input)