delphix / ansible-target-host

Ansible role for configuring target hosts for use by the Delphix platform
https://galaxy.ansible.com/delphix/target-host
Apache License 2.0
4 stars 1 forks source link

Use XML parsing to read Oracle Inventory #8

Open Ranzo3 opened 4 years ago

Ranzo3 commented 4 years ago

Is your feature request related to a problem? Please describe. It's surprisingly difficult to parse inventory.xml with Ansible. The "xml" module has a requirement on the remote host for lxml, which could be difficult to get in customer situations. Slurping and using "xml" module as a local task ("delegate 127.0.0.1") ran into OSX issues: a change to sudoers was needed and even after "pip install xml" I encoutered issues like https://github.com/cmprescott/ansible-xml/issues/51

A solution would look something like this:

- name: Slurp inventory
  slurp:
    src: "{{ oraInst.stdout }}/ContentsXML/inventory.xml"
  register: existing_dbhome

- debug:
    msg: "{{ existing_dbhome['content'] | b64decode }}"
    verbosity: 2

- name: Parse inventory
  xml:
#    path: /u01/app/oraInventory/ContentsXML/inventory.xml
    xmlstring: "{{ existing_dbhome['content'] | b64decode }}"
    xpath: /INVENTORY/HOME_LIST/HOME
    content: attribute
  delegate_to: 127.0.0.1  #Avoid issues where the remote host doesn't have lxml module and it's difficult to modify the server in that way
  register: existing_dbhome

- debug: var=existing_dbhome.matches

To workaround these issues, the current code uses a complex shell command. This feels fragile:

- name: Parse inventory
  shell: cat "{{ oraInst.stdout }}/ContentsXML/inventory.xml" |grep "HOME NAME" | grep -vi "CRS=" | grep -vi "REMOVED=" | awk '{print $3}' | awk -F"=" '{print $2}'  | tr -d '"'
  register: existing_dbhome
Ranzo3 commented 4 years ago

If we go with the local approach, we should put some helpful tips for our users who are on Mac, like using brew and following guidelines here: https://opensource.com/article/19/5/python-3-default-mac#what-to-do.

FedeHAL commented 3 years ago

Hi, I use the following code to read an Oracle Inventory file and parse it to select a database home for example.

- name: Get inventory location
  shell: "grep inventory_loc /etc/oraInst.loc|cut -d '=' -f2|awk '{print $1}'"
  register: OraInvloc
  tags: always
  changed_when: false

- name: Read Oracle homes from inventory
  xml:
    path: "{{ OraInvloc.stdout|trim }}/ContentsXML/inventory.xml"
    xpath: "/INVENTORY/HOME_LIST/HOME"
    content: attribute
  tags: always
  register: oraHomes
  changed_when: false

- name: Read Oracle home information
  xml:
    path: "{{ item.HOME.LOC }}/inventory/ContentsXML/comps.xml"
    xpath: "/PRD_LIST/TL_LIST/COMP/EXT_NAME"
    content: text
  tags: always
  register: xmloraHomes
  loop: "{{ oraHomes.matches }}"
  loop_control:
    label: "{{ item.HOME.LOC|default('NOTDEFINED') }}"
  when: "item.HOME.REMOVED is not defined"
  changed_when: false

- name: Select Oracle home
  set_fact:
    oracle_home: "{{ item.item.HOME.LOC }}"
  loop: "{{ xmloraHomes.results }}"
  loop_control:
    label: "{{ item.item.HOME.LOC|default('NOTDEFINED') }}"
  when: "item.matches is defined and 'Oracle Database' in item.matches[0].EXT_NAME"
  tags: always

Hope it helps. Regards,

arkzoidal commented 2 years ago

Great , thank you