mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-08-15 10:31:44 -07:00
Implemented a simple diff mode
This commit is contained in:
parent
1f9b1a29dd
commit
b895692181
2 changed files with 52 additions and 3 deletions
|
@ -30,6 +30,8 @@ from ansible_collections.community.mysql.plugins.module_utils.implementations.my
|
||||||
class InvalidPrivsError(Exception):
|
class InvalidPrivsError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
diff_current = {}
|
||||||
|
diff_new = {}
|
||||||
|
|
||||||
def get_mode(cursor):
|
def get_mode(cursor):
|
||||||
cursor.execute('SELECT @@sql_mode')
|
cursor.execute('SELECT @@sql_mode')
|
||||||
|
@ -49,6 +51,10 @@ def user_exists(cursor, user, host, host_all):
|
||||||
cursor.execute("SELECT count(*) FROM mysql.user WHERE user = %s AND host = %s", (user, host))
|
cursor.execute("SELECT count(*) FROM mysql.user WHERE user = %s AND host = %s", (user, host))
|
||||||
|
|
||||||
count = cursor.fetchone()
|
count = cursor.fetchone()
|
||||||
|
if count[0] > 0:
|
||||||
|
diff_current['state'] = "present"
|
||||||
|
else:
|
||||||
|
diff_current['state'] = "absent"
|
||||||
return count[0] > 0
|
return count[0] > 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,12 +68,15 @@ def user_is_locked(cursor, user, host):
|
||||||
# Need to handle both DictCursor and non-DictCursor
|
# Need to handle both DictCursor and non-DictCursor
|
||||||
if isinstance(result, tuple):
|
if isinstance(result, tuple):
|
||||||
if result[0].find('ACCOUNT LOCK') > 0:
|
if result[0].find('ACCOUNT LOCK') > 0:
|
||||||
|
diff_current['locked'] = True
|
||||||
return True
|
return True
|
||||||
elif isinstance(result, dict):
|
elif isinstance(result, dict):
|
||||||
for res in result.values():
|
for res in result.values():
|
||||||
if res.find('ACCOUNT LOCK') > 0:
|
if res.find('ACCOUNT LOCK') > 0:
|
||||||
|
diff_current['locked'] = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
diff_current['locked'] = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +120,7 @@ def get_grants(cursor, user, host):
|
||||||
grants_line = list(filter(lambda x: "ON *.*" in x[0], cursor.fetchall()))[0]
|
grants_line = list(filter(lambda x: "ON *.*" in x[0], cursor.fetchall()))[0]
|
||||||
pattern = r"(?<=\bGRANT\b)(.*?)(?=(?:\bON\b))"
|
pattern = r"(?<=\bGRANT\b)(.*?)(?=(?:\bON\b))"
|
||||||
grants = re.search(pattern, grants_line[0]).group().strip()
|
grants = re.search(pattern, grants_line[0]).group().strip()
|
||||||
|
diff_current['grants'] = grants.split(", ")
|
||||||
return grants.split(", ")
|
return grants.split(", ")
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,6 +182,7 @@ def get_existing_authentication(cursor, user, host=None):
|
||||||
'plugin': r[0],
|
'plugin': r[0],
|
||||||
'plugin_auth_string': r[1],
|
'plugin_auth_string': r[1],
|
||||||
'plugin_hash_string': r[1]})
|
'plugin_hash_string': r[1]})
|
||||||
|
diff_current['auth_list'] = existing_auth_list
|
||||||
|
|
||||||
return existing_auth_list
|
return existing_auth_list
|
||||||
|
|
||||||
|
@ -301,6 +312,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
hostnames = [host]
|
hostnames = [host]
|
||||||
|
|
||||||
password_changed = False
|
password_changed = False
|
||||||
|
diff_current['password'] = "<filtered password>"
|
||||||
|
diff_new['password'] = "<filtered password>"
|
||||||
for host in hostnames:
|
for host in hostnames:
|
||||||
# Handle clear text and hashed passwords.
|
# Handle clear text and hashed passwords.
|
||||||
if not role:
|
if not role:
|
||||||
|
@ -345,6 +358,7 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
encrypted_password = cursor.fetchone()[0]
|
encrypted_password = cursor.fetchone()[0]
|
||||||
|
|
||||||
if current_pass_hash != encrypted_password:
|
if current_pass_hash != encrypted_password:
|
||||||
|
diff_new['password'] = "<filtered new password>"
|
||||||
password_changed = True
|
password_changed = True
|
||||||
msg = "Password updated"
|
msg = "Password updated"
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
|
@ -378,6 +392,14 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
mariadb_role = True if "mariadb" in str(impl.__name__) else False
|
mariadb_role = True if "mariadb" in str(impl.__name__) else False
|
||||||
current_password_policy = get_password_expiration_policy(cursor, user, host, maria_role=mariadb_role)
|
current_password_policy = get_password_expiration_policy(cursor, user, host, maria_role=mariadb_role)
|
||||||
password_expired = is_password_expired(cursor, user, host)
|
password_expired = is_password_expired(cursor, user, host)
|
||||||
|
diff_current['password_policy'] = current_password_policy
|
||||||
|
if password_expired == "default":
|
||||||
|
diff_new['password_policy'] = -1
|
||||||
|
elif password_expired == "never":
|
||||||
|
diff_new['password_policy'] = 0
|
||||||
|
elif password_expired == "interval":
|
||||||
|
diff_new['password_policy'] = 1
|
||||||
|
|
||||||
# Check if changes needed to be applied.
|
# Check if changes needed to be applied.
|
||||||
if not ((current_password_policy == -1 and password_expire == "default") or
|
if not ((current_password_policy == -1 and password_expire == "default") or
|
||||||
(current_password_policy == 0 and password_expire == "never") or
|
(current_password_policy == 0 and password_expire == "never") or
|
||||||
|
@ -396,6 +418,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
cursor.execute("SELECT plugin, authentication_string FROM mysql.user "
|
cursor.execute("SELECT plugin, authentication_string FROM mysql.user "
|
||||||
"WHERE user = %s AND host = %s", (user, host))
|
"WHERE user = %s AND host = %s", (user, host))
|
||||||
current_plugin = cursor.fetchone()
|
current_plugin = cursor.fetchone()
|
||||||
|
diff_current['plugin'] = current_plugin
|
||||||
|
diff_new['plugin'] = plugin
|
||||||
|
|
||||||
update = False
|
update = False
|
||||||
|
|
||||||
|
@ -469,6 +493,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
privileges_grant(cursor, user, host, db_table, priv, tls_requires, maria_role)
|
privileges_grant(cursor, user, host, db_table, priv, tls_requires, maria_role)
|
||||||
changed = True
|
changed = True
|
||||||
|
diff_current['privileges'] = curr_priv
|
||||||
|
diff_new['privileges'] = new_priv
|
||||||
|
|
||||||
# If the db.table specification exists in both the user's current privileges
|
# If the db.table specification exists in both the user's current privileges
|
||||||
# and in the new privileges, then we need to see if there's a difference.
|
# and in the new privileges, then we need to see if there's a difference.
|
||||||
|
@ -527,6 +553,8 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
module.fail_json(msg="user attributes were specified but the server does not support user attributes")
|
module.fail_json(msg="user attributes were specified but the server does not support user attributes")
|
||||||
else:
|
else:
|
||||||
current_attributes = attributes_get(cursor, user, host)
|
current_attributes = attributes_get(cursor, user, host)
|
||||||
|
diff_current['attributes'] = current_attributes
|
||||||
|
diff_new['attributes'] = attributes
|
||||||
|
|
||||||
if current_attributes is None:
|
if current_attributes is None:
|
||||||
current_attributes = {}
|
current_attributes = {}
|
||||||
|
@ -558,6 +586,11 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
if attribute_support:
|
if attribute_support:
|
||||||
final_attributes = attributes_get(cursor, user, host)
|
final_attributes = attributes_get(cursor, user, host)
|
||||||
|
|
||||||
|
diff_current['locked'] = user_is_locked(cursor, user, host)
|
||||||
|
diff_new['locked'] = locked
|
||||||
|
if diff_new['locked'] is None:
|
||||||
|
diff_new['locked'] = False
|
||||||
|
|
||||||
if not role and locked is not None and user_is_locked(cursor, user, host) != locked:
|
if not role and locked is not None and user_is_locked(cursor, user, host) != locked:
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
if locked:
|
if locked:
|
||||||
|
@ -579,6 +612,10 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
|
|
||||||
# Handle TLS requirements
|
# Handle TLS requirements
|
||||||
current_requires = sanitize_requires(impl.get_tls_requires(cursor, user, host))
|
current_requires = sanitize_requires(impl.get_tls_requires(cursor, user, host))
|
||||||
|
|
||||||
|
diff_current['requires_tls'] = current_requires
|
||||||
|
diff_new['requires_tls'] = tls_requires
|
||||||
|
|
||||||
if current_requires != tls_requires:
|
if current_requires != tls_requires:
|
||||||
msg = "TLS requires updated"
|
msg = "TLS requires updated"
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
|
@ -597,10 +634,10 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
|
||||||
cursor.execute(*query_with_args)
|
cursor.execute(*query_with_args)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
return {'changed': changed, 'msg': msg, 'password_changed': password_changed, 'attributes': final_attributes}
|
return {'changed': changed, 'msg': msg, 'password_changed': password_changed, 'attributes': final_attributes, 'diff_current': diff_current, 'diff_new': diff_new}
|
||||||
|
|
||||||
|
|
||||||
def user_delete(cursor, user, host, host_all, check_mode):
|
def user_delete(cursor, user, host, host_all, check_mode):
|
||||||
|
diff_new['state'] = "absent"
|
||||||
if check_mode:
|
if check_mode:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -626,6 +663,8 @@ def user_get_hostnames(cursor, user):
|
||||||
for hostname_raw in hostnames_raw:
|
for hostname_raw in hostnames_raw:
|
||||||
hostnames.append(hostname_raw[0])
|
hostnames.append(hostname_raw[0])
|
||||||
|
|
||||||
|
diff_current['hostnames'] = hostnames
|
||||||
|
|
||||||
return hostnames
|
return hostnames
|
||||||
|
|
||||||
|
|
||||||
|
@ -1022,6 +1061,8 @@ def match_resource_limits(module, current, desired):
|
||||||
Returns: Dictionary containing parameters that need to change.
|
Returns: Dictionary containing parameters that need to change.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
diff_current['resource_limits'] = current
|
||||||
|
diff_new['resource_limits'] = desired
|
||||||
if not current:
|
if not current:
|
||||||
# It means the user does not exists, so we need
|
# It means the user does not exists, so we need
|
||||||
# to set all limits after its creation
|
# to set all limits after its creation
|
||||||
|
|
|
@ -455,6 +455,10 @@ from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
diff_current = {}
|
||||||
|
diff_current['state'] = "present"
|
||||||
|
diff_new = {}
|
||||||
|
diff_new['state'] = "present"
|
||||||
argument_spec = mysql_common_argument_spec()
|
argument_spec = mysql_common_argument_spec()
|
||||||
argument_spec.update(
|
argument_spec.update(
|
||||||
name=dict(type='str', required=True, aliases=['user'], deprecated_aliases=[
|
name=dict(type='str', required=True, aliases=['user'], deprecated_aliases=[
|
||||||
|
@ -609,6 +613,8 @@ def main():
|
||||||
msg = result['msg']
|
msg = result['msg']
|
||||||
password_changed = result['password_changed']
|
password_changed = result['password_changed']
|
||||||
final_attributes = result['attributes']
|
final_attributes = result['attributes']
|
||||||
|
diff_current = result['diff_current'] | diff_current
|
||||||
|
diff_new = result['diff_new'] | diff_new
|
||||||
|
|
||||||
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
||||||
module.fail_json(msg=to_native(e))
|
module.fail_json(msg=to_native(e))
|
||||||
|
@ -628,6 +634,7 @@ def main():
|
||||||
final_attributes = result['attributes']
|
final_attributes = result['attributes']
|
||||||
if changed:
|
if changed:
|
||||||
msg = "User added"
|
msg = "User added"
|
||||||
|
diff_new['state'] = "present"
|
||||||
|
|
||||||
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
||||||
module.fail_json(msg=to_native(e))
|
module.fail_json(msg=to_native(e))
|
||||||
|
@ -639,10 +646,11 @@ def main():
|
||||||
if user_exists(cursor, user, host, host_all):
|
if user_exists(cursor, user, host, host_all):
|
||||||
changed = user_delete(cursor, user, host, host_all, module.check_mode)
|
changed = user_delete(cursor, user, host, host_all, module.check_mode)
|
||||||
msg = "User deleted"
|
msg = "User deleted"
|
||||||
|
diff_new['state'] = "absent"
|
||||||
else:
|
else:
|
||||||
changed = False
|
changed = False
|
||||||
msg = "User doesn't exist"
|
msg = "User doesn't exist"
|
||||||
module.exit_json(changed=changed, user=user, msg=msg, password_changed=password_changed, attributes=final_attributes)
|
module.exit_json(changed=changed, diff={'before': diff_current, 'after': diff_new}, user=user, msg=msg, password_changed=password_changed, attributes=final_attributes)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue