From 35122ce3f1228a84ac4eab3089f65d2a00db4afc Mon Sep 17 00:00:00 2001 From: Sebastian Pfahl Date: Fri, 14 Jun 2024 20:20:10 +0200 Subject: [PATCH] Add options to start and stop group replication --- ...ication_add_group_replication_commands.yml | 2 + plugins/modules/mysql_replication.py | 87 ++++++++++++++++++- .../tasks/mysql_replication_initial.yml | 2 +- 3 files changed, 87 insertions(+), 4 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 0000000..95c5f4a --- /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/647). \ No newline at end of file diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index a743b82..ec1d1f0 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -20,6 +20,7 @@ author: - Balazs Pocze (@banyek) - Andrew Klychkov (@Andersson007) - Dennis Urtubia (@dennisurtubia) +- Sebastian Pfahl (@eryx12o45) - Laurent Indermühle (@laurent-indermuehle) options: mode: @@ -33,7 +34,9 @@ options: 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) - supported since community.mysql 3.10.0, + C(stopgroupreplication) (STOP GROUP_REPLICATION) - supported since community.mysql 3.10.0. type: str choices: - changeprimary @@ -45,6 +48,8 @@ options: - resetprimary - resetreplica - resetreplicaall + - startgroupreplication + - stopgroupreplication default: getreplica primary_host: description: @@ -191,7 +196,16 @@ options: type: bool default: false version_added: '0.1.0' - + group_replication_user: + description: + - User for group replication. + type: str + version_added: '3.10.0' + group_replication_password: + description: + - Password for group replication user. + type: str + 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. @@ -285,6 +299,17 @@ EXAMPLES = r''' community.mysql.mysql_replication: mode: changeprimary fail_on_error: true + +- name: Start mysql group replication + community.mysql.mysql_replication: + mode: startgroupreplication + group_replication_user: group_repl_user + group_replication_password: group_repl_passwd + +- name: Stop mysql group replication + community.mysql.mysql_replication: + mode: stopgroupreplication + ''' RETURN = r''' @@ -465,6 +490,38 @@ def changereplication(cursor, chm, channel=''): cursor.execute(query) +def startgroupreplication(module, cursor, chm, fail_on_error=False, term='GROUP_REPLICATION'): + query = 'START %s %s' % (term, ','.join(chm)) + + 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( @@ -477,7 +534,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']), @@ -501,6 +560,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'), + group_replication_password=dict(type='str', no_log=True), ) module = AnsibleModule( argument_spec=argument_spec, @@ -540,6 +601,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) @@ -742,6 +805,24 @@ 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 == "startgroupreplication": + 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: + 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: + 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") 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 182ea5c..1f31f83 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 @@ -338,5 +338,5 @@ 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