Skip to content

Commit 50a5d9e

Browse files
authored
Merge pull request #278 from bartowl/bugfix/oradb_rman_catalog_support
fix rman catalog support in oradb_rman
2 parents 7f5224b + 39bc00b commit 50a5d9e

File tree

5 files changed

+211
-53
lines changed

5 files changed

+211
-53
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
bugfixes:
3+
- 'fixed/fully implemented rman catalog support in oradb_rman (#278)'

roles/oradb_rman/README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,17 @@ Cronjobs are only created when day, weekday, hour and minute are defined.
6969

7070
* rman_retention_policy
7171

72-
This could be used to overwrite the global default of `rman_retention_policy`at database level.
72+
This could be used to overwrite the global default of `rman_retention_policy` at database level.
73+
74+
## Using RMAN Catalog
75+
76+
It is possible to configure rman jobs to use RMAN Catalog. In order to achieve this, you need to specify following attributes
77+
at your `oracle_databases` database block:
78+
* `rman_tnsalias` - tnsnames alias for RMAN Catalog database (has to be a tnsnames alias present in database home)
79+
* `rman_user` - username for the catalog database
80+
* `rman_password` - [deprecated] password for the catalog database. Use `dbpasswords[rman_tnsalias][rman_user]` instead.
81+
* `rman_wallet` (optionally) - when set to true, this role will configure Oracle Wallet for RMAN not to include plaintext password in crontab file.
7382

74-
*
7583
## Example
7684

7785
The backup is configured in oracle_databases with rman_jobs:
@@ -80,7 +88,9 @@ The backup is configured in oracle_databases with rman_jobs:
8088
oracle_databases:
8189
- home: db_home1
8290
oracle_db_name: TEST
83-
91+
# rman_tnsalias: RCAT
92+
# rman_user: rman
93+
# rman_wallet: true
8494
rman_jobs:
8595
- name: parameter
8696
- name: archivelog

roles/oradb_rman/defaults/main.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ rman_wallet_password: "oracleWallet1"
1616
rmanautofs: false
1717

1818
rman_cron_mkjob: false
19+
configure_cluster: false
20+
listener_port: 1521 # for tnsnames templates
1921

2022
rman_retention_policy_default: "RECOVERY WINDOW OF 14 DAYS"
2123
rman_channel_disk_default: "'/u10/rmanbackup/%d/%d_%T_%U'"
2224
rman_controlfile_autobackup_disk_default: "'/u10/rmanbackup/%d/%d_%F'"
2325
rman_device_type_disk_default: 'PARALLELISM 1 BACKUP TYPE TO COMPRESSED BACKUPSET'
2426

25-
rman_retention_policy: "{% if item.0.rman_retention_policy is defined %}{{ item.0.rman_retention_policy }}{% else %}{{ rman_retention_policy_default }}{% endif %}"
26-
rman_channel_disk: "{% if item.0.rman_channel_disk is defined %}{{ item.0.rman_channel_disk }}{% else %}{{ rman_channel_disk_default }}{% endif %}"
27-
rman_controlfile_autobackup_disk: "{% if item.0.rman_controlfile_autobackup_disk is defined %}{{ item.0.rman_controlfile_autobackup_disk }}
28-
{%- else %}{{ rman_controlfile_autobackup_disk_default }}
29-
{%- endif %}"
27+
rman_retention_policy: "{{ item.0.rman_retention_policy | default(rman_retention_policy_default) }}"
28+
rman_channel_disk: "{{ item.0.rman_channel_disk | default(rman_channel_disk_default) }}"
29+
rman_controlfile_autobackup_disk: "{{ item.0.rman_controlfile_autobackup_disk | default(rman_controlfile_autobackup_disk_default) }}"
3030

3131
rman_service_param: "{% if item.1.service is defined %}--service {{ item.1.service }}{% else %}{% endif %}"
3232

@@ -36,6 +36,6 @@ rmanbackuplogdir: "{% if item.0.rman_log_dir is defined %}-l {{ item.0.rman_log_
3636
rmanbackupscriptdir: "{% if item.0.rman_script_dir is defined %}-r {{ item.0.rman_script_dir }}{% else %}{% endif %}"
3737
rman_catalog_param: "{% if item.0.rman_wallet is defined and item.0.rman_wallet %}-c /@{{ item.0.rman_tnsalias }}
3838
{%- else %}
39-
{%- if item.0.rman_user is defined %}-c {{ item.0.rman_user }}/{{ item.0.rman_password }}@{{ item.0.rman_tnsalias }}
39+
{%- if item.0.rman_user is defined %}-c {{ item.0.rman_user }}/{{ dbpasswords[item.0.rman_tnsalias][item.0.rman_user] | default(item.0.rman_password) }}@{{ item.0.rman_tnsalias }}
4040
{%- endif %}
4141
{%- endif %}"

roles/oradb_rman/tasks/main.yml

Lines changed: 176 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,69 @@
99
tags:
1010
- assert
1111

12+
- name: Warn if old style password variable is used
13+
ansible.builtin.debug:
14+
msg: '[WARNING]: do not use rman_password in oracle_databases, use dbpasswords[rman_tnsname][rman_user] instead!'
15+
# make warning red, but continue
16+
failed_when: true
17+
# noqa ignore-errors
18+
ignore_errors: true
19+
when: item.rman_password is defined
20+
with_items:
21+
- "{{ oracle_databases }}"
22+
loop_control:
23+
label: "{{ item.oracle_db_name | default('') }}"
24+
1225
# autofs is configured in a special way to mount the shares with needed parameters
1326
- name: configure autofs for RMAN
1427
ansible.builtin.lineinfile:
15-
dest=/etc/auto.master
16-
regexp="^{{ rmanautofsmount }} "
17-
line="{{ rmanautofsmount }} /etc/auto.net --timeout=60 rw,hard,rsize=32768,wsize=32768,proto=tcp,nfsvers=3"
28+
dest: "/etc/auto.master"
29+
regexp: "^{{ rmanautofsmount }} "
30+
line: "{{ rmanautofsmount }} /etc/auto.net --timeout=60 rw,hard,rsize=32768,wsize=32768,proto=tcp,nfsvers=3"
1831
when: rmanautofs
1932
tags: autofs
2033

2134
- name: Create Mountpoint
22-
ansible.builtin.file: dest={{ rmanautofsmount }} state=directory mode=0755
35+
ansible.builtin.file:
36+
dest: "{{ rmanautofsmount }}"
37+
state: directory
38+
mode: '0755'
2339
when: rmanautofs
2440
tags: autofs
2541

2642
- name: Restart autofs
27-
ansible.builtin.service: name=autofs enabled=yes state=restarted
43+
ansible.builtin.service:
44+
name: autofs
45+
enabled: true
46+
state: restarted
2847
when: rmanautofs
2948
tags: autofs
3049

3150
- name: Create bin-Directory for rman_backup
32-
ansible.builtin.file: path={{ oracle_base }}/bin state=directory mode=0755
51+
ansible.builtin.file:
52+
path: "{{ oracle_base }}/bin"
53+
state: directory
54+
mode: '0755'
3355
tags:
3456
- rmancopy
3557

3658
- name: Create log-Directory for cron output
37-
ansible.builtin.file: path={{ rman_cron_logdir }} state=directory mode=0755 owner={{ oracle_user }}
59+
ansible.builtin.file:
60+
path: "{{ rman_cron_logdir }}"
61+
state: directory
62+
mode: '0755'
63+
owner: "{{ oracle_user }}"
3864
tags:
3965
- rmancron
4066
- rmancopy
4167

4268
# dummy with_together for item.0.db_name in default/main.yml
4369
- name: Create Directory for rman-scripts
44-
ansible.builtin.file: path={{ rman_script_dir }} state=directory mode=0755 owner={{ oracle_user }}
70+
ansible.builtin.file:
71+
path: "{{ rman_script_dir }}"
72+
state: directory
73+
mode: '0755'
74+
owner: "{{ oracle_user }}"
4575
with_together:
4676
- "{{ oracle_databases }}"
4777
- ""
@@ -52,7 +82,11 @@
5282

5383
# dummy with_together for item.0.db_name in default/main.yml
5484
- name: Create Directory for rman-logfiles
55-
ansible.builtin.file: path={{ rman_log_dir }} state=directory mode=0755 owner={{ oracle_user }}
85+
ansible.builtin.file:
86+
path: "{{ rman_log_dir }}"
87+
state: "directory"
88+
mode: '0755'
89+
owner: "{{ oracle_user }}"
5690
with_together:
5791
- "{{ oracle_databases }}"
5892
- ""
@@ -62,13 +96,22 @@
6296
- rmancopy
6397

6498
- name: copy rman_backup.sh
65-
ansible.builtin.copy: dest={{ oracle_base }}/bin src=rman_backup.sh backup=yes mode=755
99+
ansible.builtin.copy:
100+
dest: "{{ oracle_base }}/bin"
101+
src: "rman_backup.sh"
102+
backup: true
103+
mode: '0755'
66104
tags:
67105
- rmancopy
68106

69107
# rman_script_dir: {{oracle_admin_db}}/rman/
70108
- name: copy RMAN scipts
71-
ansible.builtin.template: dest={{ rman_script_dir }}/{{ item.1.name }}.rman src={{ item.1.name }}.rman.j2 backup=yes mode=644 owner={{ oracle_user }}
109+
ansible.builtin.template:
110+
dest: "{{ rman_script_dir }}/{{ item.1.name }}.rman"
111+
src: "{{ item.1.name }}.rman.j2"
112+
backup: true
113+
mode: '0644'
114+
owner: "{{ oracle_user }}"
72115
with_subelements:
73116
- "{{ oracle_databases }}"
74117
- rman_jobs
@@ -79,51 +122,134 @@
79122
- rmancopy
80123

81124
- name: Create directory for TNS_ADMIN
82-
ansible.builtin.file: dest={{ rman_tns_admin }} state=directory owner={{ oracle_user }} mode=0755
125+
ansible.builtin.file:
126+
dest: "{{ rman_tns_admin }}"
127+
state: directory
128+
owner: "{{ oracle_user }}"
129+
mode: '0755'
83130
with_items:
84-
- "{{ oracle_databases }}"
85-
when: item.rman_tnsalias is defined
131+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | map(attribute='oracle_db_name') }}"
86132
tags:
87133
- tns
88134

89-
- name: copy sqlnet.ora for wallet
90-
ansible.builtin.template: src=sqlnet.ora.j2 dest={{ rman_tns_admin }}/sqlnet.ora owner={{ oracle_user }} mode=0644
135+
- name: Template sqlnet.ora for rman catalog wallet
136+
ansible.builtin.template:
137+
src: "sqlnet.ora.j2"
138+
dest: "{{ rman_tns_admin }}/sqlnet.ora"
139+
owner: "{{ oracle_user }}"
140+
mode: '0644'
91141
with_items:
92-
- "{{ oracle_databases }}"
93-
when: item.rman_tnsalias is defined
142+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | selectattr('rman_wallet','defined') }}"
143+
loop_control:
144+
label: "{{ item.oracle_db_name | default('') }}"
145+
when: item.rman_wallet
94146
tags:
95147
- tns
96148

97-
- name: copy tnsnames.ora for catalog
98-
ansible.builtin.template: src=tnsnames.ora.j2 dest={{ rman_tns_admin }}/tnsnames.ora owner={{ oracle_user }} mode=644 backup=true
99-
with_items:
149+
- name: Template tnsnames.ora for rman catalog
150+
ansible.builtin.blockinfile:
151+
block: "{{ lookup('template', '../../oradb_manage_db/templates/tnsnames' + oracle_tnsnames_config[tnsinst.tnsname]['tnstemplate'] | default('') + '.ora.j2') }}"
152+
path: "{{ rman_tns_admin }}/tnsnames.ora"
153+
backup: true
154+
create: true
155+
group: "{{ oracle_group }}"
156+
owner: "{{ oracle_user }}"
157+
state: present
158+
mode: 0644
159+
insertafter: "EOF"
160+
marker: "# {mark} Ansible managed for {{ tnsinst.tnsname }}"
161+
vars:
162+
dbh: "{{ item.0 }}"
163+
tnsinst: "{{ item.1 }}"
164+
with_nested:
100165
- "{{ oracle_databases }}"
101-
when: item.rman_tnsalias is defined
166+
- "{{ tnsnames_installed }}"
167+
loop_control:
168+
label: "{{ dbh.oracle_db_name | default('') }} -> {{ tnsinst.tnsname | default('') }}"
169+
when:
170+
- dbh.rman_tnsalias is defined
171+
- dbh.home == tnsinst.home
172+
- tnsinst.tnsname == dbh.rman_tnsalias
102173
tags:
103174
- tns
104175

105176
- name: Wallet create
106-
ansible.builtin.shell: "test -d {{ rman_wallet_loc }} || echo -e '{{ rman_wallet_password }}\n{{ rman_wallet_password }}' | {{ oracle_home_db }}/bin/mkstore -create -nologo -wrl {{ rman_wallet_loc }}"
107-
# noqa risky-shell-pipe yaml
177+
ansible.builtin.shell:
178+
cmd: 'echo -e "$stdin" | {{ oracle_home_db }}/bin/mkstore -create -nologo -wrl "{{ rman_wallet_loc }}"'
179+
creates: "{{ rman_wallet_loc }}/ewallet.p12"
108180
become: true
109181
become_user: "{{ oracle_user }}"
182+
environment:
183+
stdin: "{{ rman_wallet_password }}\n{{ rman_wallet_password }}"
110184
with_items:
111-
- "{{ oracle_databases }}"
112-
when: item.rman_tnsalias is defined
185+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | selectattr('rman_wallet','defined') }}"
186+
loop_control:
187+
label: "{{ item.oracle_db_name | default('') }}"
188+
when: item.rman_wallet
113189
tags:
114190
- wallet
191+
register: wallet_created
192+
193+
- name: List wallet contents
194+
ansible.builtin.shell:
195+
cmd: 'echo "$stdin" | {{ oracle_home_db }}/bin/mkstore -listCredential -nologo -wrl "{{ rman_wallet_loc }}"'
196+
become: true
197+
become_user: "{{ oracle_user }}"
198+
environment:
199+
stdin: "{{ rman_wallet_password }}"
200+
with_items:
201+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | selectattr('rman_wallet','defined') }}"
202+
when:
203+
- item.rman_wallet
204+
- not wallet_created.changed
205+
changed_when: false # does not change anything in System
206+
loop_control:
207+
label: "{{ item.oracle_db_name | default('') }}"
208+
tags:
209+
- wallet
210+
register: wallet_contents
115211

116-
# no_log => secure password against logfiles
117-
# ignore errors during createCredential when entry is existing
118212
- name: Wallet createCredential
119-
ansible.builtin.shell: "echo -e '{{ rman_wallet_password }}' | {{ oracle_home_db }}/bin/mkstore -wrl {{ rman_wallet_loc }} -nologo -createCredential {{ item.rman_tnsalias }} {{ item.rman_user }} {{ item.rman_password }}; exit 0"
120-
# noqa yaml risky-shell-pipe
213+
ansible.builtin.shell:
214+
cmd: 'echo "$stdin" | {{ oracle_home_db }}/bin/mkstore -wrl "{{ rman_wallet_loc }}" -nologo -createCredential "$rman_tnsalias" "$rman_user" "$rman_password"'
121215
become: true
122216
become_user: "{{ oracle_user }}"
123-
no_log: true
217+
environment:
218+
stdin: "{{ rman_wallet_password }}"
219+
rman_tnsalias: "{{ item.rman_tnsalias }}"
220+
rman_user: "{{ item.rman_user }}"
221+
rman_password: "{{ dbpasswords[item.rman_tnsalias][item.rman_user] | default(item.rman_password) }}"
124222
with_items:
125-
- "{{ oracle_databases }}"
126-
when: item.rman_tnsalias is defined and item.rman_user is defined and item.rman_password is defined
223+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | selectattr('rman_wallet','defined') }}"
224+
when:
225+
- item.rman_wallet
226+
- "wallet_created.changed or ((': ' + item.rman_tnsalias + ' ' + item.rman_user) not in (wallet_contents.results[loopidx].stdout | default('')))"
227+
loop_control:
228+
label: "{{ item.oracle_db_name | default('') }}"
229+
index_var: loopidx
230+
register: wallet_credential_added
231+
tags:
232+
- wallet
233+
234+
- name: Wallet modifyCredential to ensure password is up to date
235+
ansible.builtin.shell:
236+
cmd: 'echo "$stdin" | {{ oracle_home_db }}/bin/mkstore -wrl "{{ rman_wallet_loc }}" -nologo -modifyCredential "$rman_tnsalias" "$rman_user" "$rman_password"'
237+
become: true
238+
become_user: "{{ oracle_user }}"
239+
changed_when: false # no simple way to figure out whether this changed the password or not, does not matter.
240+
environment:
241+
stdin: "{{ rman_wallet_password }}"
242+
rman_tnsalias: "{{ item.rman_tnsalias }}"
243+
rman_user: "{{ item.rman_user }}"
244+
rman_password: "{{ dbpasswords[item.rman_tnsalias][item.rman_user] | default(item.rman_password) }}"
245+
with_items:
246+
- "{{ oracle_databases | selectattr('rman_tnsalias','defined') | selectattr('rman_wallet','defined') }}"
247+
when:
248+
- item.rman_wallet
249+
- not wallet_created.changed
250+
- not wallet_credential_added.changed
251+
loop_control:
252+
label: "{{ item.oracle_db_name | default('') }}"
127253
tags:
128254
- wallet
129255

@@ -133,8 +259,8 @@
133259
# The task is only execute once on master_node when GI is installed!
134260
# no catalog connection, because setting initial parameters with catalog takes much more time
135261
- name: Execute RMAN-Script at playbook
262+
# noqa risky-shell-pipe
136263
ansible.builtin.shell: "{{ oracle_base }}/bin/rman_backup.sh -a {{ item.1.name }} -s {{ item.0.oracle_db_instance_name | default(item.0.oracle_db_name) }} -r {{ rman_script_dir }} -l {{ rman_log_dir }} | tee -a {{ rman_cron_logdir }}/rman_{{ item.1.name }}.log"
137-
# noqa risky-shell-pipe yaml
138264
environment:
139265
PATH: /bin:/usr/bin
140266
become: true
@@ -146,23 +272,25 @@
146272
- skip_missing: true
147273
loop_control:
148274
label: "oracle_db_name {{ item.0.oracle_db_name | default('') }} job {{ item.1.name | default('') }}"
149-
when: item.1.immediate is defined and item.1.immediate
150-
and ( (configure_cluster and inventory_hostname == cluster_master)
151-
or not configure_cluster
152-
)
275+
when:
276+
- item.1.immediate is defined
277+
- item.1.immediate
278+
- "((configure_cluster and inventory_hostname == cluster_master) or not configure_cluster )"
153279
tags:
154280
- rmanexecute
155281

156-
- ansible.builtin.debug: msg={{ item.results.stdout_lines | default("") }} # noqa unnamed-task
282+
- name: RMAN-Script at playbook output # noqa no-handler
283+
ansible.builtin.debug:
284+
msg: "{{ item.stdout_lines }}"
157285
with_items:
158-
- "{{ rmanexecimmediate }}"
286+
- "{{ rmanexecimmediate.results }}"
287+
when: item.changed
159288
loop_control:
160-
label: ""
161-
when: rmanexecimmediate is defined
289+
label: "oracle_db_name {{ item.item[0].oracle_db_name | default(' ') }} job {{ item.item[1].name | default('') }}"
162290
tags:
163291
- rmanexecute
164292

165-
- name: Add Environment variables to /ec/cron.d
293+
- name: Add Environment variables to /etc/cron.d
166294
ansible.builtin.cron:
167295
cron_file: "{{ rman_cronfile }}"
168296
user: "{{ oracle_user }}"
@@ -206,6 +334,10 @@
206334
- rmancron
207335

208336
- name: Create directory for mk-job
209-
ansible.builtin.file: dest=/var/lib/check_mk_agent/job/{{ oracle_user }} state=directory owner={{ oracle_user }} mode=0755
337+
ansible.builtin.file:
338+
dest: "/var/lib/check_mk_agent/job/{{ oracle_user }}"
339+
state: directory
340+
owner: "{{ oracle_user }}"
341+
mode: '0755'
210342
when: rman_cron_mkjob
211343
tags: rmancron

0 commit comments

Comments
 (0)