From 80562a3db118b3f76185bbb844e9b5a3bdaefcd7 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Mon, 7 Jul 2025 15:18:38 -0400 Subject: [PATCH] qa/tasks/ceph.key_rotate: provide mechanism to rotate client keys Signed-off-by: Patrick Donnelly (cherry picked from commit 1de9241a4b3c6e6836689f19960ca41136873f6f) --- qa/tasks/ceph.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/qa/tasks/ceph.py b/qa/tasks/ceph.py index d40c934affe..8ea2bd58930 100644 --- a/qa/tasks/ceph.py +++ b/qa/tasks/ceph.py @@ -1682,9 +1682,10 @@ def key_rotate(ctx, config): tasks: - ceph.key_rotate: [all] - For example:: + For example:: tasks: - ceph.key_rotate: + clients: [client.admin, ...] daemons: [mon.*, mds.*, osd.0] key_type: recommended @@ -1699,6 +1700,7 @@ def key_rotate(ctx, config): testdir = teuthology.get_testdir(ctx) key_type = config.setdefault('key_type', 'recommended') + log.info("key_type is %s", key_type) coverage_dir = f'{testdir}/archive/coverage' cluster_name = config.setdefault('cluster', 'ceph') @@ -1717,6 +1719,7 @@ def key_rotate(ctx, config): new_mon_key = None for role in daemons: + log.debug("daemon role is: %s", role) cluster, type_, id_ = teuthology.split_role(role) daemon = ctx.daemons.get_daemon(type_, id_, cluster) daemon.stop() @@ -1736,7 +1739,7 @@ def key_rotate(ctx, config): new_key = p.stdout.getvalue() importme = '/tmp/importme' - log.info("generated new key %s", new_key) + log.info("generated new daemon key %s", new_key) daemon.remote.write_file(importme, BytesIO(new_key.encode())) daemon_dir = DATA_PATH.format(type_=type_, cluster=cluster_name, id_=id_) @@ -1753,6 +1756,53 @@ def key_rotate(ctx, config): daemon.restart() + clients = config.get('clients', []) + firstmon = teuthology.get_first_mon(ctx, config, cluster_name) + keyring = ctx.ceph[cluster_name].keyring + for client in clients: + if client == 'all': + client_roles = [ "client." + x for x in teuthology.all_roles_of_type(ctx.cluster, 'client')] + client_roles.append("client.admin") + else: + client_roles = [client] + log.info("client roles: %s", client_roles) + for role in client_roles: + _, _, id_ = teuthology.split_role(role) + keyrings = [ctx.ceph[cluster_name].keyring] + if role == "client.admin": + remote = ctx.ceph[cluster_name].admin + else: + (remote, ) = ctx.cluster.only(role).remotes.keys() + keyrings.append(f"/etc/ceph/ceph.client.{id_}.keyring") + + log.info("rotating %s on %s", role, remote) + + p = manager.ceph(f"auth rotate --key-type={key_type} {role}") + new_key = p.stdout.getvalue() + + importme = '/tmp/importme' + log.info("generated new client key %s", new_key) + remote.write_file(importme, BytesIO(new_key.encode())) + + authimport = [ + *authtool, + '--import-keyring', + importme, + ] + remote.run(args=['sudo', 'cat', importme]) + for keyring in keyrings: + try: + out = remote.read_file(keyring, sudo=True) + log.info("keyring before:\n%s", out) + except FileNotFoundError: + log.warning("skipping keyring {}", keyring) + pass + args = list(authimport) + args.append(keyring) + remote.run(args=args) + out = remote.read_file(keyring, sudo=True) + log.info("keyring after:\n%s", out) + yield -- 2.39.5