Skip to content

Instantly share code, notes, and snippets.

@benbramley
Created March 20, 2015 05:16
Show Gist options
  • Save benbramley/df51c2548ff8ceeafa5b to your computer and use it in GitHub Desktop.
Save benbramley/df51c2548ff8ceeafa5b to your computer and use it in GitHub Desktop.
Ansible lookup plugin for XML files
from ansible import utils, errors
import os
import xml.etree.ElementTree as etree
class LookupModule(object):
def __init__(self, basedir=None, **kwargs):
self.basedir = basedir
def tostr(self, node):
if isinstance(node, etree._Element):
if len(node.getchildren()) == 0:
return node.text
return etree.tostring(node)
return str(node)
def read_xml(self, filename, dflt=None, xpath=None):
try:
xmlreader = etree.parse(filename)
nodes = xmlreader.findall(xpath)
values = [self.tostr(node) for node in nodes]
return values
except Exception, e:
raise errors.AnsibleError("xmlfile: %s" % str(e))
return dflt
def run(self, terms, inject=None, **kwargs):
terms = utils.listify_lookup_plugin_terms(terms, self.basedir, inject)
if isinstance(terms, basestring):
terms = [ terms ]
ret = []
for term in terms:
params = term.split()
key = params[0]
paramvals = {
'file' : 'ansible.xml',
'default' : None,
'xpath' : None,
}
# parameters specified?
try:
for param in params:
name, value = param.split('=')
assert(name in paramvals)
paramvals[name] = value
except (ValueError, AssertionError), e:
raise errors.AnsibleError(e)
path = utils.path_dwim(self.basedir, paramvals['file'])
var = self.read_xml(path, paramvals['default'], paramvals['xpath'])
if var is not None:
if type(var) is list:
for v in var:
ret.append(v)
else:
ret.append(var)
return ret
@benbramley
Copy link
Author

Example usage:

- hosts: local
  vars:
     buildtimestamp: "{{ lookup('xmlfile', 'file=/tmp/maven-metadata.xml xpath=./versioning/snapshot/timestamp') }}"
     buildnumber: "{{ lookup('xmlfile', 'file=/tmp/maven-metadata.xml xpath=./versioning/snapshot/buildNumber') }}"

  tasks:

     - debug: msg="the build version is {{ buildnumber }} created at {{ buildtimestamp }}"

@Lx
Copy link

Lx commented May 2, 2015

Reminder for anyone else coming across this:

Lookups occur on the local computer, not on the remote computer.

If you're looking for a way to retrieve XML values from the remote side, the best available thing at this time seems to be RHInception's ansible-xml module (although value lookup is neither explicitly documented nor necessarily actually supported yet).

@tbielawa
Copy link

Update, that issue @Lx linked 404's now. Here's the updated URL: cmprescott/ansible-xml#14

@mihai-satmarean
Copy link

This is very nice, any example how can we take a specific attribute or value from the xml?
EG <Site Name="MySite"> Loading time</>
We would like to get the site name.
Thank you!

@danieldbower
Copy link

You wouldn't happen to have a version that is compatible with version 2.0 of Ansible would you?

@danieldbower
Copy link

I created a version for Ansible 2.0 based off of yours that should function the same: https://gist.github.com/danieldbower/7b34c45ad5e39576e2e5

@akhilputhiry
Copy link

in case some one want to perform lookup using ansible-xml

- name: playing with ansible xml
    xml:
      path: /root/akhil/config.xml
      xpath: //name[text()='hive.cli.print.header']/../value
      content: text
    register: header_value
   
  - name: debug hits
    debug:
      msg: "var hits = {{ header_value.matches[0].value }}"

reference - https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/files/xml.py#L181

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment