Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support grants and revokes on foreign tables #725

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelogs/fragments/725-privs-for-foreign-tables.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
- postgresql_privs - adds support for granting and revoking privileges on foreign tables
(https://github.com/ansible-collections/community.postgresql/issues/724).
9 changes: 5 additions & 4 deletions plugins/modules/postgresql_privs.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
- The C(type) choice is available since Ansible version 2.10.
- The C(procedure) is supported since collection version 1.3.0 and PostgreSQL 11.
- The C(parameter) is supported since collection version 3.1.0 and PostgreSQL 15.
- The C(table) is inclusive of foreign tables since collection version 3.6.0.
type: str
default: table
choices: [ database, default_privs, foreign_data_wrapper, foreign_server, function,
Expand Down Expand Up @@ -549,11 +550,11 @@ def get_all_tables_in_schema(self, schema):
query = """SELECT relname
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE nspname = %s AND relkind in ('r', 'v', 'm', 'p')"""
WHERE nspname = %s AND relkind in ('r', 'v', 'm', 'p', 'f')"""
self.execute(query, (schema,))
else:
query = ("SELECT relname FROM pg_catalog.pg_class "
"WHERE relkind in ('r', 'v', 'm', 'p')")
"WHERE relkind in ('r', 'v', 'm', 'p', 'f')")
self.execute(query)
return [t["relname"] for t in self.cursor.fetchall()]

Expand Down Expand Up @@ -621,12 +622,12 @@ def get_table_acls(self, schema, tables):
query = """SELECT relacl::text
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE nspname = %s AND relkind in ('r','p','v','m') AND relname = ANY (%s)
WHERE nspname = %s AND relkind in ('r','p','v','m','f') AND relname = ANY (%s)
ORDER BY relname"""
self.execute(query, (schema, tables))
else:
query = ("SELECT relacl::text FROM pg_catalog.pg_class "
"WHERE relkind in ('r','p','v','m') AND relname = ANY (%s) "
"WHERE relkind in ('r','p','v','m','f') AND relname = ANY (%s) "
"ORDER BY relname")
self.execute(query)
return [t["relacl"] for t in self.cursor.fetchall()]
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/targets/postgresql_privs/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@
# Tests default_privs with target_role:
- include_tasks: test_target_role.yml
when: postgres_version_resp.stdout is version('9.4', '>=')

# Tests involving foreign tables:
- include_tasks: postgresql_privs_foreign_tables.yml
when: postgres_version_resp.stdout is version('9.4', '>=')
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#
# Test settings privileges for foreign tables
#
- name: Create db
become_user: "{{ pg_user }}"
become: true
postgresql_db:
name: "{{ db_name }}"
state: "present"
login_user: "{{ pg_user }}"

- name: Create some tables on the db
become_user: "{{ pg_user }}"
become: true
shell: echo "create table test_table1 (field text);" | psql {{ db_name }}

- vars:
db_password: 'secretù' # use UTF-8
block:
- name: Create a user with some permissions on the db
become_user: "{{ pg_user }}"
become: true
postgresql_user:
name: "{{ db_user1 }}"
encrypted: 'true'
password: "md5{{ (db_password ~ db_user1) | hash('md5')}}"
db: "{{ db_name }}"
login_user: "{{ pg_user }}"

- name: Install foreign data wrapper extension
become: yes
become_user: "{{ pg_user }}"
postgresql_query:
login_db: "{{ db_name }}"
query: "CREATE EXTENSION IF NOT EXISTS postgres_fdw"

- name: Create foreign server
become: yes
become_user: "{{ pg_user }}"
postgresql_query:
login_db: "{{ db_name }}"
query: "CREATE SERVER IF NOT EXISTS self FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'localhost',dbname '{{ db_name }}')"

- name: Create user mapping
become: yes
become_user: "{{ pg_user }}"
postgresql_query:
login_db: "{{ db_name }}"
query: "CREATE USER MAPPING IF NOT EXISTS FOR CURRENT_USER SERVER self OPTIONS (user '{{ pg_user }}')"

- name: Create foreign table
become: yes
become_user: "{{ pg_user }}"
postgresql_query:
login_db: "{{ db_name }}"
query: "CREATE FOREIGN TABLE IF NOT EXISTS foreign_table1 (field text) SERVER self OPTIONS (table_name 'test_table1')"

- name: Grant a single privilege on foreign table
become_user: "{{ pg_user }}"
become: true
postgresql_privs:
state: "present"
roles: "{{ db_user1 }}"
privs: "INSERT"
objs: "foreign_table1"
login_db: "{{ db_name }}"
login_user: "{{ pg_user }}"
trust_input: false

- name: Check that permissions were added (foreign_table1)
become_user: "{{ pg_user }}"
become: true
postgresql_query:
login_db: '{{ db_name }}'
query: "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='foreign_table1'"
register: result_table1

- assert:
that:
- result_table1.rowcount == 1
- result_table1.query_result[0]['privilege_type'] == 'INSERT'

- name: Revoke privileges on foreign table
become_user: "{{ pg_user }}"
become: true
postgresql_privs:
state: "absent"
roles: "{{ db_user1 }}"
privs: "INSERT"
objs: "foreign_table1"
db: "{{ db_name }}"
login_user: "{{ pg_user }}"
trust_input: false
register: result

- name: Check that ansible reports it changed the user
assert:
that:
- result is changed

- name: Check that permissions were revoked (foreign_table1)
become_user: "{{ pg_user }}"
become: true
postgresql_query:
login_db: '{{ db_name }}'
query: "select privilege_type from information_schema.role_table_grants where grantee='{{ db_user1 }}' and table_name='foreign_table1'"
register: result_table1

- assert:
that:
- result_table1.rowcount == 0
Loading