From bc08cf12ea18a1e651fd7f6b1707b62e272d252c Mon Sep 17 00:00:00 2001 From: Daniel Speichert Date: Wed, 19 Sep 2018 17:44:05 +0200 Subject: [PATCH] [stable-2.7] Migrate from MySQLdb to PyMySQL (#40123) * Migrate from MySQLdb to PyMySQL * Deduplicate driver loading and failure message * Explain requirements * Apply requirements docs change to proxysql too * Add changelog. (cherry picked from commit d34cf93f1a7f96a14da1354b8f88a90c058e3e86) Co-authored-by: Daniel Speichert --- .../fragments/mysql-migrate_to_pymysql.yaml | 2 ++ lib/ansible/module_utils/mysql.py | 14 +++++++---- .../modules/database/mysql/mysql_db.py | 17 +++++-------- .../database/mysql/mysql_replication.py | 19 +++++---------- .../modules/database/mysql/mysql_user.py | 17 ++++--------- .../modules/database/mysql/mysql_variables.py | 15 ++++-------- .../proxysql/proxysql_backend_servers.py | 24 ++++++------------- .../proxysql/proxysql_global_variables.py | 24 ++++++------------- .../proxysql/proxysql_manage_config.py | 19 ++++----------- .../database/proxysql/proxysql_mysql_users.py | 24 ++++++------------- .../database/proxysql/proxysql_query_rules.py | 24 ++++++------------- .../proxysql_replication_hostgroups.py | 24 ++++++------------- .../database/proxysql/proxysql_scheduler.py | 24 ++++++------------- .../utils/module_docs_fragments/mysql.py | 12 ++++++---- .../utils/module_docs_fragments/proxysql.py | 3 ++- .../setup_mysql_db/vars/Fedora-py3.yml | 2 +- .../targets/setup_mysql_db/vars/Fedora.yml | 2 +- .../targets/setup_mysql_db/vars/FreeBSD.yml | 2 +- .../targets/setup_mysql_db/vars/Suse.yml | 2 +- .../setup_mysql_db/vars/Ubuntu-16-py3.yml | 2 +- 20 files changed, 93 insertions(+), 179 deletions(-) create mode 100644 changelogs/fragments/mysql-migrate_to_pymysql.yaml diff --git a/changelogs/fragments/mysql-migrate_to_pymysql.yaml b/changelogs/fragments/mysql-migrate_to_pymysql.yaml new file mode 100644 index 00000000000..8eac8b5e096 --- /dev/null +++ b/changelogs/fragments/mysql-migrate_to_pymysql.yaml @@ -0,0 +1,2 @@ +bugfixes: +- mysql_*, proxysql_* - PyMySQL (a pure-Python MySQL driver) is now a preferred dependency also supporting Python 3.X. diff --git a/lib/ansible/module_utils/mysql.py b/lib/ansible/module_utils/mysql.py index 4255392af98..53c3cb1e4ad 100644 --- a/lib/ansible/module_utils/mysql.py +++ b/lib/ansible/module_utils/mysql.py @@ -30,10 +30,14 @@ import os try: - import MySQLdb - mysqldb_found = True + import pymysql as mysql_driver except ImportError: - mysqldb_found = False + try: + import MySQLdb as mysql_driver + except ImportError: + mysql_driver = None + +mysql_driver_fail_msg = 'The PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) module is required.' def mysql_connect(module, login_user=None, login_password=None, config_file='', ssl_cert=None, ssl_key=None, ssl_ca=None, db=None, cursor_class=None, @@ -69,8 +73,8 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='', if connect_timeout is not None: config['connect_timeout'] = connect_timeout - db_connection = MySQLdb.connect(**config) + db_connection = mysql_driver.connect(**config) if cursor_class is not None: - return db_connection.cursor(cursorclass=MySQLdb.cursors.DictCursor) + return db_connection.cursor(cursorclass=mysql_driver.cursors.DictCursor) else: return db_connection.cursor() diff --git a/lib/ansible/modules/database/mysql/mysql_db.py b/lib/ansible/modules/database/mysql/mysql_db.py index 7d8e91c647b..caf8c9f8f19 100644 --- a/lib/ansible/modules/database/mysql/mysql_db.py +++ b/lib/ansible/modules/database/mysql/mysql_db.py @@ -67,7 +67,9 @@ requirements: - mysql (command line binary) - mysqldump (command line binary) notes: - - Requires the python-mysqldb package on the remote host, as well as mysql and mysqldump binaries. + - Requires the PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) package on the remote host, + as well as mysql and mysqldump binaries. + - This module is B(not idempotent) when I(state) is C(import), and will import the dump file each time if run more than once. extends_documentation_fragment: mysql ''' @@ -106,16 +108,9 @@ import pipes import subprocess import traceback -try: - import MySQLdb -except ImportError: - mysqldb_found = False -else: - mysqldb_found = True - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.database import mysql_quote_identifier -from ansible.module_utils.mysql import mysql_connect, mysqldb_found +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native @@ -278,8 +273,8 @@ def main(): supports_check_mode=True ) - if not mysqldb_found: - module.fail_json(msg="The MySQL-python module is required.") + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) db = module.params["name"] encoding = module.params["encoding"] diff --git a/lib/ansible/modules/database/mysql/mysql_replication.py b/lib/ansible/modules/database/mysql/mysql_replication.py index 669757d6c85..4f08f11fcda 100644 --- a/lib/ansible/modules/database/mysql/mysql_replication.py +++ b/lib/ansible/modules/database/mysql/mysql_replication.py @@ -118,15 +118,8 @@ EXAMPLES = ''' import os import warnings -try: - import MySQLdb -except ImportError: - mysqldb_found = False -else: - mysqldb_found = True - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native @@ -239,16 +232,16 @@ def main(): connect_timeout = module.params['connect_timeout'] config_file = module.params['config_file'] - if not mysqldb_found: - module.fail_json(msg="The MySQL-python module is required.") + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) else: - warnings.filterwarnings('error', category=MySQLdb.Warning) + warnings.filterwarnings('error', category=mysql_driver.Warning) login_password = module.params["login_password"] login_user = module.params["login_user"] try: - cursor = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, None, 'MySQLdb.cursors.DictCursor', + cursor = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, None, 'mysql_driver.cursors.DictCursor', connect_timeout=connect_timeout) except Exception as e: if os.path.exists(config_file): @@ -325,7 +318,7 @@ def main(): chm.append("MASTER_AUTO_POSITION = 1") try: changemaster(cursor, chm, chm_params) - except MySQLdb.Warning as e: + except mysql_driver.Warning as e: result['warning'] = to_native(e) except Exception as e: module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' % (to_native(e), chm)) diff --git a/lib/ansible/modules/database/mysql/mysql_user.py b/lib/ansible/modules/database/mysql/mysql_user.py index 55a387143ac..a796bb95960 100644 --- a/lib/ansible/modules/database/mysql/mysql_user.py +++ b/lib/ansible/modules/database/mysql/mysql_user.py @@ -196,16 +196,9 @@ import re import string import traceback -try: - import MySQLdb -except ImportError: - mysqldb_found = False -else: - mysqldb_found = True - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.database import SQLParseError -from ansible.module_utils.mysql import mysql_connect, mysqldb_found +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native @@ -578,8 +571,8 @@ def main(): db = 'mysql' sql_log_bin = module.params["sql_log_bin"] - if not mysqldb_found: - module.fail_json(msg="The MySQL-python module is required.") + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) cursor = None try: @@ -618,14 +611,14 @@ def main(): else: changed = user_mod(cursor, user, host, host_all, None, encrypted, priv, append_privs, module) - except (SQLParseError, InvalidPrivsError, MySQLdb.Error) as e: + except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e: module.fail_json(msg=to_native(e), exception=traceback.format_exc()) else: if host_all: module.fail_json(msg="host_all parameter cannot be used when adding a user") try: changed = user_add(cursor, user, host, host_all, password, encrypted, priv, module.check_mode) - except (SQLParseError, InvalidPrivsError, MySQLdb.Error) as e: + except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e: module.fail_json(msg=to_native(e), exception=traceback.format_exc()) elif state == "absent": if user_exists(cursor, user, host, host_all): diff --git a/lib/ansible/modules/database/mysql/mysql_variables.py b/lib/ansible/modules/database/mysql/mysql_variables.py index 8bd066a9d17..fd50c1caa3c 100644 --- a/lib/ansible/modules/database/mysql/mysql_variables.py +++ b/lib/ansible/modules/database/mysql/mysql_variables.py @@ -50,16 +50,9 @@ import os import warnings from re import match -try: - import MySQLdb -except ImportError: - mysqldb_found = False -else: - mysqldb_found = True - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.database import SQLParseError, mysql_quote_identifier -from ansible.module_utils.mysql import mysql_connect, mysqldb_found +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native @@ -148,10 +141,10 @@ def main(): module.fail_json(msg="Cannot run without variable to operate with") if match('^[0-9a-z_]+$', mysqlvar) is None: module.fail_json(msg="invalid variable name \"%s\"" % mysqlvar) - if not mysqldb_found: - module.fail_json(msg="The MySQL-python module is required.") + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) else: - warnings.filterwarnings('error', category=MySQLdb.Warning) + warnings.filterwarnings('error', category=mysql_driver.Warning) try: cursor = mysql_connect(module, user, password, config_file, ssl_cert, ssl_key, ssl_ca, db, diff --git a/lib/ansible/modules/database/proxysql/proxysql_backend_servers.py b/lib/ansible/modules/database/proxysql/proxysql_backend_servers.py index 46bd13042e1..1e9903bf890 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_backend_servers.py +++ b/lib/ansible/modules/database/proxysql/proxysql_backend_servers.py @@ -148,18 +148,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -192,10 +184,8 @@ def perform_checks(module): msg="max_replication_lag must be set between 0 and 102400" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(cursor): @@ -457,8 +447,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -487,7 +477,7 @@ def main(): " and doesn't need to be updated.") result['server'] = \ proxysql_server.get_server_config(cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to modify server.. %s" % to_native(e) ) @@ -502,7 +492,7 @@ def main(): result['changed'] = False result['msg'] = ("The server is already absent from the" + " mysql_hosts memory configuration") - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to remove server.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_global_variables.py b/lib/ansible/modules/database/proxysql/proxysql_global_variables.py index 59451954c2c..ab0e9a431e4 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_global_variables.py +++ b/lib/ansible/modules/database/proxysql/proxysql_global_variables.py @@ -73,17 +73,9 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -96,10 +88,8 @@ def perform_checks(module): msg="login_port must be a valid unix port number (0-65535)" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(variable, cursor): @@ -211,8 +201,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -231,7 +221,7 @@ def main(): msg="The variable \"%s\" was not found" % variable ) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to get config.. %s" % to_native(e) ) @@ -264,7 +254,7 @@ def main(): msg="The variable \"%s\" was not found" % variable ) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to set config.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_manage_config.py b/lib/ansible/modules/database/proxysql/proxysql_manage_config.py index 7edf868055b..45d80f6e9b5 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_manage_config.py +++ b/lib/ansible/modules/database/proxysql/proxysql_manage_config.py @@ -96,16 +96,9 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native -try: - import MySQLdb -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -140,10 +133,8 @@ def perform_checks(module): " with the CONFIG config_layer") module.fail_json(msg=msg_string % module.params["direction"]) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def manage_config(manage_config_settings, cursor): @@ -201,7 +192,7 @@ def main(): login_user, login_password, config_file) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -214,7 +205,7 @@ def main(): try: result['changed'] = manage_config(manage_config_settings, cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to manage config.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_mysql_users.py b/lib/ansible/modules/database/proxysql/proxysql_mysql_users.py index 6aba7bb0a71..02f1ea0f6b1 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_mysql_users.py +++ b/lib/ansible/modules/database/proxysql/proxysql_mysql_users.py @@ -137,18 +137,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -161,10 +153,8 @@ def perform_checks(module): msg="login_port must be a valid unix port number (0-65535)" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(cursor): @@ -424,8 +414,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -454,7 +444,7 @@ def main(): " and doesn't need to be updated.") result['user'] = \ proxysql_user.get_user_config(cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to modify user.. %s" % to_native(e) ) @@ -469,7 +459,7 @@ def main(): result['changed'] = False result['msg'] = ("The user is already absent from the" + " mysql_users memory configuration") - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to remove user.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_query_rules.py b/lib/ansible/modules/database/proxysql/proxysql_query_rules.py index 01eb84cb465..9d356e2a271 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_query_rules.py +++ b/lib/ansible/modules/database/proxysql/proxysql_query_rules.py @@ -221,18 +221,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -245,10 +237,8 @@ def perform_checks(module): msg="login_port must be a valid unix port number (0-65535)" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(cursor): @@ -552,8 +542,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -583,7 +573,7 @@ def main(): result['rules'] = \ proxysql_query_rule.get_rule_config(cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to modify rule.. %s" % to_native(e) ) @@ -606,7 +596,7 @@ def main(): result['changed'] = False result['msg'] = ("The rule is already absent from the" + " mysql_query_rules memory configuration") - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to remove rule.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_replication_hostgroups.py b/lib/ansible/modules/database/proxysql/proxysql_replication_hostgroups.py index d02fbf0c3db..22ef86cfaa4 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_replication_hostgroups.py +++ b/lib/ansible/modules/database/proxysql/proxysql_replication_hostgroups.py @@ -95,17 +95,9 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -135,10 +127,8 @@ def perform_checks(module): msg="reader_hostgroup cannot equal writer_hostgroup" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(cursor): @@ -328,8 +318,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -360,7 +350,7 @@ def main(): result['repl_group'] = \ proxysql_repl_group.get_repl_group_config(cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to modify replication hostgroup.. %s" % to_native(e) ) @@ -378,7 +368,7 @@ def main(): " mysql_replication_hostgroups memory" + " configuration") - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to delete replication hostgroup.. %s" % to_native(e) ) diff --git a/lib/ansible/modules/database/proxysql/proxysql_scheduler.py b/lib/ansible/modules/database/proxysql/proxysql_scheduler.py index ba59a911383..29195b8ea78 100644 --- a/lib/ansible/modules/database/proxysql/proxysql_scheduler.py +++ b/lib/ansible/modules/database/proxysql/proxysql_scheduler.py @@ -125,18 +125,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.mysql import mysql_connect +from ansible.module_utils.mysql import mysql_connect, mysql_driver, mysql_driver_fail_msg from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_native -try: - import MySQLdb - import MySQLdb.cursors -except ImportError: - MYSQLDB_FOUND = False -else: - MYSQLDB_FOUND = True - # =========================================== # proxysql module specific support methods. # @@ -155,10 +147,8 @@ def perform_checks(module): msg="interval_ms must between 100ms & 100000000ms" ) - if not MYSQLDB_FOUND: - module.fail_json( - msg="the python mysqldb module is required" - ) + if mysql_driver is None: + module.fail_json(msg=mysql_driver_fail_msg) def save_config_to_disk(cursor): @@ -366,8 +356,8 @@ def main(): login_user, login_password, config_file, - cursor_class=MySQLdb.cursors.DictCursor) - except MySQLdb.Error as e: + cursor_class=mysql_driver.cursors.DictCursor) + except mysql_driver.Error as e: module.fail_json( msg="unable to connect to ProxySQL Admin Module.. %s" % to_native(e) ) @@ -390,7 +380,7 @@ def main(): " need to be updated.") result['schedules'] = \ proxysql_schedule.get_schedule_config(cursor) - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to modify schedule.. %s" % to_native(e) ) @@ -413,7 +403,7 @@ def main(): result['changed'] = False result['msg'] = ("The schedule is already absent from the" + " memory configuration") - except MySQLdb.Error as e: + except mysql_driver.Error as e: module.fail_json( msg="unable to remove schedule.. %s" % to_native(e) ) diff --git a/lib/ansible/utils/module_docs_fragments/mysql.py b/lib/ansible/utils/module_docs_fragments/mysql.py index 91454bd6a62..26e879b6d1c 100644 --- a/lib/ansible/utils/module_docs_fragments/mysql.py +++ b/lib/ansible/utils/module_docs_fragments/mysql.py @@ -52,7 +52,8 @@ options: ssl_ca: version_added: "2.0" description: - - The path to a Certificate Authority (CA) certificate. This option, if used, must specify the same certificate as used by the server. + - The path to a Certificate Authority (CA) certificate. This option, if used, must specify the same certificate + as used by the server. ssl_cert: version_added: "2.0" description: @@ -62,11 +63,12 @@ options: description: - The path to the client private key. requirements: - - MySQLdb + - PyMySQL (Python 2.7 and Python 3.X), or + - MySQLdb (Python 2.x) notes: - - Requires the MySQLdb Python package on the remote host. For Ubuntu, this - is as easy as apt-get install python-mysqldb. (See M(apt).) For CentOS/Fedora, this - is as easy as yum install MySQL-python. (See M(yum).) + - Requires the PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) Python package on the remote host. + For Ubuntu, this is as easy as apt-get install python-pymysql. (See M(apt).) For CentOS/Fedora, this + is as easy as yum install python2-PyMySQL. (See M(yum).) - Both C(login_password) and C(login_user) are required when you are passing credentials. If none are present, the module will attempt to read the credentials from C(~/.my.cnf), and finally fall back to using the MySQL diff --git a/lib/ansible/utils/module_docs_fragments/proxysql.py b/lib/ansible/utils/module_docs_fragments/proxysql.py index e2f9df6aef1..ad65911cf91 100644 --- a/lib/ansible/utils/module_docs_fragments/proxysql.py +++ b/lib/ansible/utils/module_docs_fragments/proxysql.py @@ -27,7 +27,8 @@ options: are to be read. default: '' requirements: - - MySQLdb + - PyMySQL (Python 2.7 and Python 3.X), or + - MySQLdb (Python 2.x) ''' # Documentation fragment for managing ProxySQL configuration diff --git a/test/integration/targets/setup_mysql_db/vars/Fedora-py3.yml b/test/integration/targets/setup_mysql_db/vars/Fedora-py3.yml index 5a66227a7e8..fa7d06e52a9 100644 --- a/test/integration/targets/setup_mysql_db/vars/Fedora-py3.yml +++ b/test/integration/targets/setup_mysql_db/vars/Fedora-py3.yml @@ -2,5 +2,5 @@ mysql_service: 'mariadb' mysql_packages: - mariadb-server - - python3-mysql + - python3-PyMySQL - bzip2 diff --git a/test/integration/targets/setup_mysql_db/vars/Fedora.yml b/test/integration/targets/setup_mysql_db/vars/Fedora.yml index f8b29fd7a16..718326ae084 100644 --- a/test/integration/targets/setup_mysql_db/vars/Fedora.yml +++ b/test/integration/targets/setup_mysql_db/vars/Fedora.yml @@ -2,5 +2,5 @@ mysql_service: 'mariadb' mysql_packages: - mariadb-server - - MySQL-python + - python-PyMySQL - bzip2 diff --git a/test/integration/targets/setup_mysql_db/vars/FreeBSD.yml b/test/integration/targets/setup_mysql_db/vars/FreeBSD.yml index 1ed5472d89b..af45ebfd40d 100644 --- a/test/integration/targets/setup_mysql_db/vars/FreeBSD.yml +++ b/test/integration/targets/setup_mysql_db/vars/FreeBSD.yml @@ -2,4 +2,4 @@ mysql_service: 'mysql-server' mysql_packages: - mariadb101-server - - py27-mysql-connector-python2 + - py-pymysql diff --git a/test/integration/targets/setup_mysql_db/vars/Suse.yml b/test/integration/targets/setup_mysql_db/vars/Suse.yml index feeeccd053d..a48a2e13302 100644 --- a/test/integration/targets/setup_mysql_db/vars/Suse.yml +++ b/test/integration/targets/setup_mysql_db/vars/Suse.yml @@ -2,5 +2,5 @@ mysql_service: 'mysql' mysql_packages: - mariadb - - python-MySQL-python + - python-PyMySQL - bzip2 diff --git a/test/integration/targets/setup_mysql_db/vars/Ubuntu-16-py3.yml b/test/integration/targets/setup_mysql_db/vars/Ubuntu-16-py3.yml index bffbf588956..a3096ae2de2 100644 --- a/test/integration/targets/setup_mysql_db/vars/Ubuntu-16-py3.yml +++ b/test/integration/targets/setup_mysql_db/vars/Ubuntu-16-py3.yml @@ -2,5 +2,5 @@ mysql_service: 'mysql' mysql_packages: - mysql-server - - python3-mysqldb + - python3-pymysql - bzip2