Skip to content

Commit

Permalink
mysql_info - Add connector_name and connector_version to returned val…
Browse files Browse the repository at this point in the history
…ue (ansible-collections#497)

* Add methods to retrieve connector name and version
* Document that mysqlclient is also named MySQLdb
* Document version_added
* Add connector name and version in the returned block
* Cut condition to display any name that is return

In case of MySQLdb is renamed in mysqlclient. In that case, the
integration tests will catch this the day we update the connector
version.

Co-authored-by: Andrew Klychkov <[email protected]>
  • Loading branch information
laurent-indermuehle and Andersson007 authored Jan 30, 2023
1 parent 3229ce4 commit a5f3296
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- mysql_info - add ``connector_name`` and ``connector_version`` to returned values (https://github.com/ansible-collections/community.mysql/pull/497).
38 changes: 38 additions & 0 deletions plugins/module_utils/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
_mysql_cursor_param = 'cursor'
except ImportError:
try:
# mysqlclient is called MySQLdb
import MySQLdb as mysql_driver
import MySQLdb.cursors
_mysql_cursor_param = 'cursorclass'
Expand All @@ -37,6 +38,43 @@
from ansible_collections.community.mysql.plugins.module_utils.database import mysql_quote_identifier


def get_connector_name(connector):
""" (class) -> str
Return the name of the connector (pymysql or mysqlclient (MySQLdb))
or 'Unknown' if not pymysql or MySQLdb. When adding a
connector here, also modify get_connector_version.
"""
if connector is None or not hasattr(connector, '__name__'):
return 'Unknown'

return connector.__name__


def get_connector_version(connector):
""" (class) -> str
Return the version of pymysql or mysqlclient (MySQLdb).
Return 'Unknown' if the connector name is unknown.
"""

if connector is None:
return 'Unknown'

connector_name = get_connector_name(connector)

if connector_name == 'pymysql':
# pymysql has two methods:
# - __version__ that returns the string: 0.7.11.None
# - VERSION that returns the tuple (0, 7, 11, None)
v = connector.VERSION[:3]
return '.'.join(map(str, v))
elif connector_name == 'MySQLdb':
# version_info returns the tuple (2, 1, 1, 'final', 0)
v = connector.version_info[:3]
return '.'.join(map(str, v))
else:
return 'Unknown'


def parse_from_mysql_config_file(cnf):
# Default values of comment_prefix is '#' and ';'.
# '!' added to prevent a parsing error
Expand Down
32 changes: 29 additions & 3 deletions plugins/modules/mysql_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
author:
- Andrew Klychkov (@Andersson007)
- Sebastian Gumprich (@rndmh3ro)
- Laurent Indermühle (@laurent-indermuehle)
extends_documentation_fragment:
- community.mysql.mysql
Expand Down Expand Up @@ -206,6 +207,21 @@
type: dict
sample:
- { "2": { "Host": "", "Master_id": 1, "Port": 3306 } }
connector_name:
description: Name of the python connector used by the module. When the connector is not identified, returns C(Unknown).
returned: always
type: str
sample:
- "pymysql"
- "MySQLdb"
version_added: '3.6.0'
connector_version:
description: Version of the python connector used by the module. When the connector is not identified, returns C(Unknown).
returned: always
type: str
sample:
- "1.0.2"
version_added: '3.6.0'
'''

from decimal import Decimal
Expand All @@ -216,6 +232,8 @@
mysql_common_argument_spec,
mysql_driver,
mysql_driver_fail_msg,
get_connector_name,
get_connector_version,
)
from ansible.module_utils.six import iteritems
from ansible.module_utils._text import to_native
Expand Down Expand Up @@ -558,21 +576,29 @@ def main():
if mysql_driver is None:
module.fail_json(msg=mysql_driver_fail_msg)

connector_name = get_connector_name(mysql_driver)
connector_version = get_connector_version(mysql_driver)

try:
cursor, db_conn = mysql_connect(module, login_user, login_password,
config_file, ssl_cert, ssl_key, ssl_ca, db,
check_hostname=check_hostname,
connect_timeout=connect_timeout, cursor_class='DictCursor')
except Exception as e:
module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
"Exception message: %s" % (config_file, to_native(e)))
msg = ('unable to connect to database using %s %s, check login_user '
'and login_password are correct or %s has the credentials. '
'Exception message: %s' % (connector_name, connector_version, config_file, to_native(e)))
module.fail_json(msg)

###############################
# Create object and do main job

mysql = MySQL_Info(module, cursor)

module.exit_json(changed=False, **mysql.get_info(filter_, exclude_fields, return_empty_dbs))
module.exit_json(changed=False,
connector_name=connector_name,
connector_version=connector_version,
**mysql.get_info(filter_, exclude_fields, return_empty_dbs))


if __name__ == '__main__':
Expand Down
32 changes: 32 additions & 0 deletions tests/integration/targets/test_mysql_info/tasks/connector_info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
# Added in 3.6.0 in
# https://github.com/ansible-collections/community.mysql/pull/497

# TODO: Refactor in PR490.
- name: Connector info | Assert connector_name exists and has expected values
ansible.builtin.assert:
that:
- result.connector_name is defined
- result.connector_name is in ['pymysql', 'MySQLdb']
success_msg: >-
Assertions passed, result.connector_name is {{ result.connector_name }}
fail_msg: >-
Assertion failed, result.connector_name is
{{ result.connector_name | d('Unknown')}} which is different than expected
pymysql or MySQLdb
# TODO: Refactor in PR490.
- name: Connector info | Assert connector_version exists and has expected values
ansible.builtin.assert:
that:
- result.connector_version is defined
- >
result.connector_version == 'Unknown'
or result.connector_version is version(connector_ver, '==')
success_msg: >-
Assertions passed, result.connector_version is
{{ result.connector_version }}
fail_msg: >-
Assertion failed, result.connector_version is
{{ result.connector_version }} which is different than expected
{{ connector_ver }}
4 changes: 4 additions & 0 deletions tests/integration/targets/test_mysql_info/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
- result.engines != {}
- result.users != {}

- name: mysql_info - Test connector informations display
ansible.builtin.import_tasks:
file: connector_info.yml

# Access by non-default cred file
- name: mysql_info - check non-default cred file
mysql_info:
Expand Down

0 comments on commit a5f3296

Please sign in to comment.