Remove mistral from the config_download deploy workflow

This change removes all of mistral from the config_download_deploy function
by calling the required functions directly.

- All of the inputs within this function have been cleaned up and documented.
- New log entires will be created when using this method giving the deployer
  a better overall user experience.
- To ensure we're able to support the ability to reproduce commands, the ssh
  args extravar has been moved to an environment variable.
- The methods get_config and get_key have been moved to the utils module.
  This was done to help avoid circular imports.

Update methods have been changed to execute without running within a mistral
workflow. This was changed because there's no need to support the multiple
code paths anymore given config_download is now running directly.

Test classes have been updated to reduce duplication.

With the new streamlined execution process we should see improved deployment
times and better visability into the deployment process.

Task: 38422
Story: 2007212

Depends-On: I006291a2465aa4c950abce76f9e5f9459b76e330
Change-Id: Ide1a4503dd2bdd2d5e494cd1eac483b842a21acf
Co-authored-by: Luke Short <ekultails@gmail.com>
Co-authored-by: Dougal Matthews <dougal@dougalmatthews.com>
Signed-off-by: Kevin Carter <kecarter@redhat.com>
This commit is contained in:
Kevin Carter 2020-02-04 12:19:55 -06:00 committed by Kevin Carter (cloudnull)
parent 712d8d7a61
commit dc9ae1ac5b
27 changed files with 732 additions and 854 deletions

View File

@ -18,6 +18,8 @@ import logging
from osc_lib.command import command
from osc_lib import exceptions as oscexc
from tripleo_common.utils import config
from tripleoclient import exceptions
from tripleoclient import utils
@ -36,6 +38,38 @@ class Command(command.Command):
self.log.exception("Exception occured while running the command")
raise
@staticmethod
def get_ansible_key_and_dir(no_workflow, stack, orchestration):
"""Return the ansible directory and key path.
:param no_workflow: Enable or disable the mistral workflow code path.
:type no_workflow: Boolean
:oaram stack: Name of a given stack to run against.
:type stack: String
:param orchestration: Orchestration client object.
:type orchestration: Object
:returns: Tuple
"""
if no_workflow:
key = utils.get_key(stack=stack)
stack_config = config.Config(orchestration)
with utils.TempDirs(cleanup=False, chdir=False) as tmp:
stack_config.write_config(
stack_config.fetch_config(stack),
stack,
tmp
)
return key, tmp
else:
# Assumes execution will take place from within a mistral
# container.
key = '.ssh/tripleo-admin-rsa'
return key, None
class Lister(Command, command.Lister):
pass

View File

@ -16,6 +16,10 @@
import mock
import sys
from osc_lib.tests import utils
from tripleoclient import plugin
AUTH_TOKEN = "foobar"
AUTH_URL = "http://0.0.0.0"
@ -36,6 +40,11 @@ class FakeApp(object):
class FakeStackObject(object):
stack_name = 'undercloud'
outputs = []
@staticmethod
def get(*args, **kwargs):
pass
class FakeClientManager(object):
@ -81,6 +90,8 @@ class FakeClientWrapper(object):
def __init__(self):
self.ws = FakeWebSocket()
self.object_store = FakeObjectClient()
self._instance = mock.Mock()
def messaging_websocket(self):
return self.ws
@ -125,6 +136,60 @@ class FakeInstanceData(object):
_data = {'token': {}}
class FakeObjectClient(object):
def __init__(self):
self._instance = mock.Mock()
self.put_object = mock.Mock()
def get_object(self, *args):
return [None, "fake"]
def get_container(self, *args):
return [None, [{"name": "fake"}]]
class FakePlaybookExecution(utils.TestCommand):
def setUp(self, ansible_mock=True):
super(FakePlaybookExecution, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.compute = mock.Mock()
self.app.client_manager.identity = mock.Mock()
self.app.client_manager.image = mock.Mock()
self.app.client_manager.network = mock.Mock()
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
self.app.client_manager.workflow_engine = mock.Mock()
stack = self.app.client_manager.orchestration = mock.Mock()
stack.stacks.get.return_value = FakeStackObject
tc.create_mistral_context = plugin.ClientWrapper(
instance=FakeInstanceData
).create_mistral_context
# NOTE(cloudnull): When mistral is gone this should be removed.
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
if ansible_mock:
self.gcn = mock.patch(
'tripleo_common.utils.config.Config',
autospec=True
)
self.gcn.start()
self.addCleanup(self.gcn.stop)
self.mkdirs = mock.patch(
'os.makedirs',
autospec=True
)
self.mkdirs.start()
self.addCleanup(self.mkdirs.stop)
def fake_ansible_runner_run_return(rc=0):
return 'Test Status', rc

View File

@ -14,7 +14,6 @@
#
import mock
from osc_lib.tests import utils
from tripleoclient.tests import fakes
@ -105,43 +104,7 @@ def create_env(**kwargs):
return env
class FakeClientWrapper(object):
def __init__(self):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self):
return fakes.FakeWebSocket()
class FakeObjectClient(object):
def __init__(self):
self._instance = mock.Mock()
self.put_object = mock.Mock()
def get_object(self, *args):
return [None, "fake"]
def get_container(self, *args):
return [None, [{"name": "fake"}]]
class TestDeployOvercloud(utils.TestCommand):
class TestDeployOvercloud(fakes.FakePlaybookExecution):
def setUp(self):
super(TestDeployOvercloud, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.compute = mock.Mock()
self.app.client_manager.identity = mock.Mock()
self.app.client_manager.image = mock.Mock()
self.app.client_manager.network = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
self.app.client_manager.tripleoclient = FakeClientWrapper()
super(TestDeployOvercloud, self).setUp(ansible_mock=False)

View File

@ -877,9 +877,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
parsed_args)
self.assertIn('/tmp/notthere', str(error))
@mock.patch('tripleoclient.tests.v1.overcloud_deploy.fakes.'
'FakeObjectClient.get_object', autospec=True)
def test_validate_args_missing_environment_files(self, mock_obj):
def test_validate_args_missing_environment_files(self):
arglist = ['--templates',
'-e', 'nonexistent.yaml']
verifylist = [
@ -887,8 +885,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
('environment_files', ['nonexistent.yaml']),
]
mock_obj.side_effect = ObjectClientException(mock.Mock(
'/fake/path not found'))
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(oscexc.CommandError,
@ -1482,8 +1478,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd.take_action(parsed_args)
self.assertTrue(fixture.mock_get_hosts_and_enable_ssh_admin.called)
self.assertTrue(fixture.mock_config_download.called)
self.assertEqual('ansible.cfg',
fixture.mock_config_download.call_args[0][8])
mock_copy.assert_called_once()
@mock.patch('tripleoclient.utils.copy_clouds_yaml')
@ -1514,7 +1508,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd.take_action(parsed_args)
fixture.mock_config_download.assert_called()
self.assertEqual(240*60, fixture.mock_config_download.call_args[0][9])
mock_copy.assert_called_once()
def test_download_missing_files_from_plan(self):

View File

@ -13,38 +13,10 @@
# under the License.
#
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):
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 TestOvercloudExternalUpdateRun(utils.TestCommand):
class TestOvercloudExternalUpdateRun(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudExternalUpdateRun, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.tripleoclient = FakeClientWrapper()
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()

View File

@ -15,6 +15,7 @@
import mock
from tripleoclient.tests import fakes as ooofakes
from tripleoclient.tests.v1.overcloud_external_update import fakes
from tripleoclient.v1 import overcloud_external_update
@ -34,13 +35,23 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_with_user_and_tags(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser, update_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--tags', 'ceph']
@ -54,25 +65,35 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
inventory_file=mock_open().__enter__().read(),
playbook='external_update_steps_playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='all',
tags='ceph',
skip_tags='',
verbosity=0,
extra_vars={}
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser, update_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1',
@ -87,14 +108,18 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
inventory_file=mock_open().__enter__().read(),
playbook='external_update_steps_playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='all',
tags='',
skip_tags='',
verbosity=0,
extra_vars={'key1': 'val1', 'key2': 'val2'}
extra_vars={
'key1': 'val1',
'key2': 'val2',
'ansible_become': True
}
)

View File

@ -13,38 +13,10 @@
# under the License.
#
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):
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 TestOvercloudExternalUpgradeRun(utils.TestCommand):
class TestOvercloudExternalUpgradeRun(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudExternalUpgradeRun, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.tripleoclient = FakeClientWrapper()
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()

View File

@ -15,6 +15,7 @@
import mock
from tripleoclient.tests import fakes as ooofakes
from tripleoclient.tests.v1.overcloud_external_upgrade import fakes
from tripleoclient.v1 import overcloud_external_upgrade
@ -34,13 +35,23 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_with_user_and_tags(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser, update_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--tags', 'ceph']
@ -54,25 +65,35 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
inventory_file=mock_open().__enter__().read(),
playbook='external_upgrade_steps_playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='all',
tags='ceph',
skip_tags='',
verbosity=0,
extra_vars={}
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser, update_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1',
@ -87,14 +108,18 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
inventory_file=mock_open().__enter__().read(),
playbook='external_upgrade_steps_playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='all',
tags='',
skip_tags='',
verbosity=0,
extra_vars={'key1': 'val1', 'key2': 'val2'}
extra_vars={
'key1': 'val1',
'key2': 'val2',
'ansible_become': True
}
)

View File

@ -13,78 +13,22 @@
# under the License.
#
import mock
from osc_lib.tests import utils
from tripleoclient import plugin
from tripleoclient.tests import fakes
class FakeClientWrapper(object):
def __init__(self):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self, queue="tripleo"):
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 TestFFWDUpgradePrepare(utils.TestCommand):
class TestFFWDUpgradePrepare(fakes.FakePlaybookExecution):
def setUp(self):
super(TestFFWDUpgradePrepare, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context
class TestFFWDUpgradeRun(utils.TestCommand):
class TestFFWDUpgradeRun(fakes.FakePlaybookExecution):
def setUp(self):
super(TestFFWDUpgradeRun, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context
class TestFFWDUpgradeConverge(utils.TestCommand):
class TestFFWDUpgradeConverge(fakes.FakePlaybookExecution):
def setUp(self):
super(TestFFWDUpgradeConverge, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context

View File

@ -155,7 +155,7 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@ -171,19 +171,19 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
inventory_file=mock_open().__enter__().read(),
nodes='',
playbook=constants.FFWD_UPGRADE_PLAYBOOK,
node_user='heat-admin',
playbook='fast_forward_upgrade_playbook.yaml',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='heat-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@ -199,19 +199,19 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
inventory_file=mock_open().__enter__().read(),
nodes='',
playbook=constants.FFWD_UPGRADE_PLAYBOOK,
node_user='my-user',
playbook='fast_forward_upgrade_playbook.yaml',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='my-user',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')

View File

@ -51,10 +51,31 @@ class TestDeleteNode(fakes.TestDeleteNode):
tc.create_mistral_context = plugin.ClientWrapper(
instance=ooofakes.FakeInstanceData
).create_mistral_context
self.gcn = mock.patch(
'tripleo_common.actions.config.DownloadConfigAction',
autospec=True
)
self.gcn.start()
self.addCleanup(self.gcn.stop)
self.ansible = mock.patch(
'tripleo_common.actions.ansible.AnsibleGenerateInventoryAction',
autospec=True
)
self.ansible.start()
self.addCleanup(self.ansible.stop)
config_mock = mock.patch(
'tripleo_common.actions.config.GetOvercloudConfig',
autospec=True
)
config_mock.start()
self.addCleanup(config_mock.stop)
self.workflow = self.app.client_manager.workflow_engine
self.stack_name = self.app.client_manager.orchestration.stacks.get
self.stack_name.return_value = mock.Mock(stack_name="overcloud")
stack = self.stack_name.return_value = mock.Mock(
stack_name="overcloud"
)
stack.output_show.return_value = {'output': {'output_value': []}}
execution = mock.Mock()
execution.id = "IDID"
self.workflow.executions.create.return_value = execution
@ -67,11 +88,19 @@ class TestDeleteNode(fakes.TestDeleteNode):
delete_node.return_value = None
self.addCleanup(delete_node.stop)
wait_stack = mock.patch(
'tripleoclient.utils.wait_for_stack_ready',
autospec=True
)
wait_stack.start()
wait_stack.return_value = None
self.addCleanup(wait_stack.stop)
# TODO(someone): This test does not pass with autospec=True, it should
# probably be fixed so that it can pass with that.
@mock.patch("heatclient.common.event_utils.poll_for_events")
def test_node_delete(self, mock_poll):
mock_poll.return_value = ("CREATE_IN_PROGRESS", "MESSAGE")
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_node_delete(self, mock_playbook):
argslist = ['instance1', 'instance2', '--templates',
'--stack', 'overcast', '--timeout', '90', '--yes']
verifylist = [
@ -79,14 +108,6 @@ class TestDeleteNode(fakes.TestDeleteNode):
('nodes', ['instance1', 'instance2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.websocket.wait_for_messages.return_value = iter([{
"execution_id": "IDID",
"status": "SUCCESS",
"message": "Success.",
}])
self.stack_name.return_value = mock.Mock(stack_name="overcast")
self.cmd.take_action(parsed_args)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
@ -122,9 +143,9 @@ class TestDeleteNode(fakes.TestDeleteNode):
# Verify
self.workflow.executions.create.assert_not_called()
@mock.patch("heatclient.common.event_utils.poll_for_events")
def test_node_delete_without_stack(self, mock_poll):
mock_poll.return_value = ("CREATE_IN_PROGRESS", "MESSAGE")
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_node_delete_without_stack(self, mock_playbook):
arglist = ['instance1', '--yes']
verifylist = [
@ -132,49 +153,17 @@ class TestDeleteNode(fakes.TestDeleteNode):
('nodes', ['instance1']),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.websocket.wait_for_messages.return_value = iter([{
"execution_id": "IDID",
"status": "SUCCESS",
"message": "Success.",
}])
self.cmd.take_action(parsed_args)
def test_node_delete_wrong_instance(self):
argslist = ['wrong_instance', '--templates',
'--stack', 'overcloud', '--yes']
verifylist = [
('stack', 'overcloud'),
('nodes', ['wrong_instance']),
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.websocket.wait_for_messages.return_value = iter([{
"status": "FAILED",
"execution_id": "IDID",
"message": """Failed to run action ERROR: Couldn't find \
following instances in stack overcloud: wrong_instance"""
}])
# Verify
self.assertRaises(exceptions.DeploymentError,
self.cmd.take_action, parsed_args)
@mock.patch("heatclient.common.event_utils.poll_for_events")
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('tripleoclient.workflows.baremetal.expand_roles',
autospec=True)
@mock.patch('tripleoclient.workflows.baremetal.undeploy_roles',
autospec=True)
def test_node_delete_baremetal_deployment(self, mock_undeploy_roles,
mock_expand_roles, mock_poll):
mock_poll.return_value = ("CREATE_IN_PROGRESS", "MESSAGE")
self.websocket.wait_for_messages.return_value = iter([{
"execution_id": "IDID",
"status": "SUCCESS",
"message": "Success.",
}])
mock_expand_roles,
mock_playbook):
bm_yaml = [{
'name': 'Compute',
'count': 5,
@ -219,7 +208,6 @@ class TestDeleteNode(fakes.TestDeleteNode):
expand_to_translate
]
self.stack_name.return_value = mock.Mock(stack_name="overcast")
res_list = self.app.client_manager.orchestration.resources.list
res_list.return_value = [
mock.Mock(

View File

@ -13,75 +13,22 @@
# under the License.
#
import mock
from osc_lib.tests import utils
from tripleoclient import plugin
from tripleoclient.tests import fakes
class FakeClientWrapper(object):
def __init__(self):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self):
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 TestOvercloudUpdatePrepare(utils.TestCommand):
class TestOvercloudUpdatePrepare(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudUpdatePrepare, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context
class TestOvercloudUpdateRun(utils.TestCommand):
class TestOvercloudUpdateRun(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudUpdateRun, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context
class TestOvercloudUpdateConverge(utils.TestCommand):
class TestOvercloudUpdateConverge(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudUpdateConverge, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
self.app.client_manager.workflow_engine = mock.Mock()
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context

View File

@ -130,75 +130,7 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_with_playbook_and_user(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute',
'--playbook', 'fake-playbook.yaml',
'--ssh-user', 'tripleo-admin']
verifylist = [
('limit', 'Compute'),
('static_inventory', None),
('playbook', 'fake-playbook.yaml'),
('ssh_user', 'tripleo-admin')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='Compute',
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_limit_with_all_playbooks(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all']
verifylist = [
('limit', 'Compute'),
('static_inventory', None),
('playbook', 'all')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
for book in constants.MINOR_UPDATE_PLAYBOOKS:
update_ansible.assert_any_call(
self.app.client_manager,
container='overcloud',
nodes='Compute',
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')

View File

@ -13,57 +13,16 @@
# under the License.
#
import mock
from osc_lib.tests import utils
from tripleoclient import plugin
from tripleoclient.tests import fakes
class FakeClientWrapper(object):
def __init__(self):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self):
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 TestOvercloudUpgradePrepare(utils.TestCommand):
class TestOvercloudUpgradePrepare(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudUpgradePrepare, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()
tc = self.app.client_manager.tripleoclient = FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
).create_mistral_context
workflow = execution = mock.Mock()
execution.id = "IDID"
workflow.executions.create.return_value = execution
self.app.client_manager.workflow_engine = workflow
class TestOvercloudUpgradeRun(utils.TestCommand):
class TestOvercloudUpgradeRun(fakes.FakePlaybookExecution):
def setUp(self):
super(TestOvercloudUpgradeRun, self).setUp()
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.tripleoclient = FakeClientWrapper()
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.orchestration = mock.Mock()

View File

@ -19,6 +19,7 @@ from osc_lib import exceptions as oscexc
from osc_lib.tests.utils import ParserException
from tripleoclient import constants
from tripleoclient import exceptions
from tripleoclient.tests import fakes as ooofakes
from tripleoclient.tests.v1.overcloud_upgrade import fakes
from tripleoclient.v1 import overcloud_upgrade
@ -173,13 +174,23 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_limit_with_playbook_and_user(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute, Controller',
'--playbook', 'fake-playbook.yaml',
@ -195,95 +206,35 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='Compute, Controller',
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='Compute, Controller',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_limit_all_playbooks_skip_validation(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all',
'--skip-tags', 'validation']
verifylist = [
('limit', 'Compute'),
('static_inventory', None),
('playbook', 'all'),
('skip_tags', 'validation')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
for book in constants.MAJOR_UPGRADE_PLAYBOOKS:
upgrade_ansible.assert_any_call(
self.app.client_manager,
container='overcloud',
nodes='Compute',
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='',
skip_tags='validation',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_limit_all_playbooks_only_validation(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all',
'--tags', 'validation']
verifylist = [
('limit', 'Compute'),
('static_inventory', None),
('playbook', 'all'),
('tags', 'validation')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
for book in constants.MAJOR_UPGRADE_PLAYBOOKS:
upgrade_ansible.assert_any_call(
self.app.client_manager,
container='overcloud',
nodes='Compute',
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='validation',
skip_tags='',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch(
'ansible_runner.runner_config.RunnerConfig',
autospec=True,
return_value=ooofakes.FakeRunnerConfig()
)
@mock.patch(
'ansible_runner.Runner.run',
return_value=ooofakes.fake_ansible_runner_run_return()
)
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_nodes_with_playbook_no_skip_tags(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_run, mock_run_prepare):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'compute-0, compute-1',
'--playbook', 'fake-playbook.yaml', ]
@ -298,87 +249,19 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='compute-0, compute-1',
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',
inventory=mock.ANY,
workdir=mock.ANY,
ssh_user='tripleo-admin',
key='/var/lib/mistral/overcloud/ssh_private_key',
module_path='/usr/share/ansible-modules',
limit_hosts='compute-0, compute-1',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
extra_vars={'ansible_become': True}
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_node_all_playbooks_skip_tags_default(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'swift-1', '--playbook', 'all']
verifylist = [
('limit', 'swift-1'),
('static_inventory', None),
('playbook', 'all'),
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
for book in constants.MAJOR_UPGRADE_PLAYBOOKS:
upgrade_ansible.assert_any_call(
self.app.client_manager,
container='overcloud',
nodes='swift-1',
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='',
skip_tags='',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_upgrade_node_all_playbooks_skip_tags_all_supported(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'swift-1', '--playbook', 'all',
'--skip-tags', 'pre-upgrade,validation']
verifylist = [
('limit', 'swift-1'),
('static_inventory', None),
('playbook', 'all'),
('skip_tags', 'pre-upgrade,validation')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
for book in constants.MAJOR_UPGRADE_PLAYBOOKS:
upgrade_ansible.assert_any_call(
self.app.client_manager,
container='overcloud',
nodes='swift-1',
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='',
skip_tags='pre-upgrade,validation',
verbosity=0,
extra_vars=None
)
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@ -391,7 +274,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(ParserException, lambda: self.check_parser(
self.cmd, argslist, verifylist))
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@ -414,7 +297,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(exceptions.InvalidConfiguration,
lambda: self.cmd.take_action(parsed_args))
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@ -437,7 +320,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(exceptions.InvalidConfiguration,
lambda: self.cmd.take_action(parsed_args))
@mock.patch('tripleoclient.workflows.package_update.update_ansible',
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')

View File

@ -16,7 +16,8 @@ import mock
from osc_lib.tests import utils
from tripleoclient import exceptions
from tripleoclient import plugin
from tripleoclient.tests.fakes import FakeInstanceData
from tripleoclient.tests.fakes import FakeStackObject
from tripleoclient.workflows import deployment
@ -32,8 +33,28 @@ class TestDeploymentWorkflows(utils.TestCommand):
self.websocket.__enter__ = lambda s: self.websocket
self.websocket.__exit__ = lambda s, *exc: None
self.tripleoclient.messaging_websocket.return_value = self.websocket
self.app.client_manager.tripleoclient = self.tripleoclient
tc = self.app.client_manager.tripleoclient = self.tripleoclient
tc.create_mistral_context = plugin.ClientWrapper(
instance=FakeInstanceData
).create_mistral_context
self.gcn = mock.patch(
'tripleo_common.actions.config.DownloadConfigAction',
autospec=True
)
self.gcn.start()
self.addCleanup(self.gcn.stop)
self.ansible = mock.patch(
'tripleo_common.actions.ansible.AnsibleGenerateInventoryAction',
autospec=True
)
self.ansible.start()
self.addCleanup(self.ansible.stop)
config_mock = mock.patch(
'tripleo_common.actions.config.GetOvercloudConfig',
autospec=True
)
config_mock.start()
self.addCleanup(config_mock.stop)
self.message_success = iter([{
"execution": {"id": "IDID"},
"status": "SUCCESS",
@ -100,6 +121,7 @@ class TestDeploymentWorkflows(utils.TestCommand):
self, mock_role_net_ip_map,
mock_blacklisted_ip_addresses):
stack = mock.Mock()
stack.output_show.return_value = []
mock_role_net_ip_map.return_value = {
'Controller': {
'ctlplane': ['1.1.1.1', '2.2.2.2', '3.3.3.3'],
@ -126,29 +148,15 @@ class TestDeploymentWorkflows(utils.TestCommand):
expected = ['4.4.4.4', '6.6.6.6', '11.11.11.11']
self.assertEqual(sorted(expected), sorted(ips))
def test_config_download_already_in_progress(
self):
log = mock.Mock()
stack = mock.Mock()
stack.stack_name = 'stacktest'
clients = mock.Mock()
mock_execution = mock.Mock()
mock_execution.input = '{"plan_name": "stacktest"}'
mock_return = mock.Mock(return_value=[mock_execution])
clients.workflow_engine.executions.find = mock_return
self.assertRaises(exceptions.ConfigDownloadInProgress,
deployment.config_download,
log, clients, stack, 'templates', 'ssh_user',
'ssh_key', 'ssh_networks', 'output_dir', False,
'timeout')
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
@mock.patch('tripleoclient.workflows.deployment.base')
def test_config_download_already_in_progress_for_diff_stack(
self, mock_base):
self, mock_base, mock_playbook):
log = mock.Mock()
stack = mock.Mock()
stack.stack_name = 'stacktest'
stack.output_show.return_value = {'output': {'output_value': []}}
clients = mock.Mock()
mock_execution = mock.Mock()
mock_execution.input = '{"plan_name": "someotherstack"}'

View File

@ -60,9 +60,12 @@ from heatclient import exc as hc_exc
from six.moves.urllib import error as url_error
from six.moves.urllib import request
from tripleo_common.actions import config
from tripleoclient import constants
from tripleoclient import exceptions
LOG = logging.getLogger(__name__ + ".utils")
@ -209,7 +212,7 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
plan='overcloud', gathering_policy='smart',
extra_env_variables=None, parallel_run=False,
callback_whitelist=None, ansible_cfg=None,
ansible_timeout=30):
ansible_timeout=30, reproduce_command=False):
"""Simple wrapper for ansible-playbook.
:param playbook: Playbook filename.
@ -286,6 +289,13 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
:param ansible_timeout: Timeout for ansible connections.
:type ansible_timeout: int
:param reproduce_command: Enable or disable option to reproduce ansible
commands upon failure. This option will produce
a bash script that can reproduce a failing
playbook command which is helpful for debugging
and retry purposes.
:type reproduce_command: Boolean
"""
def _playbook_check(play):
@ -331,23 +341,7 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
'fact_cache'
)
makedirs(ansible_fact_path)
extravars = {
'ansible_ssh_extra_args': (
'-o UserKnownHostsFile={} '
'-o StrictHostKeyChecking=no '
'-o ControlMaster=auto '
'-o ControlPersist=30m '
'-o ServerAliveInterval=64 '
'-o ServerAliveCountMax=1024 '
'-o Compression=no '
'-o TCPKeepAlive=yes '
'-o VerifyHostKeyDNS=no '
'-o ForwardX11=no '
'-o ForwardAgent=yes '
'-o PreferredAuthentications=publickey '
'-T'
).format(os.devnull)
}
extravars = dict()
if extra_vars:
if isinstance(extra_vars, dict):
extravars.update(extra_vars)
@ -363,6 +357,21 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
callback_whitelist = ','.join([callback_whitelist, 'profile_tasks'])
env = os.environ.copy()
env['ANSIBLE_SSH_ARGS'] = (
'-o UserKnownHostsFile={} '
'-o StrictHostKeyChecking=no '
'-o ControlMaster=auto '
'-o ControlPersist=30m '
'-o ServerAliveInterval=64 '
'-o ServerAliveCountMax=1024 '
'-o Compression=no '
'-o TCPKeepAlive=yes '
'-o VerifyHostKeyDNS=no '
'-o ForwardX11=no '
'-o ForwardAgent=yes '
'-o PreferredAuthentications=publickey '
'-T'
).format(os.devnull)
env['ANSIBLE_DISPLAY_FAILED_STDERR'] = True
env['ANSIBLE_FORKS'] = 36
env['ANSIBLE_TIMEOUT'] = ansible_timeout
@ -483,6 +492,8 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
else:
env.update(extra_env_variables)
command_path = None
with TempDirs(chdir=False) as ansible_artifact_path:
if 'ANSIBLE_CONFIG' not in env and not ansible_cfg:
ansible_cfg = os.path.join(ansible_artifact_path, 'ansible.cfg')
@ -533,6 +544,21 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
runner_config.env['ANSIBLE_STDOUT_CALLBACK'] = \
r_opts['envvars']['ANSIBLE_STDOUT_CALLBACK']
runner = ansible_runner.Runner(config=runner_config)
if reproduce_command:
command_path = os.path.join(
playbook_dir,
"ansible-playbook-command.sh"
)
with open(command_path, 'w') as f:
f.write('#!/usr/bin/env bash\n')
f.write('echo -e "Exporting environment variables"\n')
for key, value in r_opts['envvars'].items():
f.write('export {}="{}"\n'.format(key, value))
f.write('echo -e "Running Ansible command"\n')
f.write('{} $@\n'.format(' '.join(runner_config.command)))
os.chmod(command_path, 0o750)
status, rc = runner.run()
if rc != 0:
@ -545,6 +571,14 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None,
rc
)
)
if command_path:
err_msg += (
', To rerun the failed command manually execute the'
' following script: {}'.format(
command_path
)
)
if not quiet:
LOG.error(err_msg)
raise ansible_runner.AnsibleRunnerException(err_msg)
@ -1337,6 +1371,51 @@ def load_environment_directories(directories):
return environments
def get_config(clients, container):
"""Get cloud config.
:param clients: Application client object.
:type clients: Object
:param container: Container name to pull from.
:type container: String.
"""
context = clients.tripleoclient.create_mistral_context()
config_action = config.GetOvercloudConfig(container=container)
config_action.run(context=context)
def get_key(stack):
"""Returns the private key from the local file system.
Searches for and returns the stack private key. If the key is inaccessible
for any reason, the process will fall back to using the users key. If no
key is found, this method will return None.
:params stack: name of the stack to use
:type stack: String
:returns: String || None
"""
stack_dir = os.path.join(constants.DEFAULT_WORK_DIR, stack)
stack_key_file = os.path.join(stack_dir, 'ssh_private_key')
user_dir = os.path.join(os.path.expanduser("~"), '.ssh')
user_key_file = os.path.join(user_dir, 'id_rsa_tripleo')
legacy_dir = os.path.join(constants.DEFAULT_WORK_DIR, '.ssh')
legacy_key_file = os.path.join(legacy_dir, 'tripleo-admin-rsa')
for key_file in [stack_key_file, user_key_file, legacy_key_file]:
try:
if os.path.exists(key_file):
with open(key_file):
return key_file
except IOError:
pass
else:
return
def get_tripleo_ansible_inventory(inventory_file=None,
ssh_user='tripleo-admin',
stack='overcloud',
@ -1352,7 +1431,7 @@ def get_tripleo_ansible_inventory(inventory_file=None,
'--ansible_ssh_user', ssh_user,
'--undercloud-connection', undercloud_connection,
'--undercloud-key-file',
'/var/lib/mistral/.ssh/tripleo-admin-rsa',
get_key(stack=stack),
'--static-yaml-inventory', inventory_file)
except processutils.ProcessExecutionError as e:
message = _("Failed to generate inventory: %s") % str(e)
@ -1483,7 +1562,8 @@ def run_update_ansible_action(log, clients, stack, nodes, inventory,
module_path='/usr/share/ansible-modules',
limit_hosts=nodes,
tags=tags,
skip_tags=skip_tags)
skip_tags=skip_tags,
extra_vars=extra_vars)
def parse_extra_vars(extra_var_strings):

View File

@ -675,7 +675,7 @@ class DeployOvercloud(command.Command):
parser.add_argument(
'--overcloud-ssh-key',
default=os.path.join(
os.path.expanduser('~'), '.ssh', 'id_rsa'),
os.path.expanduser('~'), '.ssh', 'id_rsa_tripleo'),
help=_('Key path for ssh access to overcloud nodes.')
)
parser.add_argument(
@ -972,16 +972,17 @@ class DeployOvercloud(command.Command):
parsed_args.deployment_python_interpreter
deployment.config_download(
self.log, self.clients, stack,
parsed_args.templates, parsed_args.overcloud_ssh_user,
parsed_args.overcloud_ssh_key,
self.log,
self.clients,
stack,
parsed_args.overcloud_ssh_network,
parsed_args.output_dir,
parsed_args.override_ansible_cfg,
timeout,
verbosity=(self.app_args.verbose_level - 1),
deployment_options=deployment_options,
in_flight_validations=parsed_args.inflight)
in_flight_validations=parsed_args.inflight
)
except Exception:
deployment.set_deployment_status(
clients=self.clients,

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
from oslo_config import cfg
from oslo_log import log as logging
@ -86,10 +87,8 @@ class ExternalUpdateRun(command.Command):
default=[])
parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true',
default=False,
help=_('Run ansible-playbook directly via '
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
default=True,
help=_('This option no longer has any effect.')
)
return parser
@ -101,19 +100,20 @@ class ExternalUpdateRun(command.Command):
verbosity = self.app_args.verbose_level - 1
stack = parsed_args.stack
ansible_dir = None
key = package_update.get_key(stack=stack)
# Disable mistral
if parsed_args.no_workflow:
ansible_dir = oooutils.download_ansible_playbooks(orchestration,
stack)
key, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=parsed_args.no_workflow,
stack=stack,
orchestration=orchestration
)
# Run ansible:
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
parsed_args.static_inventory, parsed_args.ssh_user, stack,
return_inventory_file_path=True)
limit_hosts = 'all'
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)
extra_vars['ansible_become'] = True
oooutils.run_update_ansible_action(
self.log, clients, stack, limit_hosts, inventory, playbook,

View File

@ -86,10 +86,8 @@ class ExternalUpgradeRun(command.Command):
default=[])
parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true',
default=False,
help=_('Run ansible-playbook directly via '
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
default=True,
help=_('This option no longer has any effect.')
)
return parser
@ -101,20 +99,20 @@ class ExternalUpgradeRun(command.Command):
verbosity = self.app_args.verbose_level - 1
stack = parsed_args.stack
ansible_dir = None
key = package_update.get_key(stack=stack)
# Disable mistral
if parsed_args.no_workflow:
ansible_dir = oooutils.download_ansible_playbooks(orchestration,
stack)
key, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=parsed_args.no_workflow,
stack=stack,
orchestration=orchestration
)
# Run ansible:
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
parsed_args.static_inventory, parsed_args.ssh_user, stack,
return_inventory_file_path=True)
limit_hosts = 'all'
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)
extra_vars['ansible_become'] = True
oooutils.run_update_ansible_action(
self.log, clients, stack, limit_hosts, inventory, playbook,
constants.EXTERNAL_UPGRADE_PLAYBOOKS, parsed_args.ssh_user,

View File

@ -83,7 +83,7 @@ class FFWDUpgradePrepare(DeployOvercloud):
super(FFWDUpgradePrepare, self).take_action(parsed_args)
package_update.update(clients, container=stack_name)
package_update.get_config(clients, container=stack_name)
oooutils.get_config(clients, container=stack_name)
overcloudrcs = deployment.create_overcloudrc(
clients, container=stack_name)
@ -145,10 +145,8 @@ class FFWDUpgradeRun(command.Command):
)
parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true',
default=False,
help=_('Run ansible-playbook directly via '
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
default=True,
help=_('This option no longer has any effect.')
)
return parser
@ -160,24 +158,26 @@ class FFWDUpgradeRun(command.Command):
orchestration = clients.orchestration
stack = parsed_args.stack
ansible_dir = None
key = package_update.get_key(stack=stack)
# Disable mistral
if parsed_args.no_workflow:
ansible_dir = oooutils.download_ansible_playbooks(orchestration,
stack)
key, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=parsed_args.no_workflow,
stack=stack,
orchestration=orchestration
)
# Run ansible:
inventory = oooutils.get_tripleo_ansible_inventory(
inventory_file=parsed_args.static_inventory,
ssh_user=parsed_args.ssh_user, stack=parsed_args.stack)
ssh_user=parsed_args.ssh_user, stack=parsed_args.stack,
return_inventory_file_path=True)
# Don't expost limit_hosts. We need this on the whole overcloud.
limit_hosts = ''
extra_vars = {'ansible_become': True}
oooutils.run_update_ansible_action(
self.log, clients, parsed_args.stack, limit_hosts, inventory,
constants.FFWD_UPGRADE_PLAYBOOK, [], parsed_args.ssh_user,
(None if parsed_args.no_workflow else package_update),
verbosity=verbosity, workdir=ansible_dir, priv_key=key)
verbosity=verbosity, workdir=ansible_dir, priv_key=key,
extra_vars=extra_vars)
class FFWDUpgradeConverge(DeployOvercloud):

View File

@ -198,10 +198,11 @@ class DeleteNode(command.Command):
.format(stack=stack.stack_name, nodes=nodes_text))
scale.scale_down(
clients,
stack.stack_name,
nodes,
parsed_args.timeout
log=self.log,
clients=clients,
stack=stack,
nodes=nodes,
timeout=parsed_args.timeout
)
if parsed_args.baremetal_deployment:

View File

@ -72,7 +72,7 @@ class UpdatePrepare(DeployOvercloud):
super(UpdatePrepare, self).take_action(parsed_args)
package_update.update(clients, container=stack_name)
package_update.get_config(clients, container=stack_name)
oooutils.get_config(clients, container=stack_name)
self.log.info("Update init on stack {0} complete.".format(
parsed_args.stack))
@ -131,10 +131,8 @@ class UpdateRun(command.Command):
)
parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true',
default=False,
help=_('Run ansible-playbook directly via '
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
default=True,
help=_('This option no longer has any effect.')
)
return parser
@ -146,19 +144,20 @@ class UpdateRun(command.Command):
verbosity = self.app_args.verbose_level - 1
stack = parsed_args.stack
ansible_dir = None
key = package_update.get_key(stack=stack)
# Disable mistral
if parsed_args.no_workflow:
ansible_dir = oooutils.download_ansible_playbooks(orchestration,
stack)
key, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=parsed_args.no_workflow,
stack=stack,
orchestration=orchestration
)
# Run ansible:
limit_hosts = parsed_args.limit
playbook = parsed_args.playbook
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
parsed_args.static_inventory, parsed_args.ssh_user, stack,
return_inventory_file_path=True)
extra_vars = {'ansible_become': True}
oooutils.run_update_ansible_action(self.log, clients, stack,
limit_hosts, inventory, playbook,
constants.MINOR_UPDATE_PLAYBOOKS,
@ -167,7 +166,8 @@ class UpdateRun(command.Command):
else package_update),
verbosity=verbosity,
workdir=ansible_dir,
priv_key=key)
priv_key=key,
extra_vars=extra_vars)
class UpdateConverge(DeployOvercloud):

View File

@ -73,7 +73,7 @@ class UpgradePrepare(DeployOvercloud):
constants.UPGRADE_PREPARE_ENV)
super(UpgradePrepare, self).take_action(parsed_args)
package_update.update(clients, container=stack_name)
package_update.get_config(clients, container=stack_name)
oooutils.get_config(clients, container=stack_name)
overcloudrcs = deployment.create_overcloudrc(
clients, container=stack_name)
@ -179,10 +179,8 @@ class UpgradeRun(command.Command):
default='overcloud'))
parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true',
default=False,
help=_('Run ansible-playbook directly via '
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
default=True,
help=_('This option no longer has any effect.')
)
return parser
@ -204,20 +202,21 @@ class UpgradeRun(command.Command):
orchestration = clients.orchestration
stack = parsed_args.stack
ansible_dir = None
key = package_update.get_key(stack=stack)
# Disable mistral
if parsed_args.no_workflow:
ansible_dir = oooutils.download_ansible_playbooks(orchestration,
stack)
key, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=parsed_args.no_workflow,
stack=stack,
orchestration=orchestration
)
# Run ansible:
limit_hosts = parsed_args.limit
playbook = parsed_args.playbook
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
parsed_args.static_inventory, parsed_args.ssh_user, stack,
return_inventory_file_path=True)
skip_tags = self._validate_skip_tags(parsed_args.skip_tags)
extra_vars = {'ansible_become': True}
oooutils.run_update_ansible_action(self.log, clients, stack,
limit_hosts, inventory, playbook,
constants.MAJOR_UPGRADE_PLAYBOOKS,
@ -228,7 +227,8 @@ class UpgradeRun(command.Command):
skip_tags,
verbosity,
workdir=ansible_dir,
priv_key=key)
priv_key=key,
extra_vars=extra_vars)
playbooks = (constants.MAJOR_UPGRADE_PLAYBOOKS
if playbook == 'all' else playbook)

View File

@ -12,18 +12,20 @@
from __future__ import print_function
import copy
import getpass
import os
import pprint
import time
import yaml
from heatclient.common import event_utils
from openstackclient import shell
from tripleo_common.actions import ansible
from tripleo_common.actions import config
from tripleo_common.actions import deployment
from tripleo_common.actions import swifthelper
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
from tripleoclient.constants import DEFAULT_WORK_DIR
from tripleoclient import exceptions
from tripleoclient import utils
@ -251,70 +253,209 @@ def enable_ssh_admin(stack, hosts, ssh_user, ssh_key, timeout):
print("Enabling ssh admin - COMPLETE.")
def config_download(log, clients, stack, templates,
ssh_user, ssh_key, ssh_network,
output_dir, override_ansible_cfg, timeout, verbosity=0,
deployment_options={},
in_flight_validations=False):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
def config_download(log, clients, stack, ssh_network=None,
output_dir=None, override_ansible_cfg=None,
timeout=None, verbosity=0, deployment_options=None,
in_flight_validations=False,
ansible_playbook_name='deploy_steps_playbook.yaml',
limit_list=None):
"""Run config download.
if in_flight_validations:
skip_tags = ''
else:
:param log: Logging object
:type log: Object
:param clients: openstack clients
:type clients: Object
:param stack: Heat Stack object
:type stack: Object
:param ssh_network: Network named used to access the overcloud.
:type ssh_network: String
:param override_ansible_cfg: Ansible configuration file location.
:type override_ansible_cfg: String
:param timeout: Ansible connection timeout. If None, the effective
default will be set to 30 at playbook runtime.
:type timeout: Integer
:param verbosity: Ansible verbosity level.
:type verbosity: Integer
:param deployment_options: Additional deployment options.
:type deployment_options: Dictionary
:param in_flight_validations: Enable or Disable inflight validations.
:type in_flight_validations: Boolean
:param ansible_playbook_name: Name of the playbook to execute.
:type ansible_playbook_name: String
:param limit_list: List of hosts to limit the current playbook to.
:type limit_list: List
"""
def _log_and_print(message, logger, level='info', print_msg=True):
"""Print and log a given message.
:param message: Message to print and log.
:type message: String
:param log: Logging object
:type log: Object
:param level: Log level.
:type level: String
:param print_msg: Print messages to stdout.
:type print_msg: Boolean
"""
if print_msg:
print(message)
log = getattr(logger, level)
log(message)
if not output_dir:
output_dir = DEFAULT_WORK_DIR
if not deployment_options:
deployment_options = dict()
if not in_flight_validations:
skip_tags = 'opendev-validation'
else:
skip_tags = None
workflow_input = {
'verbosity': verbosity,
'plan_name': stack.stack_name,
'ssh_network': ssh_network,
'config_download_timeout': timeout,
'deployment_options': deployment_options,
'skip_tags': skip_tags
}
if output_dir:
workflow_input.update(dict(work_dir=output_dir))
if override_ansible_cfg:
with open(override_ansible_cfg) as cfg:
override_ansible_cfg_contents = cfg.read()
workflow_input.update(
dict(override_ansible_cfg=override_ansible_cfg_contents))
if not timeout:
timeout = 30
workflow_name = 'tripleo.deployment.v1.config_download_deploy'
# NOTE(cloudnull): List of hosts to limit the current playbook execution
# The list is later converted into an ansible compatible
# string. Storing hosts in list format will ensure all
# entries are consistent.
if not limit_list:
limit_list = list()
# Check to see if any existing executions for the same stack are already in
# progress.
log.info("Checking for existing executions of config_download for "
"%s" % stack.stack_name)
for execution in workflow_client.executions.find(
workflow_name=workflow_name,
state='RUNNING'):
try:
exec_input = yaml.safe_load(execution.input)
except yaml.YAMLError as ye:
log.error("YAML error loading input for execution %s: %s" %
(execution.id, str(ye)))
raise
if exec_input.get('plan_name', 'overcloud') == stack.stack_name:
raise exceptions.ConfigDownloadInProgress(execution.id,
stack.stack_name)
with tripleoclients.messaging_websocket() as ws:
execution = base.start_workflow(
workflow_client,
workflow_name,
workflow_input=workflow_input
with utils.TempDirs() as tmp:
utils.run_ansible_playbook(
playbook='cli-grant-local-access.yaml',
inventory='localhost,',
workdir=tmp,
playbook_dir=ANSIBLE_TRIPLEO_PLAYBOOKS,
extra_vars={
'access_path': output_dir,
'execution_user': getpass.getuser()
}
)
for payload in base.wait_for_messages(workflow_client, ws, execution):
print(payload['message'])
stack_work_dir = os.path.join(output_dir, stack.stack_name)
context = clients.tripleoclient.create_mistral_context()
_log_and_print(
message='Checking for blacklisted hosts from stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
blacklist_show = stack.output_show('BlacklistedHostnames')
blacklist_stack_output = blacklist_show.get('output', dict())
blacklist_stack_output_value = blacklist_stack_output.get('output_value')
if blacklist_stack_output_value:
limit_list.extend(
['!{}'.format(i) for i in blacklist_stack_output_value if i]
)
_log_and_print(
message='Retrieving configuration for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
utils.get_config(clients, container=stack.stack_name)
_log_and_print(
message='Downloading configuration for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
download = config.DownloadConfigAction(
work_dir=stack_work_dir,
container_config='{}-config'.format(stack.stack_name)
)
work_dir = download.run(context=context)
_log_and_print(
message='Retrieving keyfile for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
key_file = utils.get_key(stack=stack.stack_name)
_log_and_print(
message='Generating information for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
inventory_kwargs = {
'ansible_ssh_user': 'tripleo-admin',
'work_dir': work_dir,
'plan_name': stack.stack_name,
'undercloud_key_file': key_file
}
if ssh_network:
inventory_kwargs['ssh_network'] = ssh_network
python_interpreter = deployment_options.get('ansible_python_interpreter')
if python_interpreter:
inventory_kwargs['ansible_python_interpreter'] = python_interpreter
inventory = ansible.AnsibleGenerateInventoryAction(**inventory_kwargs)
inventory_path = inventory.run(context=context)
_log_and_print(
message='Executing deployment playbook for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
if payload['status'] == 'SUCCESS':
print("Overcloud configuration completed.")
else:
raise exceptions.DeploymentError("Overcloud configuration failed.")
# NOTE(cloudnull): Join the limit_list into an ansible compatible string.
# If it is an empty, the object will be reset to None.
limit_hosts = ':'.join(limit_list)
with utils.TempDirs() as tmp:
utils.run_ansible_playbook(
playbook=os.path.join(
stack_work_dir,
ansible_playbook_name
),
inventory=inventory_path,
workdir=tmp,
playbook_dir=work_dir,
skip_tags=skip_tags,
ansible_cfg=override_ansible_cfg,
verbosity=verbosity,
ssh_user='tripleo-admin',
key=key_file,
limit_hosts=limit_hosts,
ansible_timeout=timeout,
reproduce_command=True,
extra_env_variables={
'ANSIBLE_BECOME': True,
}
)
_log_and_print(
message='Overcloud configuration completed for stack: {}'.format(
stack.stack_name
),
logger=log,
print_msg=(verbosity == 0)
)
def config_download_export(clients, plan, config_type):

View File

@ -11,20 +11,17 @@
# under the License.
from __future__ import print_function
import os
import pprint
import time
from heatclient.common import event_utils
from openstackclient import shell
from tripleo_common.actions import config
from tripleoclient import constants
from tripleoclient import exceptions
from tripleoclient import utils
from tripleoclient.workflows import base
_WORKFLOW_TIMEOUT = 120 * 60 # 2h
@ -67,49 +64,6 @@ def update(clients, **workflow_input):
raise exceptions.DeploymentError("Heat Stack update failed.")
def get_config(clients, container):
"""Get cloud config.
:param clients: Application client object.
:type clients: Object
:param container: Container name to pull from.
:type container: String.
"""
context = clients.tripleoclient.create_mistral_context()
config_action = config.GetOvercloudConfig(container=container)
config_action.run(context=context)
def get_key(stack):
"""Returns the private key from the local file system.
Searches for and returns the stack private key. If the key is inaccessible
for any reason, the process will fall back to using the users key. If no
key is found, this method will return None.
:params stack: name of the stack to use
:type stack: String
:returns: String || None
"""
stack_dir = os.path.join(constants.DEFAULT_WORK_DIR, stack)
stack_key_file = os.path.join(stack_dir, 'ssh_private_key')
user_dir = os.path.join(os.path.expanduser("~"), '.ssh')
user_key_file = os.path.join(user_dir, 'id_rsa_tripleo')
for key_file in [stack_key_file, user_key_file]:
try:
if os.path.exists(key_file):
with open(key_file):
return key_file
except IOError:
pass
else:
return
def update_ansible(clients, **workflow_input):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient

View File

@ -16,65 +16,58 @@ from __future__ import print_function
from tripleo_common.actions import scale
from tripleoclient import exceptions
from tripleoclient import utils
from tripleoclient.workflows import base
from tripleoclient.workflows import deployment
def ansible_tear_down(clients, **workflow_input):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
workflow_input['playbook_name'] = 'scale_playbook.yaml'
with tripleoclients.messaging_websocket() as ws:
execution = base.start_workflow(
workflow_client,
'tripleo.deployment.v1.config_download_deploy',
workflow_input=workflow_input
)
for payload in base.wait_for_messages(workflow_client, ws, execution):
print(payload['message'])
if payload['status'] == 'SUCCESS':
print("Scale-down configuration completed.")
else:
raise exceptions.DeploymentError("Scale-down configuration failed.")
def scale_down(clients, plan_name, nodes, timeout=None):
def scale_down(log, clients, stack, nodes, timeout=None):
"""Unprovision and deletes overcloud nodes from a heat stack.
:param log: Logging object
:type log: Object
:param clients: Application client object.
:type clients: Object
:param stack: Heat Stack object
:type stack: Object
:param nodes: List of nodes to delete. If the node UUID is used the
UUID will be used to lookup the node name before being
passed through to the cleanup playbook.
:type nodes: List
:param timeout: Timeout to use when deleting nodes. If timeout is None
it will be set to 240.
:type timeout: Integer
:param plan: Plan name.
:type plan: String
:param nodes: List of nodes to delete.
:type nodes: List
"""
workflow_input = {
"plan_name": plan_name,
"nodes": nodes,
}
ansible_tear_down(clients, **workflow_input)
if not timeout:
timeout = 240
limit_list = list()
for node in nodes:
try:
_node = clients.compute.servers.get(node)
limit_list.append(_node.name)
except Exception:
limit_list.append(node)
deployment.config_download(
log=log,
clients=clients,
stack=stack,
timeout=timeout,
ansible_playbook_name='scale_playbook.yaml',
limit_list=limit_list
)
print('Running scale down')
context = clients.tripleoclient.create_mistral_context()
scale_down_action = scale.ScaleDownAction(nodes=nodes, timeout=timeout)
scale_down_action.run(context=context)
utils.wait_for_stack_ready(
orchestration_client=clients.orchestration,
stack_name=plan_name,
stack_name=stack.stack_name,
action='UPDATE'
)