From 443dda4086715c170b553baa4c8de21fb88b511c Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Fri, 14 Jun 2024 20:20:10 +0200 Subject: [PATCH 1/7] Add options to start and stop group replication --- ...ication_add_group_replication_commands.yml | 2 + plugins/modules/mysql_replication.py | 64 ++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/mysql_replication_add_group_replication_commands.yml diff --git a/changelogs/fragments/mysql_replication_add_group_replication_commands.yml b/changelogs/fragments/mysql_replication_add_group_replication_commands.yml new file mode 100644 index 00000000..804de44b --- /dev/null +++ b/changelogs/fragments/mysql_replication_add_group_replication_commands.yml @@ -0,0 +1,2 @@ +minor_changes: + - mysql_replication - add ``startgroupreplication`` and ``stopgroupreplication`` options (https://github.com/ansible-collections/community.mysql/pull/93). \ No newline at end of file diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index b0caf118..e484c811 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -20,6 +20,7 @@ - Balazs Pocze (@banyek) - Andrew Klychkov (@Andersson007) - Dennis Urtubia (@dennisurtubia) +- Sebastian Pfahl (@eryx12o45) options: mode: description: @@ -32,7 +33,9 @@ C(stopreplica) (STOP REPLICA), C(resetprimary) (RESET MASTER) - supported since community.mysql 0.1.0, C(resetreplica) (RESET REPLICA), - C(resetreplicaall) (RESET REPLICA ALL). + C(resetreplicaall) (RESET REPLICA ALL), + C(startgroupreplication) (START GROUP_REPLICATION), + C(stopgroupreplication) (STOP GROUP_REPLICATION). type: str choices: - changeprimary @@ -44,6 +47,8 @@ - resetprimary - resetreplica - resetreplicaall + - startgroupreplication + - stopgroupreplication default: getreplica primary_host: description: @@ -284,6 +289,14 @@ mode: changeprimary fail_on_error: true +- name: Start mysql group replication + community.mysql.mysql_replication: + mode: startgroupreplication + +- name: Stop mysql group replication + community.mysql.mysql_replication: + mode: stopgroupreplication + ''' RETURN = r''' @@ -470,6 +483,38 @@ def changereplication(cursor, chm, channel=''): cursor.execute(query) +def startgroupreplication(module, cursor, fail_on_error=False, term='GROUP_REPLICATION'): + query = 'START %s' % term + + try: + executed_queries.append(query) + cursor.execute(query) + started = True + except mysql_driver.Warning as e: + started = False + except Exception as e: + if fail_on_error: + module.fail_json(msg="START %s failed: %s" % (term, to_native(e))) + started = False + return started + + +def stopgroupreplication(module, cursor, fail_on_error=False, term='GROUP_REPLICATION'): + query = 'STOP %s' % term + + try: + executed_queries.append(query) + cursor.execute(query) + stopped = True + except mysql_driver.Warning as e: + stopped = False + except Exception as e: + if fail_on_error: + module.fail_json(msg="STOP %s failed: %s" % (term, to_native(e))) + stopped = False + return stopped + + def main(): argument_spec = mysql_common_argument_spec() argument_spec.update( @@ -482,7 +527,9 @@ def main(): 'resetprimary', 'resetreplica', 'resetreplicaall', - 'changereplication']), + 'changereplication', + 'startgroupreplication', + 'stopgroupreplication']), primary_auto_position=dict(type='bool', default=False, aliases=['master_auto_position']), primary_host=dict(type='str', aliases=['master_host']), primary_user=dict(type='str', aliases=['master_user']), @@ -738,6 +785,19 @@ def main(): module.fail_json(msg='%s. Query == CHANGE REPLICATION SOURCE TO %s' % (to_native(e), chm)) result['changed'] = True module.exit_json(queries=executed_queries, **result) + elif mode in "startgroupreplication": + started = startgroupreplication(module, cursor, fail_on_error) + if started is True: + module.exit_json(msg="Group replication started ", changed=True, queries=executed_queries) + else: + module.exit_json(msg="Group replication already started (Or cannot be started)", changed=False, + ueries=executed_queries) + elif mode in "stopgroupreplication": + stopped = stopgroupreplication(module, cursor, channel, fail_on_error) + if stopped is True: + module.exit_json(msg="Group replication stopped", changed=True, queries=executed_queries) + else: + module.exit_json(msg="Group replication already stopped", changed=False, queries=executed_queries) warnings.simplefilter("ignore") From 8fd556e2aefa67846aef23354662095d1cbe7731 Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Mon, 17 Jun 2024 07:44:24 +0200 Subject: [PATCH 2/7] Add user and password option and fix test --- plugins/modules/mysql_replication.py | 26 ++++++++++++++++--- .../tasks/mysql_replication_initial.yml | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index e484c811..a1bf38a2 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -194,7 +194,16 @@ type: bool default: false version_added: '0.1.0' - + group_replication_user: + description: + - User for group replication. + type: str + version_added: '3.9.0' + group_replication_password: + description: + - Password for group replication user. + type: str + version_added: '3.9.0' notes: - Compatible with MariaDB or MySQL. - If an empty value for the parameter of string type is needed, use an empty string. @@ -292,6 +301,8 @@ - name: Start mysql group replication community.mysql.mysql_replication: mode: startgroupreplication + group_replication_user: repl_user + group_replication_password: repl_passwd - name: Stop mysql group replication community.mysql.mysql_replication: @@ -483,8 +494,8 @@ def changereplication(cursor, chm, channel=''): cursor.execute(query) -def startgroupreplication(module, cursor, fail_on_error=False, term='GROUP_REPLICATION'): - query = 'START %s' % term +def startgroupreplication(module, cursor, chm, fail_on_error=False, term='GROUP_REPLICATION'): + query = 'START %s %s' % (term, ','.join(chm)) try: executed_queries.append(query) @@ -592,6 +603,8 @@ def main(): connection_name = module.params["connection_name"] channel = module.params['channel'] fail_on_error = module.params['fail_on_error'] + group_replication_user = module.params['group_replication_user'] + group_replication_password = module.params['group_replication_password'] if mysql_driver is None: module.fail_json(msg=mysql_driver_fail_msg) @@ -786,7 +799,12 @@ def main(): result['changed'] = True module.exit_json(queries=executed_queries, **result) elif mode in "startgroupreplication": - started = startgroupreplication(module, cursor, fail_on_error) + chm = [] + if group_replication_user is not None: + chm.append(" USER='%s'" % group_replication_user) + if group_replication_password is not None: + chm.append(" PASSWORD='%s'" % group_replication_password) + started = startgroupreplication(module, cursor, chm, fail_on_error) if started is True: module.exit_json(msg="Group replication started ", changed=True, queries=executed_queries) else: diff --git a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml index e08954b6..745f8208 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml @@ -318,5 +318,5 @@ - name: Assert that stopslave returns expected error message assert: that: - - result.msg == "value of mode must be one of{{ ":" }} getprimary, getreplica, changeprimary, stopreplica, startreplica, resetprimary, resetreplica, resetreplicaall, changereplication, got{{ ":" }} stopslave" + - result.msg == "value of mode must be one of{{ ":" }} getprimary, getreplica, changeprimary, stopreplica, startreplica, resetprimary, resetreplica, resetreplicaall, changereplication, startgroupreplication, stopgroupreplication, got{{ ":" }} stopslave" - result is failed From 025fc68448000af6babbfddf0f3e33b3e80c531f Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Mon, 17 Jun 2024 07:56:55 +0200 Subject: [PATCH 3/7] add missing param definition --- plugins/modules/mysql_replication.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index a1bf38a2..1cc096cf 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -301,8 +301,8 @@ - name: Start mysql group replication community.mysql.mysql_replication: mode: startgroupreplication - group_replication_user: repl_user - group_replication_password: repl_passwd + group_replication_user: group_repl_user + group_replication_password: group_repl_passwd - name: Stop mysql group replication community.mysql.mysql_replication: @@ -564,6 +564,8 @@ def main(): connection_name=dict(type='str'), channel=dict(type='str'), fail_on_error=dict(type='bool', default=False), + group_replication_user=dict(type='str', default=None), + group_replication_password=dict(type='str', default=None), ) module = AnsibleModule( argument_spec=argument_spec, From 22eb418c77e09e587f346f4c25f3273ade5496ea Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Mon, 17 Jun 2024 08:07:54 +0200 Subject: [PATCH 4/7] correct parameter no_log for password --- plugins/modules/mysql_replication.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index 1cc096cf..8d59538d 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -564,8 +564,8 @@ def main(): connection_name=dict(type='str'), channel=dict(type='str'), fail_on_error=dict(type='bool', default=False), - group_replication_user=dict(type='str', default=None), - group_replication_password=dict(type='str', default=None), + group_replication_user=dict(type='str'), + group_replication_password=dict(type='str', no_log=True), ) module = AnsibleModule( argument_spec=argument_spec, From cfdc9e777274bb8a00e49d233dc8a3c47711c2f9 Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Tue, 18 Jun 2024 13:07:30 +0200 Subject: [PATCH 5/7] fix mode selector --- .../mysql_replication_add_group_replication_commands.yml | 2 +- plugins/module_utils/version.py | 1 - plugins/modules/mysql_replication.py | 4 ++-- tests/unit/plugins/module_utils/test_mariadb_replication.py | 2 +- .../plugins/module_utils/test_mariadb_user_implementation.py | 2 +- tests/unit/plugins/module_utils/test_mysql.py | 2 +- tests/unit/plugins/module_utils/test_mysql_replication.py | 2 +- .../plugins/module_utils/test_mysql_user_implementation.py | 2 +- 8 files changed, 8 insertions(+), 9 deletions(-) diff --git a/changelogs/fragments/mysql_replication_add_group_replication_commands.yml b/changelogs/fragments/mysql_replication_add_group_replication_commands.yml index 804de44b..95c5f4a5 100644 --- a/changelogs/fragments/mysql_replication_add_group_replication_commands.yml +++ b/changelogs/fragments/mysql_replication_add_group_replication_commands.yml @@ -1,2 +1,2 @@ minor_changes: - - mysql_replication - add ``startgroupreplication`` and ``stopgroupreplication`` options (https://github.com/ansible-collections/community.mysql/pull/93). \ No newline at end of file + - mysql_replication - add ``startgroupreplication`` and ``stopgroupreplication`` options (https://github.com/ansible-collections/community.mysql/pull/647). \ No newline at end of file diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py index 94731347..ef5d66ae 100644 --- a/plugins/module_utils/version.py +++ b/plugins/module_utils/version.py @@ -13,4 +13,3 @@ # # from ansible.module_utils.compat.version import LooseVersion -from ._version import LooseVersion diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index 8d59538d..6edb3e5e 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -800,7 +800,7 @@ def main(): module.fail_json(msg='%s. Query == CHANGE REPLICATION SOURCE TO %s' % (to_native(e), chm)) result['changed'] = True module.exit_json(queries=executed_queries, **result) - elif mode in "startgroupreplication": + elif mode == "startgroupreplication": chm = [] if group_replication_user is not None: chm.append(" USER='%s'" % group_replication_user) @@ -812,7 +812,7 @@ def main(): else: module.exit_json(msg="Group replication already started (Or cannot be started)", changed=False, ueries=executed_queries) - elif mode in "stopgroupreplication": + elif mode == "stopgroupreplication": stopped = stopgroupreplication(module, cursor, channel, fail_on_error) if stopped is True: module.exit_json(msg="Group replication stopped", changed=True, queries=executed_queries) diff --git a/tests/unit/plugins/module_utils/test_mariadb_replication.py b/tests/unit/plugins/module_utils/test_mariadb_replication.py index deb3099c..3195a6a4 100644 --- a/tests/unit/plugins/module_utils/test_mariadb_replication.py +++ b/tests/unit/plugins/module_utils/test_mariadb_replication.py @@ -7,7 +7,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb.replication import uses_replica_terminology -from ..utils import dummy_cursor_class +from tests import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py b/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py index a6fbff9a..0b624315 100644 --- a/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py +++ b/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py @@ -8,7 +8,7 @@ from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb.user import ( supports_identified_by_password, ) -from ..utils import dummy_cursor_class +from tests import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql.py b/tests/unit/plugins/module_utils/test_mysql.py index 5410575b..1346bb14 100644 --- a/tests/unit/plugins/module_utils/test_mysql.py +++ b/tests/unit/plugins/module_utils/test_mysql.py @@ -5,7 +5,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version, get_server_implementation -from ..utils import dummy_cursor_class +from tests import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql_replication.py b/tests/unit/plugins/module_utils/test_mysql_replication.py index 96d4d9ac..449948e4 100644 --- a/tests/unit/plugins/module_utils/test_mysql_replication.py +++ b/tests/unit/plugins/module_utils/test_mysql_replication.py @@ -7,7 +7,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql.replication import uses_replica_terminology -from ..utils import dummy_cursor_class +from tests import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql_user_implementation.py b/tests/unit/plugins/module_utils/test_mysql_user_implementation.py index c1fe2ee9..985f7e4d 100644 --- a/tests/unit/plugins/module_utils/test_mysql_user_implementation.py +++ b/tests/unit/plugins/module_utils/test_mysql_user_implementation.py @@ -8,7 +8,7 @@ from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql.user import ( supports_identified_by_password, ) -from ..utils import dummy_cursor_class +from tests import dummy_cursor_class @pytest.mark.parametrize( From 089fd93dfd9563e44fd10354d60c1e4060b18131 Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Tue, 18 Jun 2024 13:13:27 +0200 Subject: [PATCH 6/7] fix auto IDE changes --- plugins/module_utils/version.py | 1 + plugins/modules/mysql_replication.py | 12 ++++++------ .../plugins/module_utils/test_mariadb_replication.py | 2 +- .../module_utils/test_mariadb_user_implementation.py | 2 +- tests/unit/plugins/module_utils/test_mysql.py | 2 +- .../plugins/module_utils/test_mysql_replication.py | 2 +- .../module_utils/test_mysql_user_implementation.py | 2 +- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py index ef5d66ae..cb318223 100644 --- a/plugins/module_utils/version.py +++ b/plugins/module_utils/version.py @@ -13,3 +13,4 @@ # # from ansible.module_utils.compat.version import LooseVersion +from ._version import LooseVersion \ No newline at end of file diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index 6edb3e5e..57607f00 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -34,8 +34,8 @@ C(resetprimary) (RESET MASTER) - supported since community.mysql 0.1.0, C(resetreplica) (RESET REPLICA), C(resetreplicaall) (RESET REPLICA ALL), - C(startgroupreplication) (START GROUP_REPLICATION), - C(stopgroupreplication) (STOP GROUP_REPLICATION). + C(startgroupreplication) (START GROUP_REPLICATION) - supported since community.mysql 3.10.0, + C(stopgroupreplication) (STOP GROUP_REPLICATION) - supported since community.mysql 3.10.0. type: str choices: - changeprimary @@ -198,12 +198,12 @@ description: - User for group replication. type: str - version_added: '3.9.0' + version_added: '3.10.0' group_replication_password: description: - Password for group replication user. type: str - version_added: '3.9.0' + version_added: '3.10.0' notes: - Compatible with MariaDB or MySQL. - If an empty value for the parameter of string type is needed, use an empty string. @@ -807,14 +807,14 @@ def main(): if group_replication_password is not None: chm.append(" PASSWORD='%s'" % group_replication_password) started = startgroupreplication(module, cursor, chm, fail_on_error) - if started is True: + if started: module.exit_json(msg="Group replication started ", changed=True, queries=executed_queries) else: module.exit_json(msg="Group replication already started (Or cannot be started)", changed=False, ueries=executed_queries) elif mode == "stopgroupreplication": stopped = stopgroupreplication(module, cursor, channel, fail_on_error) - if stopped is True: + if stopped: module.exit_json(msg="Group replication stopped", changed=True, queries=executed_queries) else: module.exit_json(msg="Group replication already stopped", changed=False, queries=executed_queries) diff --git a/tests/unit/plugins/module_utils/test_mariadb_replication.py b/tests/unit/plugins/module_utils/test_mariadb_replication.py index 3195a6a4..deb3099c 100644 --- a/tests/unit/plugins/module_utils/test_mariadb_replication.py +++ b/tests/unit/plugins/module_utils/test_mariadb_replication.py @@ -7,7 +7,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb.replication import uses_replica_terminology -from tests import dummy_cursor_class +from ..utils import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py b/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py index 0b624315..a6fbff9a 100644 --- a/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py +++ b/tests/unit/plugins/module_utils/test_mariadb_user_implementation.py @@ -8,7 +8,7 @@ from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb.user import ( supports_identified_by_password, ) -from tests import dummy_cursor_class +from ..utils import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql.py b/tests/unit/plugins/module_utils/test_mysql.py index 1346bb14..5410575b 100644 --- a/tests/unit/plugins/module_utils/test_mysql.py +++ b/tests/unit/plugins/module_utils/test_mysql.py @@ -5,7 +5,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version, get_server_implementation -from tests import dummy_cursor_class +from ..utils import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql_replication.py b/tests/unit/plugins/module_utils/test_mysql_replication.py index 449948e4..96d4d9ac 100644 --- a/tests/unit/plugins/module_utils/test_mysql_replication.py +++ b/tests/unit/plugins/module_utils/test_mysql_replication.py @@ -7,7 +7,7 @@ import pytest from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql.replication import uses_replica_terminology -from tests import dummy_cursor_class +from ..utils import dummy_cursor_class @pytest.mark.parametrize( diff --git a/tests/unit/plugins/module_utils/test_mysql_user_implementation.py b/tests/unit/plugins/module_utils/test_mysql_user_implementation.py index 985f7e4d..c1fe2ee9 100644 --- a/tests/unit/plugins/module_utils/test_mysql_user_implementation.py +++ b/tests/unit/plugins/module_utils/test_mysql_user_implementation.py @@ -8,7 +8,7 @@ from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql.user import ( supports_identified_by_password, ) -from tests import dummy_cursor_class +from ..utils import dummy_cursor_class @pytest.mark.parametrize( From a55be60ae0d7fc1f4cd48689aa28ac66a4ad5a7e Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Tue, 18 Jun 2024 13:14:18 +0200 Subject: [PATCH 7/7] fix auto IDE changes --- plugins/module_utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py index cb318223..94731347 100644 --- a/plugins/module_utils/version.py +++ b/plugins/module_utils/version.py @@ -13,4 +13,4 @@ # # from ansible.module_utils.compat.version import LooseVersion -from ._version import LooseVersion \ No newline at end of file +from ._version import LooseVersion