Skip to content

Commit 03a3dd3

Browse files
gspanospatchback[bot]
authored andcommitted
postgresql_db: fix session_role support for raw connections (#865)
(cherry picked from commit de36216)
1 parent bb3e94f commit 03a3dd3

File tree

4 files changed

+220
-2
lines changed

4 files changed

+220
-2
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bugfixes:
2+
- postgresql_db - fixed ``session_role`` parameter that was being ignored for raw connections (https://github.com/ansible-collections/community.postgresql/pull/865)

plugins/modules/postgresql_db.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ def db_dump(module, target, target_opts="",
530530
password=None,
531531
host=None,
532532
port=None,
533+
session_role=None,
533534
**kw):
534535

535536
flags = login_flags(db, host, port, user, db_prefix=False)
@@ -553,6 +554,9 @@ def db_dump(module, target, target_opts="",
553554
elif os.path.splitext(target)[-1] == '.xz':
554555
comp_prog_path = module.get_bin_path('xz', True)
555556

557+
if session_role:
558+
flags.append(' --role={0}'.format(shlex_quote(session_role)))
559+
556560
cmd += "".join(flags)
557561

558562
if dump_extra_args:
@@ -583,26 +587,31 @@ def db_restore(module, target, target_opts="",
583587
password=None,
584588
host=None,
585589
port=None,
590+
session_role=None,
586591
**kw):
587592

588593
flags = login_flags(db, host, port, user)
589594
comp_prog_path = None
590595
cmd = module.get_bin_path('psql', True)
596+
pg_restore = False
591597

592598
if os.path.splitext(target)[-1] == '.sql':
593599
flags.append(' --file={0}'.format(target))
594600

595601
elif os.path.splitext(target)[-1] == '.tar':
596602
flags.append(' --format=Tar')
597603
cmd = module.get_bin_path('pg_restore', True)
604+
pg_restore = True
598605

599606
elif os.path.splitext(target)[-1] == '.pgc':
600607
flags.append(' --format=Custom')
601608
cmd = module.get_bin_path('pg_restore', True)
609+
pg_restore = True
602610

603611
elif os.path.splitext(target)[-1] == '.dir':
604612
flags.append(' --format=Directory')
605613
cmd = module.get_bin_path('pg_restore', True)
614+
pg_restore = True
606615

607616
elif os.path.splitext(target)[-1] == '.gz':
608617
comp_prog_path = module.get_bin_path('zcat', True)
@@ -613,6 +622,9 @@ def db_restore(module, target, target_opts="",
613622
elif os.path.splitext(target)[-1] == '.xz':
614623
comp_prog_path = module.get_bin_path('xzcat', True)
615624

625+
if pg_restore and session_role:
626+
flags.append(' --role={0}'.format(shlex_quote(session_role)))
627+
616628
cmd += "".join(flags)
617629
if target_opts:
618630
cmd += " {0} ".format(target_opts)
@@ -843,9 +855,13 @@ def main():
843855
method = state == "dump" and db_dump or db_restore
844856

845857
if state == 'dump':
846-
rc, stdout, stderr, cmd = method(module, target, target_opts, db, dump_extra_args, **conn_params)
858+
rc, stdout, stderr, cmd = method(
859+
module, target, target_opts, db, dump_extra_args, session_role=session_role, **conn_params
860+
)
847861
else:
848-
rc, stdout, stderr, cmd = method(module, target, target_opts, db, **conn_params)
862+
rc, stdout, stderr, cmd = method(
863+
module, target, target_opts, db, session_role=session_role, **conn_params
864+
)
849865

850866
if rc != 0:
851867
module.fail_json(msg=stderr, stdout=stdout, rc=rc, cmd=cmd)

tests/integration/targets/postgresql_db/tasks/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
file: dbdata.tar
4444
test_fixture: admin
4545

46+
- import_tasks: state_dump_restore_role.yml
47+
4648
# Simple test to create and then drop with force
4749
- import_tasks: manage_database.yml
4850

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# This file is part of Ansible
2+
#
3+
# Ansible is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# Ansible is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
15+
16+
# ============================================================
17+
18+
- name: create a new role
19+
postgresql_user:
20+
name: "{{ db_session_role1 }}"
21+
state: "present"
22+
encrypted: 'true'
23+
password: "password"
24+
login_user: "{{ pg_user }}"
25+
db: postgres
26+
become: true
27+
become_user: "{{ pg_user }}"
28+
29+
- name: make db_session_role1 an admin for convenience
30+
postgresql_membership:
31+
group: "{{ pg_user }}"
32+
target_roles: "{{ db_session_role1 }}"
33+
state: present
34+
35+
# needs to be .pgc to force use of pg_dump/pg_restore binaries
36+
- set_fact: db_file_name="{{tmp_dir}}/dbdata.pgc"
37+
38+
- name: create test databases with different owners
39+
postgresql_db:
40+
state: present
41+
name: "{{ item.name }}"
42+
owner: "{{ item.owner }}"
43+
login_user: "{{ pg_user }}"
44+
loop:
45+
- name: src_db
46+
owner: "{{ pg_user }}"
47+
- name: dst_db
48+
owner: "{{ db_session_role1 }}"
49+
50+
- name: create schema1 in src_db owned by pg_user
51+
postgresql_schema:
52+
state: present
53+
name: schema1
54+
login_db: src_db
55+
login_user: "{{ pg_user }}"
56+
57+
- name: create employees table in src_db.schema1
58+
postgresql_table:
59+
name: schema1.employees
60+
columns:
61+
- id bigserial primary key
62+
- name varchar(20)
63+
state: present
64+
login_db: src_db
65+
login_user: "{{ pg_user }}"
66+
67+
- name: populate src_db.schema1.employees
68+
postgresql_query:
69+
login_db: src_db
70+
login_user: "{{ pg_user }}"
71+
query: >-
72+
INSERT INTO schema1.employees (name)
73+
VALUES ('Guybrush Threepwood');
74+
75+
- name: pg_dump src_db.schema1 as pg_user
76+
postgresql_db:
77+
login_user: "{{ pg_user }}"
78+
name: src_db
79+
state: dump
80+
target: "{{ db_file_name }}"
81+
target_opts: "-n schema1"
82+
register: result
83+
become_user: "{{ pg_user }}"
84+
become: true
85+
86+
- name: assert pg_dump usage with -n parameter
87+
assert:
88+
that:
89+
- result is changed
90+
- result.executed_commands[0] is search("/bin/pg_dump")
91+
- result.executed_commands[0] is search("-n schema1")
92+
93+
- name: pg_restore archive on dst_db with session_role
94+
postgresql_db:
95+
login_user: "{{ pg_user }}"
96+
name: dst_db
97+
state: restore
98+
target: "{{ db_file_name }}"
99+
session_role: "{{ db_session_role1 }}"
100+
target_opts: "--no-owner"
101+
register: result
102+
become_user: "{{ pg_user }}"
103+
become: true
104+
105+
- name: assert pg_restore usage with role parameter
106+
assert:
107+
that:
108+
- result is changed
109+
- result.executed_commands[0] is search("/bin/pg_restore")
110+
- result.executed_commands[0] is search("--role=")
111+
112+
- name: check restored schema1 owner is db_session_role1
113+
postgresql_query:
114+
login_db: dst_db
115+
login_user: "{{ pg_user }}"
116+
query: >-
117+
SELECT r.rolname AS owner
118+
FROM pg_namespace ns
119+
JOIN pg_roles r ON ns.nspowner = r.oid
120+
WHERE ns.nspname = 'schema1';
121+
register: result
122+
123+
- assert:
124+
that:
125+
- result.query_result[0]['owner'] == db_session_role1
126+
127+
- name: check restored schema1.employees owner is db_session_role1
128+
postgresql_query:
129+
login_db: dst_db
130+
login_user: "{{ pg_user }}"
131+
query: >-
132+
SELECT tableowner as owner
133+
FROM pg_tables WHERE tablename = 'employees' and schemaname = 'schema1'
134+
register: result
135+
136+
- assert:
137+
that:
138+
- result.query_result[0]['owner'] == db_session_role1
139+
140+
- name: drop schema1 from dst_db
141+
postgresql_schema:
142+
state: absent
143+
cascade_drop: true
144+
name: schema1
145+
login_db: dst_db
146+
login_user: "{{ pg_user }}"
147+
148+
- name: remove db archive
149+
file:
150+
name: "{{ db_file_name }}"
151+
state: absent
152+
153+
- name: pg_dump src_db.schema1 with session_role
154+
postgresql_db:
155+
login_user: "{{ pg_user }}"
156+
session_role: "{{ db_session_role1 }}"
157+
name: src_db
158+
state: dump
159+
target: "{{ db_file_name }}"
160+
target_opts: "-n schema1"
161+
register: result
162+
become_user: "{{ pg_user }}"
163+
become: true
164+
165+
- name: assert pg_dump usage with role parameter
166+
assert:
167+
that:
168+
- result is changed
169+
- result.executed_commands[0] is search("/bin/pg_dump")
170+
- result.executed_commands[0] is search("-n schema1")
171+
- result.executed_commands[0] is search("--role=")
172+
173+
- name: verify archive file was created
174+
ansible.builtin.stat:
175+
path: "{{ db_file_name }}"
176+
177+
# Clean up
178+
- name: remove test databases
179+
postgresql_db:
180+
name: "{{ item }}"
181+
login_user: "{{ pg_user }}"
182+
state: absent
183+
loop:
184+
- src_db
185+
- dst_db
186+
187+
- name: remove db archive
188+
file:
189+
name: "{{ db_file_name }}"
190+
state: absent
191+
192+
- name: remove db_session_role1 user
193+
postgresql_user:
194+
login_user: "{{ pg_user }}"
195+
name: "{{ db_session_role1 }}"
196+
state: absent
197+
become: true
198+
become_user: "{{ pg_user }}"

0 commit comments

Comments
 (0)