From 3aaebba2351137f9ec8ecba6fdca16d06984fe6d Mon Sep 17 00:00:00 2001 From: Andrey Klychkov Date: Fri, 25 Oct 2019 16:39:49 +0300 Subject: [PATCH] postgresql_privs: allow to pass roles with names containing dots (#63942) --- .../database/postgresql/postgresql_privs.py | 8 +-- .../postgresql_privs/defaults/main.yml | 2 + .../targets/postgresql_privs/tasks/main.yml | 4 +- .../tasks/postgresql_privs_initial.yml | 59 ++++++++++++++++++- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/lib/ansible/modules/database/postgresql/postgresql_privs.py b/lib/ansible/modules/database/postgresql/postgresql_privs.py index 09443fea26d..d4433e57804 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_privs.py +++ b/lib/ansible/modules/database/postgresql/postgresql_privs.py @@ -724,7 +724,7 @@ class Connection(object): # set_what: SQL-fragment specifying what to set for the target roles: # Either group membership or privileges on objects of a certain type if obj_type == 'group': - set_what = ','.join(pg_quote_identifier(i, 'role') for i in obj_ids) + set_what = ','.join('"%s"' % i for i in obj_ids) elif obj_type == 'default_privs': # We don't want privs to be quoted here set_what = ','.join(privs) @@ -751,7 +751,7 @@ class Connection(object): else: self.module.warn("Role '%s' does not exist, pass it" % r.strip()) else: - for_whom.append(pg_quote_identifier(r, 'role')) + for_whom.append('"%s"' % r) if not for_whom: return False @@ -761,7 +761,7 @@ class Connection(object): # as_who: as_who = None if target_roles: - as_who = ','.join(pg_quote_identifier(r, 'role') for r in target_roles) + as_who = ','.join('"%s"' % r for r in target_roles) status_before = get_status(objs) @@ -988,7 +988,7 @@ def main(): if p.session_role: try: - conn.cursor.execute('SET ROLE %s' % pg_quote_identifier(p.session_role, 'role')) + conn.cursor.execute('SET ROLE "%s"' % p.session_role) except Exception as e: module.fail_json(msg="Could not switch to role %s: %s" % (p.session_role, to_native(e)), exception=traceback.format_exc()) diff --git a/test/integration/targets/postgresql_privs/defaults/main.yml b/test/integration/targets/postgresql_privs/defaults/main.yml index 28a83c59ffc..e0f7076d009 100644 --- a/test/integration/targets/postgresql_privs/defaults/main.yml +++ b/test/integration/targets/postgresql_privs/defaults/main.yml @@ -2,3 +2,5 @@ db_name: ansible_db db_user1: ansible_db_user1 db_user2: ansible_db_user2 db_user3: ansible_db_user3 +db_user_with_dots1: role.with.dots1 +db_user_with_dots2: role.with.dots2 diff --git a/test/integration/targets/postgresql_privs/tasks/main.yml b/test/integration/targets/postgresql_privs/tasks/main.yml index 95bc198d90f..cf2cf0a0a98 100644 --- a/test/integration/targets/postgresql_privs/tasks/main.yml +++ b/test/integration/targets/postgresql_privs/tasks/main.yml @@ -1,9 +1,11 @@ # Initial CI tests of postgresql_privs module: - import_tasks: postgresql_privs_initial.yml + when: postgres_version_resp.stdout is version('9.4', '>=') # General tests: - import_tasks: postgresql_privs_general.yml + when: postgres_version_resp.stdout is version('9.4', '>=') # Tests default_privs with target_role: - import_tasks: test_target_role.yml - when: postgres_version_resp.stdout is version('9.1', '>=') + when: postgres_version_resp.stdout is version('9.4', '>=') diff --git a/test/integration/targets/postgresql_privs/tasks/postgresql_privs_initial.yml b/test/integration/targets/postgresql_privs/tasks/postgresql_privs_initial.yml index 760d30e912d..f9e4241bc92 100644 --- a/test/integration/targets/postgresql_privs/tasks/postgresql_privs_initial.yml +++ b/test/integration/targets/postgresql_privs/tasks/postgresql_privs_initial.yml @@ -284,6 +284,57 @@ - "'REFERENCES' in result_table2.stdout" - "'TRIGGER' in result_table2.stdout" +# Check passing roles with dots +# https://github.com/ansible/ansible/issues/63204 +- name: Create roles for further tests + become_user: "{{ pg_user }}" + become: yes + postgresql_user: + db: "{{ db_name }}" + login_user: "{{ pg_user }}" + name: "{{ item }}" + loop: + - "{{ db_user_with_dots1 }}" + - "{{ db_user_with_dots2 }}" + +- name: Pass role with dots in its name to roles parameter + become_user: "{{ pg_user }}" + become: yes + postgresql_privs: + state: "present" + roles: "{{ db_user_with_dots1 }}" + privs: "INSERT" + objs: "test_table1" + db: "{{ db_name }}" + login_user: "{{ pg_user }}" + +- name: Check that permissions were added (table1) + become_user: "{{ pg_user }}" + become: yes + postgresql_query: + db: "{{ db_name }}" + login_user: "{{ pg_user }}" + query: "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user_with_dots1 }}' and table_name='test_table1'" + register: result + +- assert: + that: + - result.rowcount == 1 + +# We don't need to check anything here, only that nothing failed +- name: Pass role with dots in its name to target_roles parameter + become_user: "{{ pg_user }}" + become: yes + postgresql_privs: + db: "{{ db_name }}" + login_user: "{{ pg_user }}" + state: "present" + roles: "{{ db_user_with_dots1 }}" + privs: "INSERT" + objs: TABLES + type: default_privs + target_roles: "{{ db_user_with_dots2 }}" + # # Cleanup # @@ -309,10 +360,16 @@ become_user: "{{ pg_user }}" become: yes postgresql_user: - name: "{{ db_user1 }}" + name: "{{ item }}" state: 'absent' login_user: "{{ pg_user }}" db: postgres + loop: + - "{{ db_user1 }}" + - "{{ db_user2 }}" + - "{{ db_user3 }}" + - "{{ db_user_with_dots1 }}" + - "{{ db_user_with_dots2 }}" - name: Check that they were removed become_user: "{{ pg_user }}"