Merge pull request #1029 from ajkavanagh/feature/test-rotate-rabbitmq-service-user-password

Add test to rotate rabbitmq-server service user password
This commit is contained in:
Alex Kavanagh
2023-05-14 18:41:32 +01:00
committed by GitHub

View File

@@ -14,17 +14,22 @@
"""RabbitMQ Testing."""
import configparser
import json
import logging
import re
import time
import uuid
import unittest
import yaml
import juju
import tenacity
import zaza.model
import zaza.openstack.charm_tests.test_utils as test_utils
import zaza.openstack.utilities.generic as generic_utils
import zaza.openstack.utilities.juju as juju_utils
import zaza.openstack.utilities.openstack as openstack_utils
from zaza.openstack.utilities.generic import get_series
from zaza.openstack.utilities.os_versions import CompareHostReleases
@@ -470,6 +475,104 @@ class RmqTests(test_utils.OpenStackBaseTest):
logging.info('OK')
class RmqRotateServiceUserPasswordTests(test_utils.OpenStackBaseTest):
"""RMQ service user password rotation tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running RMQ service user rotation tests."""
super().setUpClass()
cls.application = "rabbitmq-server"
def test_rotate_cinder_service_user_password(self):
"""Verify action used to rotate a service user (cinder) password."""
CINDER_APP = 'cinder'
CINDER_PASSWD_KEY = "cinder.passwd"
CINDER_CONF_FILE = '/etc/cinder/cinder.conf'
def _get_password_from_cinder_leader():
conf = zaza.model.file_contents(
'cinder/leader', CINDER_CONF_FILE)
config = configparser.ConfigParser()
config.read_string(conf)
connection_info = config['DEFAULT']['transport_url']
match = re.match(r"^rabbit.*cinder:(.+)@", connection_info)
if match:
return match[1]
self.fail("Couldn't find mysql password in {}"
.format(connection_info))
# only do the test if keystone is in the model
applications = zaza.model.sync_deployed(self.model_name)
if CINDER_APP not in applications:
self.skipTest(
'{} is not deployed, so not doing password rotation'
.format(CINDER_APP))
# get the users via the 'list-service-usernames' action.
logging.info(
"Getting usernames from rabbitmq-server that can have password "
"rotated.")
action = zaza.model.run_action_on_leader(
self.application,
'list-service-usernames',
action_params={}
)
usernames = yaml.safe_load(action.data['results']['usernames'])
self.assertIn(CINDER_APP, usernames)
logging.info("... usernames: %s", ', '.join(usernames))
# grab the password for cinder from the leader / to verify the change
old_cinder_passwd_on_rmq = juju_utils.leader_get(
self.application_name, CINDER_PASSWD_KEY).strip()
old_cinder_passwd_conf = _get_password_from_cinder_leader()
# verify that cinder is working.
cinder_client = openstack_utils.get_cinder_session_client(
self.keystone_session, version=3.42)
cinder_client.volumes.list()
# now rotate the password for keystone
# run the action to rotate the password.
logging.info("Rotating password for cinder in rabbitmq-server.")
zaza.model.run_action_on_leader(
self.application_name,
'rotate-service-user-password',
action_params={'service-user': 'cinder'},
)
# let everything settle.
logging.info("Waiting for model to settle.")
zaza.model.wait_for_agent_status()
zaza.model.block_until_all_units_idle()
# verify that the password has changed.
# Due to the async-ness of the whole model and when the various hooks
# will fire between rabbitmq-server and cinder, we retry a reasonable
# time to wait for everything to propagate through to the
# /etc/cinder/cinder.conf file.
for attempt in tenacity.Retrying(
reraise=True,
wait=tenacity.wait_fixed(30),
stop=tenacity.stop_after_attempt(20), # wait for max 10m
):
with attempt:
new_cinder_passwd_on_rmq = juju_utils.leader_get(
self.application_name, CINDER_PASSWD_KEY).strip()
new_cinder_passwd_conf = _get_password_from_cinder_leader()
self.assertNotEqual(old_cinder_passwd_on_rmq,
new_cinder_passwd_on_rmq)
self.assertNotEqual(old_cinder_passwd_conf,
new_cinder_passwd_conf)
self.assertEqual(new_cinder_passwd_on_rmq,
new_cinder_passwd_conf)
# finally, verify that cinder is still working.
cinder_client = openstack_utils.get_cinder_session_client(
self.keystone_session, version=3.42)
cinder_client.volumes.list()
class RabbitMQDeferredRestartTest(test_utils.BaseDeferredRestartTest):
"""Deferred restart tests."""