diff --git a/changelogs/fragments/796-postgresql_privs-grant-option-bug.yaml b/changelogs/fragments/796-postgresql_privs-grant-option-bug.yaml new file mode 100644 index 0000000000..48799923f2 --- /dev/null +++ b/changelogs/fragments/796-postgresql_privs-grant-option-bug.yaml @@ -0,0 +1,2 @@ +bugfixes: + - postgresql_privs - the module was attempting to revoke grant options even though ``grant_option`` was not specified (https://github.com/ansible-collections/community.general/pull/796). diff --git a/plugins/modules/database/postgresql/postgresql_privs.py b/plugins/modules/database/postgresql/postgresql_privs.py index 6325c86656..989279e9ed 100644 --- a/plugins/modules/database/postgresql/postgresql_privs.py +++ b/plugins/modules/database/postgresql/postgresql_privs.py @@ -864,12 +864,14 @@ class QueryBuilder(object): self.query[-1] += ' WITH ADMIN OPTION;' else: self.query[-1] += ' WITH GRANT OPTION;' - else: + elif self._grant_option is False: self.query[-1] += ';' if self._obj_type == 'group': self.query.append('REVOKE ADMIN OPTION FOR {0} FROM {1};'.format(self._set_what, self._for_whom)) elif not self._obj_type == 'default_privs': self.query.append('REVOKE GRANT OPTION FOR {0} FROM {1};'.format(self._set_what, self._for_whom)) + else: + self.query[-1] += ';' def add_default_priv(self): for obj in self._objs: diff --git a/tests/integration/targets/postgresql_privs/tasks/postgresql_privs_general.yml b/tests/integration/targets/postgresql_privs/tasks/postgresql_privs_general.yml index 431c78aa17..fe28150b39 100644 --- a/tests/integration/targets/postgresql_privs/tasks/postgresql_privs_general.yml +++ b/tests/integration/targets/postgresql_privs/tasks/postgresql_privs_general.yml @@ -59,11 +59,11 @@ - result is changed - name: Create schema with hyphen in the name - postgresql_schema: + postgresql_schema: login_user: "{{ pg_user }}" login_password: password db: "{{ db_name_with_hyphens }}" - name: "{{ db_schema_with_hyphens }}" + name: "{{ db_schema_with_hyphens }}" state: present register: result @@ -71,12 +71,12 @@ that: - result is changed -- name: Set table default privs on the schema with hyphen in the name +- name: Set table default privs on the schema with hyphen in the name postgresql_privs: login_user: "{{ pg_user }}" password: password db: "{{ db_name_with_hyphens }}" - schema: "{{ db_schema_with_hyphens }}" + schema: "{{ db_schema_with_hyphens }}" role: "{{ db_user_with_hyphens }}" type: default_privs obj: TABLES @@ -683,6 +683,135 @@ - result.rowcount == 0 when: postgres_version_resp.stdout is version('10', '>=') +# Test +- name: Grant execute with grant option on pg_create_restore_point function + postgresql_privs: + privs: EXECUTE + type: function + schema: pg_catalog + obj: pg_create_restore_point(text) + db: "{{ db_name }}" + roles: "{{ db_user2 }}" + login_user: "{{ pg_user }}" + grant_option: yes + state: present + become: yes + become_user: "{{ pg_user }}" + register: result + +# Checks +- assert: + that: result is changed + +- name: Check that user has GRANT privilege on the function + postgresql_query: + query: SELECT proacl FROM pg_proc WHERE proname='pg_create_restore_point' + db: "{{ db_name }}" + login_user: "{{ db_user2 }}" + login_password: password + become: yes + become_user: "{{ pg_user }}" + register: result + +- assert: + that: "'{{ db_user2 }}=X*/{{ pg_user }}' in result.query_result[0].proacl" + +# Test +- name: Grant execute without specifying grant_option to check idempotence + postgresql_privs: + privs: EXECUTE + type: function + schema: pg_catalog + obj: pg_create_restore_point(text) + db: "{{ db_name }}" + roles: "{{ db_user2 }}" + login_user: "{{ pg_user }}" + state: present + become: yes + become_user: "{{ pg_user }}" + register: result + +# Checks +- assert: + that: result is not changed + +- name: Check that user has GRANT privilege on the function + postgresql_query: + query: SELECT proacl FROM pg_proc WHERE proname='pg_create_restore_point' + db: "{{ db_name }}" + login_user: "{{ db_user2 }}" + login_password: password + become: yes + become_user: "{{ pg_user }}" + register: result + +- assert: + that: "'{{ db_user2 }}=X*/{{ pg_user }}' in result.query_result[0].proacl" + +# Test +- name: Revoke grant option on pg_create_restore_point function + postgresql_privs: + privs: EXECUTE + type: function + schema: pg_catalog + obj: pg_create_restore_point(text) + db: "{{ db_name }}" + roles: "{{ db_user2 }}" + login_user: "{{ pg_user }}" + grant_option: no + state: present + become: yes + become_user: "{{ pg_user }}" + register: result + +# Checks +- assert: + that: result is changed + +- name: Check that user does not have GRANT privilege on the function + postgresql_query: + query: SELECT proacl FROM pg_proc WHERE proname='pg_create_restore_point' + db: "{{ db_name }}" + login_user: "{{ db_user2 }}" + login_password: password + become: yes + become_user: "{{ pg_user }}" + register: result + +- assert: + that: "'{{ db_user2 }}=X/{{ pg_user }}' in result.query_result[0].proacl" + +# Test +- name: Revoke execute on pg_create_restore_point function + postgresql_privs: + privs: EXECUTE + type: function + schema: pg_catalog + obj: pg_create_restore_point(text) + db: "{{ db_name }}" + roles: "{{ db_user2 }}" + login_user: "{{ pg_user }}" + state: absent + become: yes + become_user: "{{ pg_user }}" + register: result + +# Checks +- assert: + that: result is changed + +- name: Check that user does not have EXECUTE privilege on the function + postgresql_query: + query: SELECT proacl FROM pg_proc WHERE proname='pg_create_restore_point' + db: "{{ db_name }}" + login_user: "{{ db_user2 }}" + login_password: password + become: yes + become_user: "{{ pg_user }}" + register: result + +- assert: + that: "'{{ db_user2 }}' not in result.query_result[0].proacl" # Test - name: Grant execute to all tables @@ -934,7 +1063,7 @@ that: - "'{{ db_user2 }}' in typ_result.query_result[0].typacl" when: postgres_version_resp.stdout is version('10', '>=') - + - name: Revoke type privileges in check_mode become: yes become_user: "{{ pg_user }}"