Skip to content

Commit

Permalink
Using show all slaves status when using MariaDB to be consistent wi…
Browse files Browse the repository at this point in the history
…th MySQL (#602)

* Using `show all slaves status` whe using MariaDB to be consistent
with the MySQL behaviour.

* Fixing lint issues

* Fix issue by using dict attribute

* Fix unit tests

* fix lint test

* Add unit tests

* Fix unit tests

* Adding changlog fragment

* Update changelogs/fragments/602-show-all-slaves-status.yaml

Co-authored-by: Laurent Indermühle <[email protected]>

* Refactoring change by moving common logic to the module_utils

* Fix sanity checks

* Fix sanity checks

* Adding lines to fix sanity checks

* Fixing sanity checks

* Update changelogs/fragments/602-show-all-slaves-status.yaml

Co-authored-by: Andrew Klychkov <[email protected]>

* Removing is_mariadb and is_mysql functions

---------

Co-authored-by: Laurent Indermühle <[email protected]>
Co-authored-by: Andrew Klychkov <[email protected]>
  • Loading branch information
3 people authored Jan 19, 2024
1 parent 051aa48 commit 852c19a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/602-show-all-slaves-status.yaml
Original file line number Diff line number Diff line change
@@ -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).
7 changes: 7 additions & 0 deletions plugins/module_utils/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
14 changes: 11 additions & 3 deletions plugins/modules/mysql_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'''
Expand Down Expand Up @@ -292,6 +293,7 @@
mysql_driver_fail_msg,
get_connector_name,
get_connector_version,
get_server_implementation,
)

from ansible_collections.community.mysql.plugins.module_utils.user import (
Expand Down Expand Up @@ -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': {},
Expand Down Expand Up @@ -497,7 +500,10 @@ def __get_master_status(self):

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']
Expand Down Expand Up @@ -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,
Expand Down
21 changes: 20 additions & 1 deletion tests/unit/plugins/module_utils/test_mysql.py
Original file line number Diff line number Diff line change
@@ -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


Expand All @@ -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
14 changes: 7 additions & 7 deletions tests/unit/plugins/modules/test_mysql_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@


@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}]
Expand All @@ -32,6 +32,6 @@ def __cursor_return_value(input_parameter):
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

0 comments on commit 852c19a

Please sign in to comment.