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:
parent
712d8d7a61
commit
dc9ae1ac5b
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
)
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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()
|
||||
|
@ -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')
|
||||
|
@ -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"}'
|
||||
|
@ -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):
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user