Merge "Create Ceph pools/cephx keys before overcloud deploy" into stable/wallaby

This commit is contained in:
Zuul 2022-05-25 18:00:40 +00:00 committed by Gerrit Code Review
commit f18eec5ca3
4 changed files with 162 additions and 0 deletions

View File

@ -2711,3 +2711,24 @@ class TestCheckDeployBackups(TestCase):
self.assertIn(
'Deploy backup files disk usage 90.00% exceeds 50% percent',
mock_log.warning.call_args_list[0][0][0])
class TestGetCephadmKeys(TestCase):
def test_get_cephadm_keys(self):
user = 'openstack'
key = 'AQC+vYNXgDAgAhAAc8UoYt+OTz5uhV7ItLdwUw=='
pools = ['foo', 'bar']
keys = utils.get_tripleo_cephadm_keys(user,
key,
pools)
expected = [
{'name': 'client.openstack',
'key': key,
'mode': '0600',
'caps': {
'mgr': 'allow *',
'mon': 'profile rbd',
'osd': 'profile rbd pool=foo, profile rbd pool=bar'}}]
self.assertEqual(keys, expected)

View File

@ -60,6 +60,7 @@ class TestOvercloudCephDeploy(fakes.FakePlaybookExecution):
verbosity=3,
skip_tags='cephadm_ssh_user',
reproduce_command=False,
extra_vars_file=mock.ANY,
extra_vars={
"baremetal_deployed_path": mock.ANY,
"deployed_ceph_tht_path": mock.ANY,
@ -85,6 +86,24 @@ class TestOvercloudCephDeploy(fakes.FakePlaybookExecution):
self.assertRaises(osc_lib_exc.CommandError,
self.cmd.take_action, parsed_args)
@mock.patch('tripleoclient.utils.get_ceph_networks', autospect=True)
@mock.patch('tripleoclient.utils.TempDirs', autospect=True)
@mock.patch('os.path.abspath', autospect=True)
@mock.patch('os.path.exists', autospect=True)
@mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True)
def test_overcloud_deploy_ceph_ansible_no_force(self,
mock_playbook,
mock_abspath,
mock_path_exists,
mock_tempdirs,
mock_get_ceph_networks):
arglist = ['deployed-metal.yaml', '--yes',
'--ansible-extra-vars', 'foo.yml',
'--output', 'deployed-ceph.yaml']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.assertRaises(osc_lib_exc.CommandError,
self.cmd.take_action, parsed_args)
class TestOvercloudCephUserDisable(fakes.FakePlaybookExecution):
def setUp(self):

View File

@ -3350,3 +3350,23 @@ def check_deploy_backups(
"percent of disk size. Consider deleting some "
"older deploy backups.".format(fs_usage, disk_usage_percent))
print(backup_table, file=sys.stdout)
def get_tripleo_cephadm_keys(username, key, pools):
"""Get a tripleo_cephadm_keys structure to be passed to
the tripleo-ansible role tripleo_cephadm. Assumes only
one key will be created to write to all pools.
:param username: string, e.g. 'openstack'
:param key: string for cephx secret key, e.g. 'AQC+...w=='
:param pools: list of pool names, e.g. ['vms', 'images']
:return a list containing a single dictionary
"""
return [dict(
name='client.' + username,
key=key,
mode='0600',
caps=dict(
mgr='allow *',
mon='profile rbd',
osd=', '.join(list(
map(lambda x: 'profile rbd pool=' + x, pools)))))]

View File

@ -15,12 +15,16 @@
import logging
import os
import re
import uuid
import yaml
from osc_lib import exceptions as oscexc
from osc_lib.i18n import _
from osc_lib import utils
from tripleo_common.utils import passwords
from tripleoclient import command
from tripleoclient import constants
from tripleoclient import utils as oooutils
@ -188,6 +192,54 @@ class OvercloudCephDeploy(command.Command):
parser.add_argument('--force', default=False,
action='store_true',
help=_("Run command regardless of consequences."))
parser.add_argument('--ansible-extra-vars',
help=_(
"Path to an existing Ansible vars file which "
"can override any variable in "
"tripleo-ansible. If "
"'--ansible-extra-vars vars.yaml' is passed, "
"then 'ansible-playbook -e @vars.yaml ...' is "
"used to call tripleo-ansible Ceph roles. "
"Warning: requires --force as not all "
"options ensure a functional deployment."))
parser.add_argument('--ceph-client-username',
help=_(
"Name of the cephx user. E.g. if "
"'openstack' is used, then "
"'ceph auth get client.openstack' will "
"return a working user with key and "
"capabilities on the deployed Ceph cluster. "
"Ignored unless tripleo_cephadm_pools is set "
"via --ansible-extra-vars. "
"If this parameter is not set and "
"tripleo_cephadm_keys is set via "
"--ansible-extra-vars, then "
"'openstack' will be used. "
"Used to set CephClientUserName in --output."),
default='openstack'),
parser.add_argument('--ceph-client-key',
help=_(
"Value of the cephx key. E.g. "
"'AQC+vYNXgDAgAhAAc8UoYt+OTz5uhV7ItLdwUw=='. "
"Ignored unless tripleo_cephadm_pools is set "
"via --ansible-extra-vars. "
"If this parameter is not set and "
"tripleo_cephadm_keys is set via "
"--ansible-extra-vars, then a random "
"key will be generated. "
"Used to set CephClientKey in --output."),
default='')
parser.add_argument('--skip-cephx-keys', default=False,
action='store_true',
help=_("Do not create cephx keys even if "
"tripleo_cephadm_pools is set via "
"--ansible-extra-vars. If this option "
"is used, then even the defaults of "
"--ceph-client-key and "
"--ceph-client-username are ignored, "
"but the pools defined via "
"--ansible-extra-vars "
"are still created."))
parser.add_argument('--single-host-defaults', default=False,
action='store_true',
help=_("Adjust configuration defaults to suit "
@ -318,6 +370,7 @@ class OvercloudCephDeploy(command.Command):
"working_dir": working_dir,
"stack_name": parsed_args.stack,
}
extra_vars_file = None
# optional paths to pass to playbook
if parsed_args.roles_data:
if not os.path.exists(parsed_args.roles_data):
@ -386,6 +439,52 @@ class OvercloudCephDeploy(command.Command):
if parsed_args.cephadm_extra_args and parsed_args.force:
extra_vars['tripleo_cephadm_extra_args'] = \
parsed_args.cephadm_extra_args
if parsed_args.ansible_extra_vars and not parsed_args.force:
raise oscexc.CommandError(
"--ansible-extra-vars requires --force.")
if parsed_args.ansible_extra_vars and parsed_args.force:
if not os.path.exists(parsed_args.ansible_extra_vars):
raise oscexc.CommandError(
"Ansible vars file not found --ansible-extra-vars %s."
% os.path.abspath(parsed_args.ansible_extra_vars))
else:
# utils.run_ansible_playbook() assums extra_vars_file is a dict
with open(os.path.abspath(parsed_args.ansible_extra_vars),
'r') as f:
extra_vars_file = yaml.safe_load(f)
if (not parsed_args.skip_cephx_keys and
'tripleo_cephadm_pools' in extra_vars_file and # noqa
'tripleo_cephadm_keys' not in extra_vars_file): # noqa
# create tripleo_cephadm_keys and add it to extra_vars
self.log.debug("Generating tripleo_cephadm_keys")
if len(parsed_args.ceph_client_key) == 0:
parsed_args.ceph_client_key = \
passwords.create_cephx_key()
cephx = re.compile(r"^[a-zA-Z0-9+/]{38}==$")
if not cephx.match(parsed_args.ceph_client_key):
msg = ("'%s' is not a valid cephx key"
% str(parsed_args.ceph_client_key))
raise oscexc.CommandError(msg)
extra_vars['tripleo_cephadm_keys'] = \
oooutils.get_tripleo_cephadm_keys(
parsed_args.ceph_client_username,
parsed_args.ceph_client_key,
list(map(lambda x: x.get('name', ''),
extra_vars_file['tripleo_cephadm_pools']))
)
# pass CLI args to THT via --output deployed_ceph.yaml
extra_vars['ceph_client_key'] = parsed_args.ceph_client_key
extra_vars['ceph_client_username'] =\
parsed_args.ceph_client_username
else:
self.log.debug("Not generating tripleo_cephadm_keys. "
"Either --skip-cephx-keys was used, "
"or tripleo_cephadm_pools was not "
"in %s, or tripleo_cephadm_keys was "
"in %s." % (
(parsed_args.ansible_extra_vars,)*2))
# optional container vars to pass to playbook
keys = ['ceph_namespace', 'ceph_image', 'ceph_tag']
push_sub_keys = ['ceph_namespace']
@ -481,6 +580,7 @@ class OvercloudCephDeploy(command.Command):
verbosity=oooutils.playbook_verbosity(self=self),
reproduce_command=False,
extra_vars=hosts_extra_vars,
extra_vars_file=extra_vars_file,
)
else:
self.log.debug("Not updating /etc/hosts because "
@ -501,6 +601,7 @@ class OvercloudCephDeploy(command.Command):
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
verbosity=oooutils.playbook_verbosity(self=self),
extra_vars=reg_extra_vars,
extra_vars_file=extra_vars_file,
reproduce_command=False,
)
else:
@ -522,6 +623,7 @@ class OvercloudCephDeploy(command.Command):
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
verbosity=oooutils.playbook_verbosity(self=self),
extra_vars=extra_vars,
extra_vars_file=extra_vars_file,
reproduce_command=False,
skip_tags=','.join(skip_tags),
)