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

postgresql_lang: add owner parameter #62999

Merged
merged 2 commits into from
Oct 3, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- postgresql_lang - add ``owner`` parameter (https://github.com/ansible/ansible/pull/62999).
50 changes: 49 additions & 1 deletion lib/ansible/modules/database/postgresql/postgresql_lang.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@
type: str
aliases: [ ssl_rootcert ]
version_added: '2.8'
owner:
description:
- Set an owner for the language.
- Ignored when I(state=absent).
type: str
version_added: '2.10'
seealso:
- name: PostgreSQL languages
description: General information about PostgreSQL languages.
Expand Down Expand Up @@ -156,6 +162,12 @@
lang: pltclu
state: absent
fail_on_drop: no

- name: In testdb change owner of mylang to alice
postgresql_lang:
db: testdb
lang: mylang
owner: alice
'''

RETURN = r'''
Expand Down Expand Up @@ -228,6 +240,34 @@ def lang_drop(cursor, lang, cascade):
return True


def get_lang_owner(cursor, lang):
"""Get language owner.

Args:
cursor (cursor): psycopg2 cursor object.
lang (str): language name.
"""
query = ("SELECT r.rolname FROM pg_language l "
"JOIN pg_roles r ON l.lanowner = r.oid "
"WHERE l.lanname = '%s'" % lang)
cursor.execute(query)
return cursor.fetchone()[0]


def set_lang_owner(cursor, lang, owner):
"""Set language owner.

Args:
cursor (cursor): psycopg2 cursor object.
lang (str): language name.
owner (str): name of new owner.
"""
query = "ALTER LANGUAGE %s OWNER TO %s" % (lang, owner)
executed_queries.append(query)
cursor.execute(query)
return True


def main():
argument_spec = postgres_common_argument_spec()
argument_spec.update(
Expand All @@ -239,6 +279,7 @@ def main():
cascade=dict(type="bool", default="no"),
fail_on_drop=dict(type="bool", default="yes"),
session_role=dict(type="str"),
owner=dict(type="str"),
)

module = AnsibleModule(
Expand All @@ -253,6 +294,7 @@ def main():
force_trust = module.params["force_trust"]
cascade = module.params["cascade"]
fail_on_drop = module.params["fail_on_drop"]
owner = module.params["owner"]

conn_params = get_conn_params(module, module.params)
db_connection = connect_to_db(module, conn_params, autocommit=False)
Expand Down Expand Up @@ -285,10 +327,16 @@ def main():
else:
changed = lang_drop(cursor, lang, cascade)
if fail_on_drop and not changed:
msg = "unable to drop language, use cascade to delete dependencies or fail_on_drop=no to ignore"
msg = ("unable to drop language, use cascade "
"to delete dependencies or fail_on_drop=no to ignore")
module.fail_json(msg=msg)
kw['lang_dropped'] = changed

if owner and state == 'present':
if lang_exists(cursor, lang):
if owner != get_lang_owner(cursor, lang):
changed = set_lang_owner(cursor, lang, owner)

if changed:
if module.check_mode:
db_connection.rollback()
Expand Down
4 changes: 4 additions & 0 deletions test/integration/targets/postgresql_lang/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Initial CI tests of postgresql_lang module
- import_tasks: postgresql_lang_initial.yml
when: ansible_distribution == 'CentOS'

# CI tests of owner param
- import_tasks: postgresql_lang_add_owner_param.yml
when: ansible_distribution == 'CentOS'
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Copyright: (c) 2019, Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

- vars:
test_user1: alice
test_user2: bob
test_lang: plperl
non_existent_role: fake_role
task_parameters: &task_parameters
become_user: '{{ pg_user }}'
become: yes
register: result
pg_parameters: &pg_parameters
login_user: '{{ pg_user }}'
login_db: postgres

block:
- name: Create roles for tests
<<: *task_parameters
postgresql_user:
<<: *pg_parameters
name: '{{ item }}'
loop:
- '{{ test_user1 }}'
- '{{ test_user2 }}'

- name: Create lang with owner in check_mode
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
owner: '{{ test_user1 }}'
check_mode: yes

- assert:
that:
- result is changed
- result.queries == []

- name: Check that nothing was actually changed
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'
AND r.rolname = '{{ test_user1 }}'

- assert:
that:
- result.rowcount == 0

- name: Create lang with owner
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
owner: '{{ test_user1 }}'

- assert:
that:
- result is changed
- result.queries == ['CREATE LANGUAGE "{{ test_lang }}"', 'ALTER LANGUAGE {{ test_lang }} OWNER TO {{ test_user1 }}']

- name: Check
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'
AND r.rolname = '{{ test_user1 }}'

- assert:
that:
- result.rowcount == 1

- name: Change lang owner in check_mode
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
owner: '{{ test_user2 }}'
check_mode: yes

- assert:
that:
- result is changed
- result.queries == ["ALTER LANGUAGE {{ test_lang }} OWNER TO {{ test_user2 }}"]

- name: Check that nothing was actually changed
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'
AND r.rolname = '{{ test_user2 }}'

- assert:
that:
- result.rowcount == 0

- name: Change lang owner
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
owner: '{{ test_user2 }}'

- assert:
that:
- result is changed
# TODO: the first elem of the returned list below
# looks like a bug, not related with the option owner, needs to be checked
- result.queries == ["UPDATE pg_language SET lanpltrusted = 'False' WHERE lanname = '{{ test_lang }}'", "ALTER LANGUAGE {{ test_lang }} OWNER TO {{ test_user2 }}"]

- name: Check
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'
AND r.rolname = '{{ test_user2 }}'

- assert:
that:
- result.rowcount == 1

- name: Try to change lang owner again to the same role
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
owner: '{{ test_user2 }}'

- assert:
that:
- result is not changed
- result.queries == []

- name: Check
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'
AND r.rolname = '{{ test_user2 }}'

- assert:
that:
- result.rowcount == 1

- name: Drop test lang with owner, must ignore
<<: *task_parameters
postgresql_lang:
<<: *pg_parameters
name: '{{ test_lang }}'
state: absent
owner: '{{ non_existent_role }}'

- assert:
that:
- result is changed
- result.queries == ["DROP LANGUAGE \"{{ test_lang }}\""]

- name: Check
<<: *task_parameters
postgresql_query:
<<: *pg_parameters
query: >
SELECT r.rolname FROM pg_language l
JOIN pg_roles r ON l.lanowner = r.oid
WHERE l.lanname = '{{ test_lang }}'

- assert:
that:
- result.rowcount == 0

# Clean up
- name: Drop test roles
<<: *task_parameters
postgresql_user:
<<: *pg_parameters
name: '{{ item }}'
state: absent
loop:
- '{{ test_user1 }}'
- '{{ test_user2 }}'