Merge "Create Ceph pools/cephx keys before overcloud deploy" into stable/wallaby
This commit is contained in:
commit
f18eec5ca3
@ -2711,3 +2711,24 @@ class TestCheckDeployBackups(TestCase):
|
|||||||
self.assertIn(
|
self.assertIn(
|
||||||
'Deploy backup files disk usage 90.00% exceeds 50% percent',
|
'Deploy backup files disk usage 90.00% exceeds 50% percent',
|
||||||
mock_log.warning.call_args_list[0][0][0])
|
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)
|
||||||
|
@ -60,6 +60,7 @@ class TestOvercloudCephDeploy(fakes.FakePlaybookExecution):
|
|||||||
verbosity=3,
|
verbosity=3,
|
||||||
skip_tags='cephadm_ssh_user',
|
skip_tags='cephadm_ssh_user',
|
||||||
reproduce_command=False,
|
reproduce_command=False,
|
||||||
|
extra_vars_file=mock.ANY,
|
||||||
extra_vars={
|
extra_vars={
|
||||||
"baremetal_deployed_path": mock.ANY,
|
"baremetal_deployed_path": mock.ANY,
|
||||||
"deployed_ceph_tht_path": mock.ANY,
|
"deployed_ceph_tht_path": mock.ANY,
|
||||||
@ -85,6 +86,24 @@ class TestOvercloudCephDeploy(fakes.FakePlaybookExecution):
|
|||||||
self.assertRaises(osc_lib_exc.CommandError,
|
self.assertRaises(osc_lib_exc.CommandError,
|
||||||
self.cmd.take_action, parsed_args)
|
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):
|
class TestOvercloudCephUserDisable(fakes.FakePlaybookExecution):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -3350,3 +3350,23 @@ def check_deploy_backups(
|
|||||||
"percent of disk size. Consider deleting some "
|
"percent of disk size. Consider deleting some "
|
||||||
"older deploy backups.".format(fs_usage, disk_usage_percent))
|
"older deploy backups.".format(fs_usage, disk_usage_percent))
|
||||||
print(backup_table, file=sys.stdout)
|
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)))))]
|
||||||
|
@ -15,12 +15,16 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
import yaml
|
||||||
|
|
||||||
from osc_lib import exceptions as oscexc
|
from osc_lib import exceptions as oscexc
|
||||||
from osc_lib.i18n import _
|
from osc_lib.i18n import _
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
|
from tripleo_common.utils import passwords
|
||||||
|
|
||||||
from tripleoclient import command
|
from tripleoclient import command
|
||||||
from tripleoclient import constants
|
from tripleoclient import constants
|
||||||
from tripleoclient import utils as oooutils
|
from tripleoclient import utils as oooutils
|
||||||
@ -188,6 +192,54 @@ class OvercloudCephDeploy(command.Command):
|
|||||||
parser.add_argument('--force', default=False,
|
parser.add_argument('--force', default=False,
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help=_("Run command regardless of consequences."))
|
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,
|
parser.add_argument('--single-host-defaults', default=False,
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help=_("Adjust configuration defaults to suit "
|
help=_("Adjust configuration defaults to suit "
|
||||||
@ -318,6 +370,7 @@ class OvercloudCephDeploy(command.Command):
|
|||||||
"working_dir": working_dir,
|
"working_dir": working_dir,
|
||||||
"stack_name": parsed_args.stack,
|
"stack_name": parsed_args.stack,
|
||||||
}
|
}
|
||||||
|
extra_vars_file = None
|
||||||
# optional paths to pass to playbook
|
# optional paths to pass to playbook
|
||||||
if parsed_args.roles_data:
|
if parsed_args.roles_data:
|
||||||
if not os.path.exists(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:
|
if parsed_args.cephadm_extra_args and parsed_args.force:
|
||||||
extra_vars['tripleo_cephadm_extra_args'] = \
|
extra_vars['tripleo_cephadm_extra_args'] = \
|
||||||
parsed_args.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
|
# optional container vars to pass to playbook
|
||||||
keys = ['ceph_namespace', 'ceph_image', 'ceph_tag']
|
keys = ['ceph_namespace', 'ceph_image', 'ceph_tag']
|
||||||
push_sub_keys = ['ceph_namespace']
|
push_sub_keys = ['ceph_namespace']
|
||||||
@ -481,6 +580,7 @@ class OvercloudCephDeploy(command.Command):
|
|||||||
verbosity=oooutils.playbook_verbosity(self=self),
|
verbosity=oooutils.playbook_verbosity(self=self),
|
||||||
reproduce_command=False,
|
reproduce_command=False,
|
||||||
extra_vars=hosts_extra_vars,
|
extra_vars=hosts_extra_vars,
|
||||||
|
extra_vars_file=extra_vars_file,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.log.debug("Not updating /etc/hosts because "
|
self.log.debug("Not updating /etc/hosts because "
|
||||||
@ -501,6 +601,7 @@ class OvercloudCephDeploy(command.Command):
|
|||||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||||
verbosity=oooutils.playbook_verbosity(self=self),
|
verbosity=oooutils.playbook_verbosity(self=self),
|
||||||
extra_vars=reg_extra_vars,
|
extra_vars=reg_extra_vars,
|
||||||
|
extra_vars_file=extra_vars_file,
|
||||||
reproduce_command=False,
|
reproduce_command=False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -522,6 +623,7 @@ class OvercloudCephDeploy(command.Command):
|
|||||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||||
verbosity=oooutils.playbook_verbosity(self=self),
|
verbosity=oooutils.playbook_verbosity(self=self),
|
||||||
extra_vars=extra_vars,
|
extra_vars=extra_vars,
|
||||||
|
extra_vars_file=extra_vars_file,
|
||||||
reproduce_command=False,
|
reproduce_command=False,
|
||||||
skip_tags=','.join(skip_tags),
|
skip_tags=','.join(skip_tags),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user