summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Klychkov <aaklychkov@mail.ru>2020-01-31 18:32:31 +0300
committerGitHub <noreply@github.com>2020-01-31 16:32:31 +0100
commit54520c468553155f95757bd9cec0bb34f4d84418 (patch)
treea6002024e4fbfe1825ec44085363dec3fc58a20e
parent813091cf94f5bf943dd052204734c12e9e73a9d4 (diff)
downloadansible-54520c468553155f95757bd9cec0bb34f4d84418.tar.gz
mysql_user: priv parameter can also be a dictionary (#66801)
* mysql_user: add priv_dict parameter * add changelog * priv can be string or dictionary * fix example
-rw-r--r--changelogs/fragments/66801-mysql_user_priv_can_be_dict.yml2
-rw-r--r--lib/ansible/modules/database/mysql/mysql_user.py33
-rw-r--r--test/integration/targets/mysql_user/defaults/main.yml2
-rw-r--r--test/integration/targets/mysql_user/tasks/main.yml3
-rw-r--r--test/integration/targets/mysql_user/tasks/test_priv_dict.yml46
5 files changed, 84 insertions, 2 deletions
diff --git a/changelogs/fragments/66801-mysql_user_priv_can_be_dict.yml b/changelogs/fragments/66801-mysql_user_priv_can_be_dict.yml
new file mode 100644
index 0000000000..c4f04e065e
--- /dev/null
+++ b/changelogs/fragments/66801-mysql_user_priv_can_be_dict.yml
@@ -0,0 +1,2 @@
+minor_changes:
+- mysql_user - ``priv`` parameter can be string or dictionary (https://github.com/ansible/ansible/issues/57533).
diff --git a/lib/ansible/modules/database/mysql/mysql_user.py b/lib/ansible/modules/database/mysql/mysql_user.py
index f999abb74a..257f5412d7 100644
--- a/lib/ansible/modules/database/mysql/mysql_user.py
+++ b/lib/ansible/modules/database/mysql/mysql_user.py
@@ -60,7 +60,8 @@ options:
exactly as returned by a C(SHOW GRANT) statement. If not followed,
the module will always report changes. It includes grouping columns
by permission (C(SELECT(col1,col2)) instead of C(SELECT(col1),SELECT(col2))).
- type: str
+ - Can be passed as a dictionary (see the examples).
+ type: raw
append_privs:
description:
- Append the privileges defined by priv to the existing ones for this
@@ -167,6 +168,15 @@ EXAMPLES = r'''
priv: '*.*:ALL,GRANT'
state: present
+- name: Create user with password, all database privileges and 'WITH GRANT OPTION' in db1 and db2
+ mysql_user:
+ state: present
+ name: bob
+ password: 12345dd
+ priv:
+ 'db1.*': 'ALL,GRANT'
+ 'db2.*': 'ALL,GRANT'
+
# Note that REQUIRESSL is a special privilege that should only apply to *.* by itself.
- name: Modify user to require SSL connections.
mysql_user:
@@ -651,6 +661,20 @@ def privileges_grant(cursor, user, host, db_table, priv):
query = ' '.join(query)
cursor.execute(query, (user, host))
+
+def convert_priv_dict_to_str(priv):
+ """Converts privs dictionary to string of certain format.
+
+ Args:
+ priv (dict): Dict of privileges that needs to be converted to string.
+
+ Returns:
+ priv (str): String representation of input argument.
+ """
+ priv_list = ['%s:%s' % (key, val) for key, val in iteritems(priv)]
+
+ return '/'.join(priv_list)
+
# ===========================================
# Module execution.
#
@@ -670,7 +694,7 @@ def main():
host=dict(type='str', default='localhost'),
host_all=dict(type="bool", default=False),
state=dict(type='str', default='present', choices=['absent', 'present']),
- priv=dict(type='str'),
+ priv=dict(type='raw'),
append_privs=dict(type='bool', default=False),
check_implicit_admin=dict(type='bool', default=False),
update_password=dict(type='str', default='always', choices=['always', 'on_create']),
@@ -708,6 +732,11 @@ def main():
plugin = module.params["plugin"]
plugin_hash_string = module.params["plugin_hash_string"]
plugin_auth_string = module.params["plugin_auth_string"]
+ if priv and not (isinstance(priv, str) or isinstance(priv, dict)):
+ module.fail_json(msg="priv parameter must be str or dict but %s was passed" % type(priv))
+
+ if priv and isinstance(priv, dict):
+ priv = convert_priv_dict_to_str(priv)
if mysql_driver is None:
module.fail_json(msg=mysql_driver_fail_msg)
diff --git a/test/integration/targets/mysql_user/defaults/main.yml b/test/integration/targets/mysql_user/defaults/main.yml
index 9d6865a919..7522aba14f 100644
--- a/test/integration/targets/mysql_user/defaults/main.yml
+++ b/test/integration/targets/mysql_user/defaults/main.yml
@@ -3,9 +3,11 @@
db_name: 'data'
user_name_1: 'db_user1'
user_name_2: 'db_user2'
+user_name_3: 'db_user3'
user_password_1: 'gadfFDSdtTU^Sdfuj'
user_password_2: 'jkFKUdfhdso78yi&td'
+user_password_3: 'jkFKUdfhdso78yi&tk'
root_password: 'zevuR6oPh7'
diff --git a/test/integration/targets/mysql_user/tasks/main.yml b/test/integration/targets/mysql_user/tasks/main.yml
index e399b6db89..7d2a10c014 100644
--- a/test/integration/targets/mysql_user/tasks/main.yml
+++ b/test/integration/targets/mysql_user/tasks/main.yml
@@ -208,6 +208,9 @@
#
- include: test_privs.yml current_privilege='INSERT,DELETE' current_append_privs=yes
+# Tests for the priv parameter with dict value (https://github.com/ansible/ansible/issues/57533)
+- include: test_priv_dict.yml
+
- import_tasks: issue-29511.yaml
tags:
- issue-29511
diff --git a/test/integration/targets/mysql_user/tasks/test_priv_dict.yml b/test/integration/targets/mysql_user/tasks/test_priv_dict.yml
new file mode 100644
index 0000000000..a28cc806f6
--- /dev/null
+++ b/test/integration/targets/mysql_user/tasks/test_priv_dict.yml
@@ -0,0 +1,46 @@
+# Tests for priv parameter value passed as a dict
+- name: Create test databases
+ mysql_db:
+ name: '{{ item }}'
+ state: present
+ login_unix_socket: '{{ mysql_socket }}'
+ loop:
+ - data1
+ - data2
+
+- name: Create user with privileges
+ mysql_user:
+ name: '{{ user_name_3 }}'
+ password: '{{ user_password_3 }}'
+ priv:
+ "data1.*": "SELECT"
+ "data2.*": "SELECT"
+ state: present
+ login_unix_socket: '{{ mysql_socket }}'
+
+- name: Run command to show privileges for user (expect privileges in stdout)
+ command: mysql "-e SHOW GRANTS FOR '{{ user_name_3 }}'@'localhost';"
+ register: result
+
+- name: Assert user has giving privileges
+ assert:
+ that:
+ - "'GRANT SELECT ON `data1`.*' in result.stdout"
+ - "'GRANT SELECT ON `data2`.*' in result.stdout"
+
+##########
+# Clean up
+- name: Drop test databases
+ mysql_db:
+ name: '{{ item }}'
+ state: present
+ login_unix_socket: '{{ mysql_socket }}'
+ loop:
+ - data1
+ - data2
+
+- name: Drop test user
+ mysql_user:
+ name: '{{ user_name_3 }}'
+ state: absent
+ login_unix_socket: '{{ mysql_socket }}'