requested changes pt. 2

This commit is contained in:
n-cc 2024-01-17 10:07:06 -06:00 committed by n-cc
parent c35bfb983b
commit 55e896e252
3 changed files with 156 additions and 64 deletions
plugins
module_utils
modules
tests/integration/targets/test_mysql_user/tasks

View file

@ -211,7 +211,7 @@ def user_add(cursor, user, host, host_all, password, encrypted,
if tls_requires is not None:
privileges_grant(cursor, user, host, "*.*", get_grants(cursor, user, host), tls_requires)
final_attributes = {}
final_attributes = None
if attributes:
cursor.execute("ALTER USER %s@%s ATTRIBUTE %s", (user, host, json.dumps(attributes)))
@ -434,6 +434,10 @@ 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")
else:
current_attributes = attributes_get(cursor, user, host)
if current_attributes is None:
current_attributes = {}
attributes_to_change = {}
for key, value in attributes.items():
@ -451,6 +455,9 @@ def user_mod(cursor, user, host, host_all, password, encrypted,
# 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
@ -974,7 +981,6 @@ def get_attribute_support(cursor):
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")
@ -994,21 +1000,16 @@ def attributes_get(cursor, user, host):
host (str): User host name.
Returns:
None if the user does not exist, otherwise a dict of attributes set on the user
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 r:
attributes = r[0]
# convert JSON string stored in row into a dict - mysql enforces that user_attributes entires are in JSON format
if attributes:
return json.loads(attributes)
else:
return {}
return None
# if the attributes dict is empty, return None instead
return j if j else None
def get_impl(cursor):

View file

@ -515,7 +515,7 @@ def main():
priv = privileges_unpack(priv, mode, column_case_sensitive, ensure_usage=not subtract_privs)
password_changed = False
final_attributes = {}
final_attributes = None
if state == "present":
if user_exists(cursor, user, host, host_all):
try:

View file

@ -68,6 +68,60 @@
- 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
#
@ -226,57 +280,6 @@
- result_module.attributes.key2 == "new_value2"
- (result_query.query_result[0][0]['ATTRIBUTE'] | from_yaml)['key2'] == "new_value2"
# ============================================================
# 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 idempotency when specifying attributes
#
@ -375,6 +378,94 @@
- 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
#