finally:
pass
+@contextlib.contextmanager
+def setup_ca_signed_keys(ctx, config):
+ # generate our ca key
+ cluster_name = config['cluster']
+ bootstrap_remote = ctx.ceph[cluster_name].bootstrap_remote
+ bootstrap_remote.run(args=[
+ 'sudo', 'ssh-keygen', '-t', 'rsa', '-f', '/root/ca-key', '-N', ''
+ ])
+
+ # not using read_file here because it runs dd as a non-root
+ # user and would hit permission issues
+ r = bootstrap_remote.run(args=[
+ 'sudo', 'cat', '/root/ca-key.pub'
+ ], stdout=StringIO())
+ ca_key_pub_contents = r.stdout.getvalue()
+
+ # make CA key accepted on each host
+ for remote in ctx.cluster.remotes.keys():
+ # write key to each host's /etc/ssh dir
+ remote.run(args=[
+ 'sudo', 'echo', ca_key_pub_contents,
+ run.Raw('|'),
+ 'sudo', 'tee', '-a', '/etc/ssh/ca-key.pub',
+ ])
+ # make sshd accept the CA signed key
+ remote.run(args=[
+ 'sudo', 'echo', 'TrustedUserCAKeys /etc/ssh/ca-key.pub',
+ run.Raw('|'),
+ 'sudo', 'tee', '-a', '/etc/ssh/sshd_config',
+ run.Raw('&&'),
+ 'sudo', 'systemctl', 'restart', 'sshd',
+ ])
+
+ # generate a new key pair and sign the pub key to make a cert
+ bootstrap_remote.run(args=[
+ 'sudo', 'ssh-keygen', '-t', 'rsa', '-f', '/root/cephadm-ssh-key', '-N', '',
+ run.Raw('&&'),
+ 'sudo', 'ssh-keygen', '-s', '/root/ca-key', '-I', 'user_root', '-n', 'root', '-V', '+52w', '/root/cephadm-ssh-key',
+ ])
+
+ # for debugging, to make sure this setup has worked as intended
+ for remote in ctx.cluster.remotes.keys():
+ remote.run(args=[
+ 'sudo', 'cat', '/etc/ssh/ca-key.pub'
+ ])
+ remote.run(args=[
+ 'sudo', 'cat', '/etc/ssh/sshd_config',
+ run.Raw('|'),
+ 'grep', 'TrustedUserCAKeys'
+ ])
+ bootstrap_remote.run(args=[
+ 'sudo', 'ls', '/root/'
+ ])
+
+ ctx.ca_signed_key_info = {}
+ ctx.ca_signed_key_info['ca-key'] = '/root/ca-key'
+ ctx.ca_signed_key_info['ca-key-pub'] = '/root/ca-key.pub'
+ ctx.ca_signed_key_info['private-key'] = '/root/cephadm-ssh-key'
+ ctx.ca_signed_key_info['ca-signed-cert'] = '/root/cephadm-ssh-key-cert.pub'
+
+ try:
+ yield
+ finally:
+ pass
@contextlib.contextmanager
def ceph_bootstrap(ctx, config):
'--output-config', '/etc/ceph/{}.conf'.format(cluster_name),
'--output-keyring',
'/etc/ceph/{}.client.admin.keyring'.format(cluster_name),
- '--output-pub-ssh-key', '{}/{}.pub'.format(testdir, cluster_name),
]
+
+ if not config.get("use-ca-signed-key", False):
+ cmd += ['--output-pub-ssh-key', '{}/{}.pub'.format(testdir, cluster_name)]
+ else:
+ # ctx.ca_signed_key_info should have been set up in
+ # setup_ca_signed_keys function which we expect to have
+ # run before bootstrap if use-ca-signed-key is true
+ signed_key_info = ctx.ca_signed_key_info
+ cmd += [
+ "--ssh-private-key", signed_key_info['private-key'],
+ "--ssh-signed-cert", signed_key_info['ca-signed-cert'],
+ ]
+
if config.get("no_cgroups_split") is True:
cmd.insert(cmd.index("bootstrap"), "--no-cgroups-split")
ctx.ceph[cluster_name].mon_keyring = \
bootstrap_remote.read_file(f'/var/lib/ceph/{fsid}/mon.{first_mon}/keyring', sudo=True)
- # fetch ssh key, distribute to additional nodes
- log.info('Fetching pub ssh key...')
- ssh_pub_key = bootstrap_remote.read_file(
- f'{testdir}/{cluster_name}.pub').decode('ascii').strip()
+ if not config.get("use-ca-signed-key", False):
+ # fetch ssh key, distribute to additional nodes
+ log.info('Fetching pub ssh key...')
+ ssh_pub_key = bootstrap_remote.read_file(
+ f'{testdir}/{cluster_name}.pub').decode('ascii').strip()
- log.info('Installing pub ssh key for root users...')
- ctx.cluster.run(args=[
- 'sudo', 'install', '-d', '-m', '0700', '/root/.ssh',
- run.Raw('&&'),
- 'echo', ssh_pub_key,
- run.Raw('|'),
- 'sudo', 'tee', '-a', '/root/.ssh/authorized_keys',
- run.Raw('&&'),
- 'sudo', 'chmod', '0600', '/root/.ssh/authorized_keys',
- ])
+ log.info('Installing pub ssh key for root users...')
+ ctx.cluster.run(args=[
+ 'sudo', 'install', '-d', '-m', '0700', '/root/.ssh',
+ run.Raw('&&'),
+ 'echo', ssh_pub_key,
+ run.Raw('|'),
+ 'sudo', 'tee', '-a', '/root/.ssh/authorized_keys',
+ run.Raw('&&'),
+ 'sudo', 'chmod', '0600', '/root/.ssh/authorized_keys',
+ ])
# set options
if config.get('allow_ptrace', True):
with contextutil.nested(
#if the cluster is already bootstrapped bypass corresponding methods
- lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\
+ lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \
else initialize_config(ctx=ctx, config=config),
lambda: ceph_initial(),
lambda: normalize_hostnames(ctx=ctx),
- lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\
+ lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \
else download_cephadm(ctx=ctx, config=config, ref=ref),
lambda: ceph_log(ctx=ctx, config=config),
lambda: ceph_crash(ctx=ctx, config=config),
lambda: pull_image(ctx=ctx, config=config),
- lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\
+ lambda: _bypass() if not (config.get('use-ca-signed-key', False)) \
+ else setup_ca_signed_keys(ctx, config),
+ lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \
else ceph_bootstrap(ctx, config),
lambda: crush_setup(ctx=ctx, config=config),
lambda: ceph_mons(ctx=ctx, config=config),