Generate openrc files during control host bootstrap

Fixes an issue where the admin-openrc.sh and public-openrc.sh files
would not be generated when preparing a new control host environment for
an existing cloud. These files are now generated during 'kayobe control
host bootstrap' if the Kolla Ansible 'passwords.yml' file exists in the
Kayobe configuration.

Change-Id: I47cc95bc4c4198532c8cfd2c105f1c7033e7b932
Story: 2001667
Task: 6713
This commit is contained in:
Mark Goddard 2019-06-25 20:44:47 +01:00
parent d1b51adb3d
commit 9d01cf39b7
5 changed files with 119 additions and 4 deletions

View File

@ -109,7 +109,7 @@ def _get_vars_files(config_path):
vars_files = []
for vars_file in os.listdir(config_path):
abs_path = os.path.join(config_path, vars_file)
if utils.is_readable_file(abs_path):
if utils.is_readable_file(abs_path)["result"]:
root, ext = os.path.splitext(vars_file)
if ext in (".yml", ".yaml", ".json"):
vars_files.append(abs_path)
@ -277,3 +277,10 @@ def prune_galaxy_roles(parsed_args):
]
LOG.debug("Removing roles: %s", ",".join(roles_to_remove))
utils.galaxy_remove(roles_to_remove, "ansible/roles")
def passwords_yml_exists(parsed_args):
"""Return whether passwords.yml exists in the kayobe configuration."""
passwords_path = os.path.join(parsed_args.config_path,
'kolla', 'passwords.yml')
return utils.is_readable_file(passwords_path)["result"]

View File

@ -144,12 +144,15 @@ class KollaAnsibleMixin(object):
return kolla_ansible.run_seed(*args, **kwargs)
class ControlHostBootstrap(KayobeAnsibleMixin, VaultMixin, Command):
class ControlHostBootstrap(KayobeAnsibleMixin, KollaAnsibleMixin, VaultMixin,
Command):
"""Bootstrap the Kayobe control environment.
* Downloads and installs Ansible roles from Galaxy.
* Generates an SSH key for the Ansible control host, if one does not exist.
* Installs kolla-ansible on the Ansible control host.
* Generates admin-openrc.sh and public-openrc.sh files when passwords.yml
exists.
"""
def take_action(self, parsed_args):
@ -157,8 +160,31 @@ class ControlHostBootstrap(KayobeAnsibleMixin, VaultMixin, Command):
ansible.install_galaxy_roles(parsed_args)
playbooks = _build_playbook_list("bootstrap")
self.run_kayobe_playbooks(parsed_args, playbooks, ignore_limit=True)
passwords_exist = ansible.passwords_yml_exists(parsed_args)
if passwords_exist:
# Install and generate configuration - necessary for post-deploy.
ka_tags = None
else:
ka_tags = "install"
playbooks = _build_playbook_list("kolla-ansible")
self.run_kayobe_playbooks(parsed_args, playbooks, tags="install",
self.run_kayobe_playbooks(parsed_args, playbooks, tags=ka_tags,
ignore_limit=True)
if passwords_exist:
# If we are bootstrapping a control host for an existing
# environment, we should also generate the admin-openrc.sh and
# public-openrc.sh scripts that provide admin credentials.
# FIXME: Fudge to work around incorrect configuration path.
extra_vars = {"node_config_directory":
parsed_args.kolla_config_path}
self.run_kolla_ansible_overcloud(parsed_args, "post-deploy",
extra_vars=extra_vars)
# Create an environment file for accessing the public API as the
# admin user.
playbooks = _build_playbook_list("public-openrc")
self.run_kayobe_playbooks(parsed_args, playbooks,
ignore_limit=True)

View File

@ -35,9 +35,12 @@ class TestApp(cliff.app.App):
class TestCase(unittest.TestCase):
@mock.patch.object(ansible, "install_galaxy_roles", autospec=True)
@mock.patch.object(ansible, "passwords_yml_exists", autospec=True)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_control_host_bootstrap(self, mock_run, mock_install):
def test_control_host_bootstrap(self, mock_run, mock_passwords,
mock_install):
mock_passwords.return_value = False
command = commands.ControlHostBootstrap(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
@ -59,6 +62,50 @@ class TestCase(unittest.TestCase):
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(ansible, "install_galaxy_roles", autospec=True)
@mock.patch.object(ansible, "passwords_yml_exists", autospec=True)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
@mock.patch.object(commands.KollaAnsibleMixin,
"run_kolla_ansible_overcloud")
def test_control_host_bootstrap_with_passwords(
self, mock_kolla_run, mock_run, mock_passwords, mock_install):
mock_passwords.return_value = True
command = commands.ControlHostBootstrap(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
result = command.run(parsed_args)
self.assertEqual(0, result)
mock_install.assert_called_once_with(parsed_args)
expected_calls = [
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "bootstrap.yml")],
ignore_limit=True
),
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "kolla-ansible.yml")],
tags=None,
ignore_limit=True
),
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "public-openrc.yml")],
ignore_limit=True
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
expected_calls = [
mock.call(
mock.ANY,
"post-deploy",
extra_vars={"node_config_directory": "/etc/kolla"},
)
]
self.assertEqual(expected_calls, mock_kolla_run.call_args_list)
@mock.patch.object(ansible, "install_galaxy_roles", autospec=True)
@mock.patch.object(ansible, "prune_galaxy_roles", autospec=True)
@mock.patch.object(commands.KayobeAnsibleMixin,

View File

@ -445,3 +445,29 @@ class TestCase(unittest.TestCase):
]
mock_remove.assert_called_once_with(expected_roles,
"ansible/roles")
@mock.patch.object(utils, 'is_readable_file', autospec=True)
def test_passwords_yml_exists_false(self, mock_is_readable):
parser = argparse.ArgumentParser()
ansible.add_args(parser)
parsed_args = parser.parse_args([])
mock_is_readable.return_value = {"result": False}
result = ansible.passwords_yml_exists(parsed_args)
self.assertFalse(result)
mock_is_readable.assert_called_once_with(
"/etc/kayobe/kolla/passwords.yml")
@mock.patch.object(utils, 'is_readable_file', autospec=True)
def test_passwords_yml_exists_true(self, mock_is_readable):
parser = argparse.ArgumentParser()
ansible.add_args(parser)
parsed_args = parser.parse_args(["--config-path", "/path/to/config"])
mock_is_readable.return_value = {"result": True}
result = ansible.passwords_yml_exists(parsed_args)
self.assertTrue(result)
mock_is_readable.assert_called_once_with(
"/path/to/config/kolla/passwords.yml")

View File

@ -0,0 +1,9 @@
---
fixes:
- |
Fixes an issue where the ``admin-openrc.sh`` and ``public-openrc.sh`` files
would not be generated when preparing a new control host environment for an
existing cloud. These files are now generated during ``kayobe control host
bootstrap`` if the Kolla Ansible ``passwords.yml`` file exists in the
Kayobe configuration. See `story 2001667
<https://storyboard.openstack.org/#!/story/2001667>`__ for details.