diff --git a/actions/actions.py b/actions/actions.py index 081144ff..375788e6 100755 --- a/actions/actions.py +++ b/actions/actions.py @@ -67,6 +67,7 @@ from hooks.rabbit_utils import ( assess_status, list_vhosts, vhost_queue_info, + rabbitmq_version_newer_or_equal, ) @@ -86,9 +87,17 @@ def resume(args): def cluster_status(args): """Return the output of 'rabbitmqctl cluster_status'.""" try: - clusterstat = check_output(['rabbitmqctl', 'cluster_status'], - universal_newlines=True) - action_set({'output': clusterstat}) + if rabbitmq_version_newer_or_equal('3.7'): + clusterstat = check_output(['rabbitmqctl', 'cluster_status', + '--formatter', 'json'], + universal_newlines=True) + + clusterstat = json.loads(clusterstat) + action_set({'output': json.dumps(clusterstat, indent=4)}) + else: + clusterstat = check_output(['rabbitmqctl', 'cluster_status'], + universal_newlines=True) + action_set({'output': clusterstat}) except CalledProcessError as e: action_set({'output': e.output}) action_fail('Failed to run rabbitmqctl cluster_status') diff --git a/hooks/rabbit_utils.py b/hooks/rabbit_utils.py index e808046a..2ea76832 100644 --- a/hooks/rabbit_utils.py +++ b/hooks/rabbit_utils.py @@ -426,7 +426,7 @@ def rabbitmqctl(action, *args): # # [1]: https://github.com/rabbitmq/rabbitmq-server/commit/3dd58ae1 WAIT_TIMEOUT_SECONDS = 180 - focal_or_newer = _rabbitmq_version_newer_or_equal('3.8') + focal_or_newer = rabbitmq_version_newer_or_equal('3.8') cmd = [] if 'wait' in action and not focal_or_newer: @@ -672,7 +672,7 @@ def disable_plugin(plugin): def get_managment_port(): - if _rabbitmq_version_newer_or_equal('3'): + if rabbitmq_version_newer_or_equal('3'): return 15672 else: return 55672 @@ -1581,7 +1581,7 @@ def nrpe_update_cluster_check(nrpe_compat, user, password): check_cmd='{}/check_rabbitmq_cluster.py'.format(NAGIOS_PLUGINS)) -def _rabbitmq_version_newer_or_equal(version): +def rabbitmq_version_newer_or_equal(version): """Compare the installed RabbitMQ version :param version: Version to compare with diff --git a/unit_tests/test_actions.py b/unit_tests/test_actions.py index ea260130..a0bb6807 100644 --- a/unit_tests/test_actions.py +++ b/unit_tests/test_actions.py @@ -15,6 +15,8 @@ import mock from functools import wraps +import json + from unit_tests.test_utils import CharmTestCase with mock.patch('charmhelpers.core.hookenv.cached') as cached: @@ -57,9 +59,34 @@ class ClusterStatusTestCase(CharmTestCase): def setUp(self): super(ClusterStatusTestCase, self).setUp( - actions, ["check_output", "action_set", "action_fail"]) + actions, ["check_output", "action_set", "action_fail", + "rabbitmq_version_newer_or_equal"]) + + def test_cluster_status_json(self): + self.rabbitmq_version_newer_or_equal.return_value = True + self.check_output.return_value = json.dumps({"Status": + "Cluster status OK"}) + actions.cluster_status([]) + self.check_output.assert_called_once_with(['rabbitmqctl', + 'cluster_status', + '--formatter', 'json'], + universal_newlines=True) + self.action_set.assert_called() + + def test_cluster_status_exception_json(self): + self.rabbitmq_version_newer_or_equal.return_value = True + self.check_output.side_effect = actions.CalledProcessError(1, + "Failure") + actions.cluster_status([]) + self.check_output.assert_called_once_with(['rabbitmqctl', + 'cluster_status', + '--formatter', 'json'], + universal_newlines=True) + self.action_set.assert_called() + self.action_fail.assert_called() def test_cluster_status(self): + self.rabbitmq_version_newer_or_equal.return_value = False self.check_output.return_value = b'Cluster status OK' actions.cluster_status([]) self.check_output.assert_called_once_with(['rabbitmqctl', @@ -68,6 +95,7 @@ class ClusterStatusTestCase(CharmTestCase): self.action_set.assert_called() def test_cluster_status_exception(self): + self.rabbitmq_version_newer_or_equal.return_value = False self.check_output.side_effect = actions.CalledProcessError(1, "Failure") actions.cluster_status([]) diff --git a/unit_tests/test_rabbit_utils.py b/unit_tests/test_rabbit_utils.py index 5ff5746f..9d90d469 100644 --- a/unit_tests/test_rabbit_utils.py +++ b/unit_tests/test_rabbit_utils.py @@ -422,7 +422,7 @@ class UtilsTests(CharmTestCase): @mock.patch('rabbit_utils.leader_node') @mock.patch('rabbit_utils.clustered') @mock.patch('rabbit_utils.cmp_pkgrevno') - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_cluster_with_not_clustered( self, mock_new_rabbitmq, mock_cmp_pkgrevno, mock_clustered, mock_leader_node, mock_running_nodes, mock_time, mock_check_output, @@ -686,7 +686,7 @@ class UtilsTests(CharmTestCase): f.assert_called_once_with('assessor', services='s1', ports=None) @mock.patch('rabbit_utils.subprocess.check_call') - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_rabbitmqctl_wait_before_focal(self, mock_new_rabbitmq, check_call): mock_new_rabbitmq.return_value = False @@ -696,7 +696,7 @@ class UtilsTests(CharmTestCase): '/var/lib/rabbitmq.pid']) @mock.patch('rabbit_utils.subprocess.check_call') - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_rabbitmqctl_wait_focal_or_newer(self, mock_new_rabbitmq, check_call): mock_new_rabbitmq.return_value = True @@ -711,7 +711,7 @@ class UtilsTests(CharmTestCase): check_call.assert_called_with(['/usr/sbin/rabbitmqctl', 'start_app']) @mock.patch('rabbit_utils.subprocess.check_call') - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_rabbitmqctl_wait_fail(self, mock_new_rabbitmq, check_call): mock_new_rabbitmq.return_value = True @@ -883,12 +883,12 @@ class UtilsTests(CharmTestCase): mock_cluster_ready.return_value = True self.assertTrue(rabbit_utils.leader_node_is_ready()) - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_get_managment_port_legacy(self, mock_new_rabbitmq): mock_new_rabbitmq.return_value = False self.assertEqual(rabbit_utils.get_managment_port(), 55672) - @mock.patch('rabbit_utils._rabbitmq_version_newer_or_equal') + @mock.patch('rabbit_utils.rabbitmq_version_newer_or_equal') def test_get_managment_port(self, mock_new_rabbitmq): mock_new_rabbitmq.return_value = True self.assertEqual(rabbit_utils.get_managment_port(), 15672)