Merge "Implement command for deleting OIDC signing keys"

This commit is contained in:
Zuul
2025-05-15 10:00:39 +00:00
committed by Gerrit Code Review
2 changed files with 80 additions and 0 deletions

View File

@ -28,6 +28,8 @@ import jwt
import testtools
import sqlalchemy
from zuul.lib import encryption
from zuul.lib.keystorage import OIDCSigningKeys
from zuul.zk import ZooKeeperClient
from zuul.zk.locks import SessionAwareLock
from zuul.cmd.client import parse_cutoff
@ -352,6 +354,55 @@ class TestKeyOperations(ZuulTestCase):
data.get('/keystorage/gerrit/org'))
class TestOIDCSigningKeyOperation(ZuulTestCase):
tenant_config_file = 'config/single-tenant/main.yaml'
def test_delete_oidc_signing_keys(self):
algorithm = "RS256"
keystore = self.scheds.first.sched.keystore
# Makesure keys are created by calling getLatestOidcSigningKeys()
private_key1, _, version1 = keystore.getLatestOidcSigningKeys(
algorithm)
with keystore.createZKContext() as context:
# Check that the keys are there
test_keys1 = OIDCSigningKeys.loadKeys(
context, algorithm)
self.assertEqual(len(test_keys1.keys), 1)
self.assertEqual(version1, 0)
# Config and exeute the delete command
config_file = os.path.join(self.test_root, 'zuul.conf')
with open(config_file, 'w') as f:
self.config.write(f)
p = subprocess.Popen(
[os.path.join(sys.prefix, 'bin/zuul-admin'),
'-c', config_file,
'delete-oidc-signing-keys',
algorithm,
],
stdout=subprocess.PIPE)
out, _ = p.communicate()
self.log.debug(out.decode('utf8'))
self.assertEqual(p.returncode, 0)
# Keys should be gone
test_keys2 = OIDCSigningKeys.loadKeys(
context, algorithm)
self.assertIsNone(test_keys2)
# New keys are auto generated when calling getLatestOidcSigningKeys()
private_key2, _, version2 = keystore.getLatestOidcSigningKeys(
algorithm)
self.assertEqual(4096, private_key2.key_size)
self.assertNotEqual(
encryption.serialize_rsa_private_key(private_key2),
encryption.serialize_rsa_private_key(private_key1))
self.assertEqual(version2, 0)
class TestOfflineZKOperations(ZuulTestCase):
tenant_config_file = 'config/single-tenant/main.yaml'

View File

@ -491,6 +491,20 @@ class Client(zuul.cmd.ZuulApp):
help='project name')
cmd_delete_keys.set_defaults(func=self.delete_keys)
cmd_delete_oidc_signing_keys = subparsers.add_parser(
'delete-oidc-signing-keys',
help='delete OIDC signing keys',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent('''\
Delete the OIDC signing keys of an algorithm
'''))
cmd_delete_oidc_signing_keys.set_defaults(
command='delete-oidc-signing-keys')
cmd_delete_oidc_signing_keys.add_argument(
'algorithm', type=str, help='algorithm name')
cmd_delete_oidc_signing_keys.set_defaults(
func=self.delete_oidc_signing_keys)
# ZK Maintenance
cmd_delete_state = subparsers.add_parser(
'delete-state',
@ -1050,6 +1064,21 @@ class Client(zuul.cmd.ZuulApp):
args.connection, args.project)
sys.exit(0)
def delete_oidc_signing_keys(self):
logging.basicConfig(level=logging.INFO)
zk_client = ZooKeeperClient.fromConfig(self.config)
zk_client.connect()
try:
password = self.config["keystore"]["password"]
except KeyError:
raise RuntimeError("No key store password configured!")
keystore = KeyStorage(zk_client, password=password)
algorithm = self.args.algorithm
keystore.deleteOidcSigningKeys(algorithm)
self.log.info("Delete OIDC signing keys for %s", algorithm)
sys.exit(0)
def delete_state(self):
logging.basicConfig(level=logging.INFO)