Files
programming/ansible/swgalaxy/playbooks/ora_stand_datapatch.yml
T

294 lines
10 KiB
YAML
Raw Normal View History

2026-06-28 12:00:23 +02:00
---
# Playbook: ora_stand_datapatch.yml
# Usage example:
# ansible-playbook playbooks/ora_stand_datapatch.yml \
# -e server=togoria \
# -e oracle_sid=NABOOPRD
- name: Gather facts for a specific inventory host
hosts: "{{ server }}"
gather_facts: yes
become: true
become_user: oracle
become_method: su
pre_tasks:
- name: Ensure 'server' variable is provided
assert:
that: server is defined
fail_msg: "Please provide the server via -e 'server=<server>'"
- name: Ensure 'oracle_sid' variable is provided
assert:
that: oracle_sid is defined
fail_msg: "Please provide the oracle_sid via -e 'oracle_sid=<oracle_sid>'"
tasks:
- name: Show selected system facts
debug:
msg:
hostname: "{{ (ansible_facts.nodename | default(ansible_facts.hostname)) | default('unknown') }}"
os_family: "{{ ansible_facts.os_family | default(ansible_facts.distribution | default('unknown')) }}"
operating_system: "{{ ansible_facts.distribution | default('unknown') }} {{ ansible_facts.distribution_version | default('') }}"
ip_address: "{{ ansible_default_ipv4.address | default('unknown') }}"
hardware_model: "{{ ansible_facts['machine'] | default('unknown') }}"
cpu_count: "{{ ansible_facts['processor_vcpus'] | default(ansible_facts['processor_count'] | default('unknown')) }}"
ram_gb: "{{ (ansible_facts['memtotal_mb'] / 1024) | int | default('unknown') }}"
- name: Source oraenv and display OPatch informations
shell: |
. oraenv <<< {{ oracle_sid }} && $ORACLE_HOME/OPatch/opatch version && echo && echo && $ORACLE_HOME/OPatch/opatch lspatches
register: opatch_output
when: oracle_sid is defined
- name: Display OPatch output
debug:
var: opatch_output.stdout_lines
when: oracle_sid is defined
- name: Check Oracle instance status via sqlplus as SYSDBA
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
set heading off feedback off verify off pagesize 0
select status from v$instance;
exit
SQL
register: instance_status
changed_when: false
when: oracle_sid is defined
- name: Show Oracle instance status
debug:
msg: "Oracle instance {{ oracle_sid }} status: {{ instance_status.stdout | trim | default('unknown') }}"
when: oracle_sid is defined
- name: Fail if Oracle instance is not OPEN
fail:
msg: "Oracle instance {{ oracle_sid }} is not OPEN (status: {{ instance_status.stdout | default('unknown') }})"
when: oracle_sid is defined and ("OPEN" not in (instance_status.stdout | default('')))
- name: List PDBs (if multitenant)
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
set heading off feedback off verify off pagesize 0
2026-06-28 21:28:40 +02:00
select name||':'||open_mode||':'||restricted from v$pdbs where name!='PDB$SEED';
2026-06-28 12:00:23 +02:00
exit
SQL
register: pdb_list
failed_when: false
changed_when: false
when: oracle_sid is defined
- name: Determine if database is multitenant
set_fact:
is_multitenant: "{{ (pdb_list.stdout is defined) and ('ORA-' not in pdb_list.stdout) and (pdb_list.stdout | trim != '') }}"
when: oracle_sid is defined
- name: Show PDB list (if multitenant)
debug:
2026-06-28 21:28:40 +02:00
msg: |
PDB, OPEN, RESTRICTED
{% for pdb in pdb_list.stdout_lines %}
{{ pdb }}
{% endfor %}
2026-06-28 12:00:23 +02:00
when: oracle_sid is defined and is_multitenant
2026-06-28 21:28:40 +02:00
- name: Check for non-OPEN PDBs or RESTRICTED PDBs
2026-06-28 12:00:23 +02:00
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
set heading off feedback off verify off pagesize 0
2026-06-28 21:28:40 +02:00
select name||':'||open_mode||':'||restricted from v$pdbs where name!='PDB$SEED' and (upper(open_mode) not like '%READ WRITE%' or upper(restricted) = 'YES');
2026-06-28 12:00:23 +02:00
exit
SQL
register: pdb_not_open
failed_when: false
changed_when: false
when: oracle_sid is defined and is_multitenant
- name: Filter non-empty PDB results
set_fact:
pdb_not_open_filtered: "{{ pdb_not_open.stdout_lines | select('match', '^.+:.+$') | list }}"
when: oracle_sid is defined and is_multitenant
- name: Fail if any PDB is not OPEN
fail:
msg: "PDB(s) not OPEN: {{ pdb_not_open_filtered }}"
when: oracle_sid is defined and is_multitenant and (pdb_not_open_filtered | length) > 0
2026-06-28 21:28:40 +02:00
- name: Execute datapatch
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/OPatch/datapatch
register: datapatch_output
changed_when: false
when: oracle_sid is defined
- name: Show datapatch output
debug:
var: datapatch_output.stdout_lines
when: oracle_sid is defined
- name: Remove temporary SQL files from remote host
file:
path: "{{ item }}"
state: absent
loop:
- /tmp/dba_invalid_objects.sql
- /tmp/dba_registry.sql
when: oracle_sid is defined
- name: Execute utlrp.sql in CDB$ROOT
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
@$ORACLE_HOME/rdbms/admin/utlrp.sql
exit
SQL
register: utlrp_root
changed_when: false
when: oracle_sid is defined
- name: Get list of PDBs for utlrp execution
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
set heading off feedback off verify off pagesize 0
select name from v$pdbs where name!='PDB$SEED' and open_mode like '%READ WRITE%' and restricted='NO';
exit
SQL
register: pdb_names
failed_when: false
changed_when: false
when: oracle_sid is defined and is_multitenant
- name: Execute utlrp.sql in each PDB
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
alter session set container={{ item | trim }};
@$ORACLE_HOME/rdbms/admin/utlrp.sql
exit
SQL
loop: "{{ pdb_names.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
register: utlrp_pdb_results
changed_when: false
failed_when: false
when: oracle_sid is defined and is_multitenant and (pdb_names.stdout_lines | default([]) | length) > 0
- name: Copy dba_invalid_objects.sql to remote host
copy:
src: ../files/scripts/sql/dba_invalid_objects.sql
dest: /tmp/dba_invalid_objects.sql
mode: '0644'
when: oracle_sid is defined
- name: Copy dba_registry.sql to remote host
copy:
src: ../files/scripts/sql/dba_registry.sql
dest: /tmp/dba_registry.sql
mode: '0644'
when: oracle_sid is defined
- name: Execute dba_invalid_objects.sql in CDB$ROOT
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
@/tmp/dba_invalid_objects.sql
exit
SQL
register: dba_invalid_root
changed_when: false
when: oracle_sid is defined
- name: Show dba_invalid_objects.sql results in CDB$ROOT
debug:
var: dba_invalid_root.stdout_lines
when: oracle_sid is defined
- name: Execute dba_registry.sql in CDB$ROOT
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
@/tmp/dba_registry.sql
exit
SQL
register: dba_registry_root
changed_when: false
when: oracle_sid is defined
- name: Show dba_registry.sql results in CDB$ROOT
debug:
var: dba_registry_root.stdout_lines
when: oracle_sid is defined
- name: Execute dba_invalid_objects.sql in each PDB
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
alter session set container={{ item | trim }};
@/tmp/dba_invalid_objects.sql
exit
SQL
loop: "{{ pdb_names.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
register: dba_invalid_pdb_results
changed_when: false
failed_when: false
when: oracle_sid is defined and is_multitenant and (pdb_names.stdout_lines | default([]) | length) > 0
- name: Show dba_invalid_objects.sql results in PDBs
debug:
msg: |
dba_invalid_objects.sql output for PDB: {{ item }}
{{ dba_invalid_pdb_results.results[pdb_names.stdout_lines.index(item)].stdout }}
loop: "{{ pdb_names.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
when: oracle_sid is defined and is_multitenant and (pdb_names.stdout_lines | default([]) | length) > 0
- name: Execute dba_registry.sql in each PDB
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
$ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL'
alter session set container={{ item | trim }};
@/tmp/dba_registry.sql
exit
SQL
loop: "{{ pdb_names.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
register: dba_registry_pdb_results
changed_when: false
failed_when: false
when: oracle_sid is defined and is_multitenant and (pdb_names.stdout_lines | default([]) | length) > 0
- name: Show dba_registry.sql results in PDBs
debug:
msg: |
dba_registry.sql output for PDB: {{ item }}
{{ dba_registry_pdb_results.results[pdb_names.stdout_lines.index(item)].stdout }}
loop: "{{ pdb_names.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
when: oracle_sid is defined and is_multitenant and (pdb_names.stdout_lines | default([]) | length) > 0
- name: Remove temporary SQL files from remote host
file:
path: "{{ item }}"
state: absent
loop:
- /tmp/dba_invalid_objects.sql
- /tmp/dba_registry.sql
when: oracle_sid is defined