diff --git a/changelogs/fragments/602-show-all-slaves-status.yaml b/changelogs/fragments/602-show-all-slaves-status.yaml new file mode 100644 index 0000000..8c9320c --- /dev/null +++ b/changelogs/fragments/602-show-all-slaves-status.yaml @@ -0,0 +1,2 @@ +bugfixes: + - mysql_info - the ``slave_status`` filter was returning an empty list on MariaDB with multiple replication channels. It now returns all channels by running ``SHOW ALL SLAVES STATUS`` for MariaDB servers (https://github.com/ansible-collections/community.mysql/issues/603). diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py index b95d20d..10ccfcf 100644 --- a/plugins/module_utils/mysql.py +++ b/plugins/module_utils/mysql.py @@ -207,6 +207,13 @@ def get_server_version(cursor): return version_str +def get_server_implementation(cursor): + if 'mariadb' in get_server_version(cursor).lower(): + return "mariadb" + else: + return "mysql" + + def set_session_vars(module, cursor, session_vars): """Set session vars.""" for var, value in session_vars.items(): diff --git a/plugins/modules/mysql_info.py b/plugins/modules/mysql_info.py index 73e403a..303921b 100644 --- a/plugins/modules/mysql_info.py +++ b/plugins/modules/mysql_info.py @@ -5,6 +5,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function + __metaclass__ = type DOCUMENTATION = r''' @@ -292,6 +293,7 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import ( mysql_driver_fail_msg, get_connector_name, get_connector_version, + get_server_implementation, ) from ansible_collections.community.mysql.plugins.module_utils.user import ( @@ -325,9 +327,10 @@ class MySQL_Info(object): 5. add info about the new subset with an example to RETURN block """ - def __init__(self, module, cursor): + def __init__(self, module, cursor, server_implementation): self.module = module self.cursor = cursor + self.server_implementation = server_implementation self.info = { 'version': {}, 'databases': {}, @@ -497,7 +500,10 @@ class MySQL_Info(object): def __get_slave_status(self): """Get slave status if the instance is a slave.""" - res = self.__exec_sql('SHOW SLAVE STATUS') + if self.server_implementation == "mariadb": + res = self.__exec_sql('SHOW ALL SLAVES STATUS') + else: + res = self.__exec_sql('SHOW SLAVE STATUS') if res: for line in res: host = line['Master_Host'] @@ -738,10 +744,12 @@ def main(): 'Exception message: %s' % (connector_name, connector_version, config_file, to_native(e))) module.fail_json(msg) + server_implementation = get_server_implementation(cursor) + ############################### # Create object and do main job - mysql = MySQL_Info(module, cursor) + mysql = MySQL_Info(module, cursor, server_implementation) module.exit_json(changed=False, connector_name=connector_name, diff --git a/tests/unit/plugins/module_utils/test_mysql.py b/tests/unit/plugins/module_utils/test_mysql.py index ac4de24..5410575 100644 --- a/tests/unit/plugins/module_utils/test_mysql.py +++ b/tests/unit/plugins/module_utils/test_mysql.py @@ -1,9 +1,10 @@ from __future__ import (absolute_import, division, print_function) + __metaclass__ = type import pytest -from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version +from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version, get_server_implementation from ..utils import dummy_cursor_class @@ -22,3 +23,21 @@ def test_get_server_version(cursor_return_version, cursor_return_type): """ cursor = dummy_cursor_class(cursor_return_version, cursor_return_type) assert get_server_version(cursor) == cursor_return_version + + +@pytest.mark.parametrize( + 'cursor_return_version,cursor_return_type,server_implementation', + [ + ('5.7.0-mysql', 'dict', 'mysql'), + ('8.0.0-mysql', 'list', 'mysql'), + ('10.5.0-mariadb', 'dict', 'mariadb'), + ('10.5.1-mariadb', 'list', 'mariadb'), + ] +) +def test_get_server_implamentation(cursor_return_version, cursor_return_type, server_implementation): + """ + Test that server implementation are handled properly by get_server_implementation() whether the server version returned as a list or dict. + """ + cursor = dummy_cursor_class(cursor_return_version, cursor_return_type) + + assert get_server_implementation(cursor) == server_implementation diff --git a/tests/unit/plugins/modules/test_mysql_info.py b/tests/unit/plugins/modules/test_mysql_info.py index 7aa9577..6aaf66e 100644 --- a/tests/unit/plugins/modules/test_mysql_info.py +++ b/tests/unit/plugins/modules/test_mysql_info.py @@ -14,15 +14,15 @@ from ansible_collections.community.mysql.plugins.modules.mysql_info import MySQL @pytest.mark.parametrize( - 'suffix,cursor_output', + 'suffix,cursor_output,server_implementation', [ - ('mysql', '5.5.1-mysql'), - ('log', '5.7.31-log'), - ('mariadb', '10.5.0-mariadb'), - ('', '8.0.22'), + ('mysql', '5.5.1-mysql', 'mysql'), + ('log', '5.7.31-log', 'mysql'), + ('mariadb', '10.5.0-mariadb', 'mariadb'), + ('', '8.0.22', 'mysql'), ] ) -def test_get_info_suffix(suffix, cursor_output): +def test_get_info_suffix(suffix, cursor_output, server_implementation): def __cursor_return_value(input_parameter): if input_parameter == "SHOW GLOBAL VARIABLES": cursor.fetchall.return_value = [{"Variable_name": "version", "Value": cursor_output}] @@ -32,6 +32,6 @@ def test_get_info_suffix(suffix, cursor_output): cursor = MagicMock() cursor.execute.side_effect = __cursor_return_value - info = MySQL_Info(MagicMock(), cursor) + info = MySQL_Info(MagicMock(), cursor, server_implementation) assert info.get_info([], [], False)['version']['suffix'] == suffix