mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-04-05 10:10:32 -07:00
Merge branch 'main' into password_expiration_mysql_user
This commit is contained in:
commit
273fd2cdcc
21 changed files with 693 additions and 103 deletions
|
@ -1,6 +1,3 @@
|
|||
betanummeric
|
||||
bmalynovytch
|
||||
Jorge-Rodriguez
|
||||
rsicart
|
||||
laurent-indermuehle
|
||||
Andersson007 (andersson007_ in #ansible-community IRC/Matrix)
|
||||
Andersson007
|
||||
|
|
|
@ -87,7 +87,7 @@ We maintain each major release (1.x.y, 2.x.y, ...) for two years after the next
|
|||
Here is the table for the support timeline:
|
||||
|
||||
- 1.x.y: released 2020-08-17, EOL
|
||||
- 2.x.y: released 2021-04-15, supported until 2023-12-01
|
||||
- 2.x.y: released 2021-04-15, EOL
|
||||
- 3.x.y: released 2021-12-01, current
|
||||
- 4.x.y: To be released
|
||||
|
||||
|
|
2
changelogs/fragments/0-stable-2-eol.yml
Normal file
2
changelogs/fragments/0-stable-2-eol.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
major_changes:
|
||||
- "Collection version 2.*.* is EOL, no more bugfixes will be backported. Please consider upgrading to the latest version."
|
2
changelogs/fragments/602-show-all-slaves-status.yaml
Normal file
2
changelogs/fragments/602-show-all-slaves-status.yaml
Normal file
|
@ -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).
|
2
changelogs/fragments/604-user-attributes.yaml
Normal file
2
changelogs/fragments/604-user-attributes.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "mysql_user - add user attribute support via the ``attributes`` parameter and return value (https://github.com/ansible-collections/community.mysql/pull/604)."
|
|
@ -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():
|
||||
|
|
|
@ -10,6 +10,7 @@ __metaclass__ = type
|
|||
# Simplified BSD License (see simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
|
||||
import string
|
||||
import json
|
||||
import re
|
||||
|
||||
from ansible.module_utils.six import iteritems
|
||||
|
@ -151,14 +152,14 @@ def get_existing_authentication(cursor, user, host):
|
|||
|
||||
def user_add(cursor, user, host, host_all, password, encrypted,
|
||||
plugin, plugin_hash_string, plugin_auth_string, new_priv,
|
||||
tls_requires, module, reuse_existing_password,
|
||||
attributes, tls_requires, module, reuse_existing_password,
|
||||
password_expire, password_expire_interval):
|
||||
# we cannot create users without a proper hostname
|
||||
if host_all:
|
||||
return {'changed': False, 'password_changed': False}
|
||||
return {'changed': False, 'password_changed': False, 'attributes': attributes}
|
||||
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'password_changed': None}
|
||||
return {'changed': True, 'password_changed': None, 'attributes': attributes}
|
||||
|
||||
# Determine what user management method server uses
|
||||
old_user_mgmt = impl.use_old_user_mgmt(cursor)
|
||||
|
@ -212,7 +213,14 @@ def user_add(cursor, user, host, host_all, password, encrypted,
|
|||
privileges_grant(cursor, user, host, db_table, priv, tls_requires)
|
||||
if tls_requires is not None:
|
||||
privileges_grant(cursor, user, host, "*.*", get_grants(cursor, user, host), tls_requires)
|
||||
return {'changed': True, 'password_changed': not used_existing_password}
|
||||
|
||||
final_attributes = None
|
||||
|
||||
if attributes:
|
||||
cursor.execute("ALTER USER %s@%s ATTRIBUTE %s", (user, host, json.dumps(attributes)))
|
||||
final_attributes = attributes_get(cursor, user, host)
|
||||
|
||||
return {'changed': True, 'password_changed': not used_existing_password, 'attributes': final_attributes}
|
||||
|
||||
|
||||
def is_hash(password):
|
||||
|
@ -225,7 +233,7 @@ def is_hash(password):
|
|||
|
||||
def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||
plugin, plugin_hash_string, plugin_auth_string, new_priv,
|
||||
append_privs, subtract_privs, tls_requires, module,
|
||||
append_privs, subtract_privs, attributes, tls_requires, module,
|
||||
password_expire, password_expire_interval, role=False, maria_role=False):
|
||||
changed = False
|
||||
msg = "User unchanged"
|
||||
|
@ -286,27 +294,26 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
|||
if current_pass_hash != encrypted_password:
|
||||
password_changed = True
|
||||
msg = "Password updated"
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'msg': msg, 'password_changed': password_changed}
|
||||
if old_user_mgmt:
|
||||
cursor.execute("SET PASSWORD FOR %s@%s = %s", (user, host, encrypted_password))
|
||||
msg = "Password updated (old style)"
|
||||
else:
|
||||
try:
|
||||
cursor.execute("ALTER USER %s@%s IDENTIFIED WITH mysql_native_password AS %s", (user, host, encrypted_password))
|
||||
msg = "Password updated (new style)"
|
||||
except (mysql_driver.Error) as e:
|
||||
# https://stackoverflow.com/questions/51600000/authentication-string-of-root-user-on-mysql
|
||||
# Replacing empty root password with new authentication mechanisms fails with error 1396
|
||||
if e.args[0] == 1396:
|
||||
cursor.execute(
|
||||
"UPDATE mysql.user SET plugin = %s, authentication_string = %s, Password = '' WHERE User = %s AND Host = %s",
|
||||
('mysql_native_password', encrypted_password, user, host)
|
||||
)
|
||||
cursor.execute("FLUSH PRIVILEGES")
|
||||
msg = "Password forced update"
|
||||
else:
|
||||
raise e
|
||||
if not module.check_mode:
|
||||
if old_user_mgmt:
|
||||
cursor.execute("SET PASSWORD FOR %s@%s = %s", (user, host, encrypted_password))
|
||||
msg = "Password updated (old style)"
|
||||
else:
|
||||
try:
|
||||
cursor.execute("ALTER USER %s@%s IDENTIFIED WITH mysql_native_password AS %s", (user, host, encrypted_password))
|
||||
msg = "Password updated (new style)"
|
||||
except (mysql_driver.Error) as e:
|
||||
# https://stackoverflow.com/questions/51600000/authentication-string-of-root-user-on-mysql
|
||||
# Replacing empty root password with new authentication mechanisms fails with error 1396
|
||||
if e.args[0] == 1396:
|
||||
cursor.execute(
|
||||
"UPDATE mysql.user SET plugin = %s, authentication_string = %s, Password = '' WHERE User = %s AND Host = %s",
|
||||
('mysql_native_password', encrypted_password, user, host)
|
||||
)
|
||||
cursor.execute("FLUSH PRIVILEGES")
|
||||
msg = "Password forced update"
|
||||
else:
|
||||
raise e
|
||||
changed = True
|
||||
|
||||
# Handle password expiration
|
||||
|
@ -383,9 +390,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
|||
if db_table not in new_priv:
|
||||
if user != "root" and "PROXY" not in priv:
|
||||
msg = "Privileges updated"
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'msg': msg, 'password_changed': password_changed}
|
||||
privileges_revoke(cursor, user, host, db_table, priv, grant_option, maria_role)
|
||||
if not module.check_mode:
|
||||
privileges_revoke(cursor, user, host, db_table, priv, grant_option, maria_role)
|
||||
changed = True
|
||||
|
||||
# If the user doesn't currently have any privileges on a db.table, then
|
||||
|
@ -394,9 +400,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
|||
for db_table, priv in iteritems(new_priv):
|
||||
if db_table not in curr_priv:
|
||||
msg = "New privileges granted"
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'msg': msg, 'password_changed': password_changed}
|
||||
privileges_grant(cursor, user, host, db_table, priv, tls_requires, maria_role)
|
||||
if not module.check_mode:
|
||||
privileges_grant(cursor, user, host, db_table, priv, tls_requires, maria_role)
|
||||
changed = True
|
||||
|
||||
# If the db.table specification exists in both the user's current privileges
|
||||
|
@ -435,17 +440,58 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
|||
|
||||
if len(grant_privs) + len(revoke_privs) > 0:
|
||||
msg = "Privileges updated: granted %s, revoked %s" % (grant_privs, revoke_privs)
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'msg': msg, 'password_changed': password_changed}
|
||||
if len(revoke_privs) > 0:
|
||||
privileges_revoke(cursor, user, host, db_table, revoke_privs, grant_option, maria_role)
|
||||
if len(grant_privs) > 0:
|
||||
privileges_grant(cursor, user, host, db_table, grant_privs, tls_requires, maria_role)
|
||||
if not module.check_mode:
|
||||
if len(revoke_privs) > 0:
|
||||
privileges_revoke(cursor, user, host, db_table, revoke_privs, grant_option, maria_role)
|
||||
if len(grant_privs) > 0:
|
||||
privileges_grant(cursor, user, host, db_table, grant_privs, tls_requires, maria_role)
|
||||
else:
|
||||
changed = True
|
||||
|
||||
# after privilege manipulation, compare privileges from before and now
|
||||
after_priv = privileges_get(cursor, user, host, maria_role)
|
||||
changed = changed or (curr_priv != after_priv)
|
||||
|
||||
# Handle attributes
|
||||
attribute_support = get_attribute_support(cursor)
|
||||
final_attributes = {}
|
||||
|
||||
if attributes:
|
||||
if not attribute_support:
|
||||
module.fail_json(msg="user attributes were specified but the server does not support user attributes")
|
||||
else:
|
||||
current_attributes = attributes_get(cursor, user, host)
|
||||
|
||||
if current_attributes is None:
|
||||
current_attributes = {}
|
||||
|
||||
attributes_to_change = {}
|
||||
|
||||
for key, value in attributes.items():
|
||||
if key not in current_attributes or current_attributes[key] != value:
|
||||
attributes_to_change[key] = value
|
||||
|
||||
if attributes_to_change:
|
||||
msg = "Attributes updated: %s" % (", ".join(["%s: %s" % (key, value) for key, value in attributes_to_change.items()]))
|
||||
|
||||
# Calculate final attributes by re-running attributes_get when not in check mode, and merge dictionaries when in check mode
|
||||
if not module.check_mode:
|
||||
cursor.execute("ALTER USER %s@%s ATTRIBUTE %s", (user, host, json.dumps(attributes_to_change)))
|
||||
final_attributes = attributes_get(cursor, user, host)
|
||||
else:
|
||||
# Final if statements excludes items whose values are None in attributes_to_change, i.e. attributes that will be deleted
|
||||
final_attributes = {k: v for d in (current_attributes, attributes_to_change) for k, v in d.items() if k not in attributes_to_change or
|
||||
attributes_to_change[k] is not None}
|
||||
|
||||
# Convert empty dict to None per return value requirements
|
||||
final_attributes = final_attributes if final_attributes else None
|
||||
changed = True
|
||||
else:
|
||||
final_attributes = current_attributes
|
||||
else:
|
||||
if attribute_support:
|
||||
final_attributes = attributes_get(cursor, user, host)
|
||||
|
||||
if role:
|
||||
continue
|
||||
|
||||
|
@ -453,24 +499,23 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
|||
current_requires = get_tls_requires(cursor, user, host)
|
||||
if current_requires != tls_requires:
|
||||
msg = "TLS requires updated"
|
||||
if module.check_mode:
|
||||
return {'changed': True, 'msg': msg, 'password_changed': password_changed}
|
||||
if not old_user_mgmt:
|
||||
pre_query = "ALTER USER"
|
||||
else:
|
||||
pre_query = "GRANT %s ON *.* TO" % ",".join(get_grants(cursor, user, host))
|
||||
if not module.check_mode:
|
||||
if not old_user_mgmt:
|
||||
pre_query = "ALTER USER"
|
||||
else:
|
||||
pre_query = "GRANT %s ON *.* TO" % ",".join(get_grants(cursor, user, host))
|
||||
|
||||
if tls_requires is not None:
|
||||
query = " ".join((pre_query, "%s@%s"))
|
||||
query_with_args = mogrify_requires(query, (user, host), tls_requires)
|
||||
else:
|
||||
query = " ".join((pre_query, "%s@%s REQUIRE NONE"))
|
||||
query_with_args = query, (user, host)
|
||||
if tls_requires is not None:
|
||||
query = " ".join((pre_query, "%s@%s"))
|
||||
query_with_args = mogrify_requires(query, (user, host), tls_requires)
|
||||
else:
|
||||
query = " ".join((pre_query, "%s@%s REQUIRE NONE"))
|
||||
query_with_args = query, (user, host)
|
||||
|
||||
cursor.execute(*query_with_args)
|
||||
cursor.execute(*query_with_args)
|
||||
changed = True
|
||||
|
||||
return {'changed': changed, 'msg': msg, 'password_changed': password_changed}
|
||||
return {'changed': changed, 'msg': msg, 'password_changed': password_changed, 'attributes': final_attributes}
|
||||
|
||||
|
||||
def user_delete(cursor, user, host, host_all, check_mode):
|
||||
|
@ -1020,6 +1065,41 @@ def is_password_expired(cursor, user, host):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_attribute_support(cursor):
|
||||
"""Checks if the MySQL server supports user attributes.
|
||||
|
||||
Args:
|
||||
cursor (cursor): DB driver cursor object.
|
||||
Returns:
|
||||
True if attributes are supported, False if they are not.
|
||||
"""
|
||||
try:
|
||||
# information_schema.tables does not hold the tables within information_schema itself
|
||||
cursor.execute("SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES LIMIT 0")
|
||||
cursor.fetchone()
|
||||
except mysql_driver.Error:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def attributes_get(cursor, user, host):
|
||||
"""Get attributes for a given user.
|
||||
|
||||
host (str): User host name.
|
||||
|
||||
Returns:
|
||||
None if the user does not exist or the user has no attributes set, otherwise a dict of attributes set on the user
|
||||
"""
|
||||
cursor.execute("SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = %s AND host = %s", (user, host))
|
||||
|
||||
r = cursor.fetchone()
|
||||
# convert JSON string stored in row into a dict - mysql enforces that user_attributes entires are in JSON format
|
||||
j = json.loads(r[0]) if r and r[0] else None
|
||||
|
||||
# if the attributes dict is empty, return None instead
|
||||
return j if j else None
|
||||
|
||||
|
||||
def get_impl(cursor):
|
||||
global impl
|
||||
|
|
|
@ -577,14 +577,14 @@ def db_create(cursor, db, encoding, collation):
|
|||
def main():
|
||||
argument_spec = mysql_common_argument_spec()
|
||||
argument_spec.update(
|
||||
name=dict(type='list', required=True, aliases=['db']),
|
||||
name=dict(type='list', elements='str', required=True, aliases=['db']),
|
||||
encoding=dict(type='str', default=''),
|
||||
collation=dict(type='str', default=''),
|
||||
target=dict(type='path'),
|
||||
state=dict(type='str', default='present', choices=['absent', 'dump', 'import', 'present']),
|
||||
single_transaction=dict(type='bool', default=False),
|
||||
quick=dict(type='bool', default=True),
|
||||
ignore_tables=dict(type='list', default=[]),
|
||||
ignore_tables=dict(type='list', elements='str', default=[]),
|
||||
hex_blob=dict(default=False, type='bool'),
|
||||
force=dict(type='bool', default=False),
|
||||
master_data=dict(type='int', default=0, choices=[0, 1, 2]),
|
||||
|
|
|
@ -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'''
|
||||
|
@ -292,6 +293,7 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
|||
mysql_driver_fail_msg,
|
||||
get_connector_name,
|
||||
get_connector_version,
|
||||
get_server_implementation,
|
||||
)
|
||||
|
||||
from ansible_collections.community.mysql.plugins.module_utils.user import (
|
||||
|
@ -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': {},
|
||||
|
@ -497,7 +500,10 @@ class MySQL_Info(object):
|
|||
|
||||
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']
|
||||
|
@ -692,8 +698,8 @@ def main():
|
|||
argument_spec = mysql_common_argument_spec()
|
||||
argument_spec.update(
|
||||
login_db=dict(type='str'),
|
||||
filter=dict(type='list'),
|
||||
exclude_fields=dict(type='list'),
|
||||
filter=dict(type='list', elements='str'),
|
||||
exclude_fields=dict(type='list', elements='str'),
|
||||
return_empty_dbs=dict(type='bool', default=False),
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
|
|
|
@ -36,6 +36,7 @@ options:
|
|||
- List of values to be passed as positional arguments to the query.
|
||||
- Mutually exclusive with I(named_args).
|
||||
type: list
|
||||
elements: raw
|
||||
named_args:
|
||||
description:
|
||||
- Dictionary of key-value arguments to pass to the query.
|
||||
|
@ -141,7 +142,7 @@ def main():
|
|||
argument_spec.update(
|
||||
query=dict(type='raw', required=True),
|
||||
login_db=dict(type='str'),
|
||||
positional_args=dict(type='list'),
|
||||
positional_args=dict(type='list', elements='raw'),
|
||||
named_args=dict(type='dict'),
|
||||
single_transaction=dict(type='bool', default=False),
|
||||
)
|
||||
|
|
|
@ -931,7 +931,7 @@ class Role():
|
|||
if privs:
|
||||
result = user_mod(self.cursor, self.name, self.host,
|
||||
None, None, None, None, None, None,
|
||||
privs, append_privs, subtract_privs, None,
|
||||
privs, append_privs, subtract_privs, None, None,
|
||||
self.module, None, None, role=True,
|
||||
maria_role=self.is_mariadb)
|
||||
changed = result['changed']
|
||||
|
|
|
@ -179,6 +179,13 @@ options:
|
|||
fields names in privileges.
|
||||
type: bool
|
||||
version_added: '3.8.0'
|
||||
attributes:
|
||||
description:
|
||||
- "Create, update, or delete user attributes (arbitrary 'key: value' comments) for the user."
|
||||
- MySQL server must support the INFORMATION_SCHEMA.USER_ATTRIBUTES table. Provided since MySQL 8.0.
|
||||
- To delete an existing attribute, set its value to null.
|
||||
type: dict
|
||||
version_added: '3.9.0'
|
||||
|
||||
notes:
|
||||
- "MySQL server installs with default I(login_user) of C(root) and no password.
|
||||
|
@ -271,6 +278,13 @@ EXAMPLES = r'''
|
|||
FUNCTION my_db.my_function: EXECUTE
|
||||
state: present
|
||||
|
||||
- name: Modify user attributes, creating the attribute 'foo' and removing the attribute 'bar'
|
||||
community.mysql.mysql_user:
|
||||
name: bob
|
||||
attributes:
|
||||
foo: "foo"
|
||||
bar: null
|
||||
|
||||
- name: Modify user to require TLS connection with a valid client certificate
|
||||
community.mysql.mysql_user:
|
||||
name: bob
|
||||
|
@ -419,6 +433,7 @@ def main():
|
|||
tls_requires=dict(type='dict'),
|
||||
append_privs=dict(type='bool', default=False),
|
||||
subtract_privs=dict(type='bool', default=False),
|
||||
attributes=dict(type='dict'),
|
||||
check_implicit_admin=dict(type='bool', default=False),
|
||||
update_password=dict(type='str', default='always', choices=['always', 'on_create', 'on_new_username'], no_log=False),
|
||||
sql_log_bin=dict(type='bool', default=True),
|
||||
|
@ -453,6 +468,7 @@ def main():
|
|||
append_privs = module.boolean(module.params["append_privs"])
|
||||
subtract_privs = module.boolean(module.params['subtract_privs'])
|
||||
update_password = module.params['update_password']
|
||||
attributes = module.params['attributes']
|
||||
ssl_cert = module.params["client_cert"]
|
||||
ssl_key = module.params["client_key"]
|
||||
ssl_ca = module.params["ca_cert"]
|
||||
|
@ -522,23 +538,25 @@ def main():
|
|||
|
||||
priv = privileges_unpack(priv, mode, column_case_sensitive, ensure_usage=not subtract_privs)
|
||||
password_changed = False
|
||||
final_attributes = None
|
||||
if state == "present":
|
||||
if user_exists(cursor, user, host, host_all):
|
||||
try:
|
||||
if update_password == "always":
|
||||
result = user_mod(cursor, user, host, host_all, password, encrypted,
|
||||
plugin, plugin_hash_string, plugin_auth_string,
|
||||
priv, append_privs, subtract_privs, tls_requires, module,
|
||||
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
||||
password_expire, password_expire_interval)
|
||||
|
||||
else:
|
||||
result = user_mod(cursor, user, host, host_all, None, encrypted,
|
||||
None, None, None,
|
||||
priv, append_privs, subtract_privs, tls_requires, module,
|
||||
priv, append_privs, subtract_privs, attributes, tls_requires, module,
|
||||
password_expire, password_expire_interval)
|
||||
changed = result['changed']
|
||||
msg = result['msg']
|
||||
password_changed = result['password_changed']
|
||||
final_attributes = result['attributes']
|
||||
|
||||
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
||||
module.fail_json(msg=to_native(e))
|
||||
|
@ -551,10 +569,11 @@ def main():
|
|||
reuse_existing_password = update_password == 'on_new_username'
|
||||
result = user_add(cursor, user, host, host_all, password, encrypted,
|
||||
plugin, plugin_hash_string, plugin_auth_string,
|
||||
priv, tls_requires, module, reuse_existing_password,
|
||||
priv, attributes, tls_requires, module, reuse_existing_password,
|
||||
password_expire, password_expire_interval)
|
||||
changed = result['changed']
|
||||
password_changed = result['password_changed']
|
||||
final_attributes = result['attributes']
|
||||
if changed:
|
||||
msg = "User added"
|
||||
|
||||
|
@ -571,7 +590,7 @@ def main():
|
|||
else:
|
||||
changed = False
|
||||
msg = "User doesn't exist"
|
||||
module.exit_json(changed=changed, user=user, msg=msg, password_changed=password_changed)
|
||||
module.exit_json(changed=changed, user=user, msg=msg, password_changed=password_changed, attributes=final_attributes)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -176,7 +176,7 @@ def setvariable(cursor, mysqlvar, value, mode='global'):
|
|||
def main():
|
||||
argument_spec = mysql_common_argument_spec()
|
||||
argument_spec.update(
|
||||
variable=dict(type='str'),
|
||||
variable=dict(type='str', required=True),
|
||||
value=dict(type='str'),
|
||||
mode=dict(type='str', choices=['global', 'persist', 'persist_only'], default='global'),
|
||||
)
|
||||
|
|
|
@ -269,6 +269,9 @@
|
|||
tags:
|
||||
- issue_465
|
||||
|
||||
# Tests for user attributes
|
||||
- include_tasks: test_user_attributes.yml
|
||||
|
||||
# Tests for the TLS requires dictionary
|
||||
- include_tasks: test_tls_requirements.yml
|
||||
|
||||
|
|
|
@ -0,0 +1,474 @@
|
|||
---
|
||||
- vars:
|
||||
mysql_parameters: &mysql_params
|
||||
login_user: '{{ mysql_user }}'
|
||||
login_password: '{{ mysql_password }}'
|
||||
login_host: '{{ mysql_host }}'
|
||||
login_port: '{{ mysql_primary_port }}'
|
||||
|
||||
block:
|
||||
|
||||
- when: db_engine == 'mariadb'
|
||||
block:
|
||||
|
||||
# ============================================================
|
||||
# Fail creating a user with mariadb
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Attempt to create user with attributes with mariadb in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
ignore_errors: yes
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify user creation with attributes fails with mariadb in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT user FROM mysql.user WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
ignore_errors: yes
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that creating user with attributes fails with mariadb in check mode
|
||||
assert:
|
||||
that:
|
||||
- result_module is failed
|
||||
- not result_query.query_result[0]
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Attempt to create user with attributes with mariadb
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
ignore_errors: yes
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify user creation with attributes fails with mariadb
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT user FROM mysql.user WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that creating user with attributes fails with mariadb
|
||||
assert:
|
||||
that:
|
||||
- result_module is failed
|
||||
- not result_query.query_result[0]
|
||||
|
||||
- when: db_engine == 'mysql'
|
||||
block:
|
||||
|
||||
# ============================================================
|
||||
# Create user with no attributes (test attributes return type)
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test creating a user with no attributes in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify user creation with no attributes did not take place in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT user FROM mysql.user WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that user would have been created without attributes
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes is none
|
||||
- not result_query.query_result[0]
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test creating a user with no attributes
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify created user without attributes
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that user was created without attributes
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes is none
|
||||
- result_query.query_result[0][0]['ATTRIBUTE'] is none
|
||||
|
||||
# Clean up user to allow it to be recreated with attributes
|
||||
- include_tasks: utils/remove_user.yml
|
||||
vars:
|
||||
user_name: "{{ user_name_2 }}"
|
||||
|
||||
# ============================================================
|
||||
# Create user with attributes
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test creating a user with attributes in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify user creation did not take place in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT user FROM mysql.user WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that user would have been created with attributes
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- not result_query.query_result[0]
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test creating a user with attributes
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
password: '{{ user_password_2 }}'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify created user attributes
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that user was created with attributes
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
|
||||
# ============================================================
|
||||
# Append attributes on an existing user
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test appending attributes to an existing user in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: "value2"
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to check appended attributes in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute would have been appended and existing attribute stays
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- result_module.attributes.key2 == "value2"
|
||||
- "'key2' not in result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml"
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test appending attributes to an existing user
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: "value2"
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to check appended attributes
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that new attribute was appended and existing attribute stays
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- result_module.attributes.key2 == "value2"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key2'] == "value2"
|
||||
|
||||
# ============================================================
|
||||
# Test updating existing attributes
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test updating attributes on an existing user in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: "new_value2"
|
||||
check_mode: yes
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify updated attribute in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute would have been updated
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key2 == "new_value2"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key2'] == "value2"
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test updating attributes on an existing user
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: "new_value2"
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify updated attribute
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute was updated
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes.key2 == "new_value2"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key2'] == "new_value2"
|
||||
|
||||
# ============================================================
|
||||
# Test attribute idempotency when specifying attributes
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test attribute idempotency by trying to change an already correct attribute in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify idempotency of already correct attribute in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute would not have been updated
|
||||
assert:
|
||||
that:
|
||||
- result_module is not changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test attribute idempotency by trying to change an already correct attribute
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key1: "value1"
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify idempotency of already correct attribute
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute was not updated
|
||||
assert:
|
||||
that:
|
||||
- result_module is not changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
|
||||
# ============================================================
|
||||
# Test attribute idempotency when not specifying attribute parameter
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test attribute idempotency by not specifying attribute parameter in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify idempotency when not specifying attribute parameter in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute is returned in check mode
|
||||
assert:
|
||||
that:
|
||||
- result_module is not changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test attribute idempotency by not specifying attribute parameter
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify idempotency when not specifying attribute parameter
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute is returned
|
||||
assert:
|
||||
that:
|
||||
- result_module is not changed
|
||||
- result_module.attributes.key1 == "value1"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key1'] == "value1"
|
||||
|
||||
# ============================================================
|
||||
# Test deleting attributes
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test deleting attributes on an existing user in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: null
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Run query to verify deleted attribute in check mode
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute would have been deleted
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- "'key2' not in result_module.attributes"
|
||||
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key2'] == "new_value2"
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test deleting attributes on an existing user
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key2: null
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Run query to verify deleted attribute
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
query: 'SELECT attribute FROM INFORMATION_SCHEMA.USER_ATTRIBUTES WHERE user = "{{ user_name_2 }}" AND host = "%"'
|
||||
register: result_query
|
||||
|
||||
- name: Attributes | Assert that attribute was deleted
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- "'key2' not in result_module.attributes"
|
||||
- "'key2' not in result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml"
|
||||
|
||||
# ============================================================
|
||||
# Test attribute return value when no attributes exist
|
||||
#
|
||||
|
||||
# Check mode
|
||||
- name: Attributes | Test attributes return value when no attributes exist in check mode
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key1: null
|
||||
register: result_module
|
||||
check_mode: yes
|
||||
|
||||
- name: Attributes | Assert attributes return value when no attributes exist in check mode
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes is none
|
||||
|
||||
# Real mode
|
||||
- name: Attributes | Test attributes return value when no attributes exist
|
||||
mysql_user:
|
||||
<<: *mysql_params
|
||||
name: '{{ user_name_2 }}'
|
||||
host: '%'
|
||||
attributes:
|
||||
key1: null
|
||||
register: result_module
|
||||
|
||||
- name: Attributes | Assert attributes return value when no attributes exist
|
||||
assert:
|
||||
that:
|
||||
- result_module is changed
|
||||
- result_module.attributes is none
|
||||
|
||||
# ============================================================
|
||||
# Cleanup
|
||||
#
|
||||
- include_tasks: utils/remove_user.yml
|
||||
vars:
|
||||
user_name: "{{ user_name_2 }}"
|
|
@ -1,8 +1,2 @@
|
|||
plugins/modules/mysql_db.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_db.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_db.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/mysql_info.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_info.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_query.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_user.py validate-modules:undocumented-parameter
|
||||
plugins/modules/mysql_variables.py validate-modules:doc-required-mismatch
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
plugins/modules/mysql_db.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_db.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_db.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/mysql_info.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_info.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_query.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_user.py validate-modules:undocumented-parameter
|
||||
plugins/modules/mysql_variables.py validate-modules:doc-required-mismatch
|
||||
plugins/module_utils/mysql.py pylint:unused-import
|
||||
plugins/module_utils/version.py pylint:unused-import
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
plugins/modules/mysql_db.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_db.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_db.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/mysql_info.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_info.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_query.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_user.py validate-modules:undocumented-parameter
|
||||
plugins/modules/mysql_variables.py validate-modules:doc-required-mismatch
|
||||
plugins/module_utils/mysql.py pylint:unused-import
|
||||
plugins/module_utils/version.py pylint:unused-import
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
plugins/modules/mysql_db.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_db.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_db.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/mysql_info.py validate-modules:doc-elements-mismatch
|
||||
plugins/modules/mysql_info.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_query.py validate-modules:parameter-list-no-elements
|
||||
plugins/modules/mysql_user.py validate-modules:undocumented-parameter
|
||||
plugins/modules/mysql_variables.py validate-modules:doc-required-mismatch
|
||||
plugins/module_utils/mysql.py pylint:unused-import
|
||||
plugins/module_utils/version.py pylint:unused-import
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
@ -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,15 +14,15 @@ from ansible_collections.community.mysql.plugins.modules.mysql_info import MySQL
|
|||
|
||||
|
||||
@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}]
|
||||
|
@ -32,6 +32,6 @@ def test_get_info_suffix(suffix, cursor_output):
|
|||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue