feat[mysql_user]: add support for mysql user attributes (#604)

* add support for mysql user attributes

* fix CI

* write integration tests

* requested changes pt. 1

* requested changes pt. 2

* fix changelog fragment

---------

Co-authored-by: n-cc <ncc@github.com>
This commit is contained in:
ncc 2024-01-19 08:37:28 -06:00 committed by GitHub
parent 81ab18d56c
commit 051aa48d8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 644 additions and 59 deletions

View file

@ -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, role=True, maria_role=self.is_mariadb)
changed = result['changed']

View file

@ -155,7 +155,6 @@ options:
- Cannot be used to set global variables, use the M(community.mysql.mysql_variables) module instead.
type: dict
version_added: '3.6.0'
column_case_sensitive:
description:
- The default is C(false).
@ -165,6 +164,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.
@ -257,6 +263,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
@ -405,6 +418,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),
@ -437,6 +451,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"]
@ -500,21 +515,23 @@ 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)
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)
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))
@ -527,9 +544,10 @@ 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.check_mode, reuse_existing_password)
priv, attributes, tls_requires, reuse_existing_password, module)
changed = result['changed']
password_changed = result['password_changed']
final_attributes = result['attributes']
if changed:
msg = "User added"
@ -546,7 +564,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__':