Search code examples
xmlansiblefirewall

Problem parsing XML output using community XML module in Ansible


I have a string of output from a query I have ran against a firewall. When I try to parse the string using the community XML module, I am getting an output of:

fatal: [hostname]: FAILED! => {"changed": false, "msg": "Error while parsing document: xml_string (Start tag expected, '<' not found, line 1, column 1 (<string>, line 1))"}

From:

    - name: Gather allocated number of addresses for LAN interface...
      community.general.xml:
        xmlstring: ethernet1-1_output.content
        xpath: "/x:response/x:result/x:interface[@name='allocated']"
      register: allocated_ethernet1-1

I have debugged my input and it does seem to be valid XML according to VS.Code. But there are extra characters I think Ansible is adding that might be giving it a problem.

<response status=\"success\">
    <result>
        <interface name=\"ethernet1/1\" id=\"258\" allocated=\"40\" total=\"150\">
            <entry name=\"10.10.10.10\">\n

Is there a way to get a more 'unmodified' output from an API query? Or an easier way to format this to be more module-readable? The goal is to grab the allocated and total values as separate numbers.


Solution

  • It looks like you simply forgot to surround your variable name with curly braces, so Ansible interprets ethernet1-1_output.content as a string. You should use Jinja2 templating instead to reference a variable:

        - name: Gather allocated number of addresses for LAN interface...
          community.general.xml:
            xmlstring: "{{ ethernet1-1_output.content }}"
            xpath: "/x:response/x:result/x:interface[@name='allocated']"
          register: allocated_ethernet1-1
    

    But there are extra characters I think Ansible is adding that might be giving it a problem.

    Is there a way to get a more 'unmodified' output from an API query? Or an easier way to format this to be more module-readable?

    Ansible does not add any extra characters. The output you've posted is probably copied from a debug task console output, isn't it? By default, Ansible outputs the task execution results as JSON, so any double quotes or control characters should be escaped. To have more human-readable console output, you can use community.general.yaml stdout callback or setting callback_result_format = yaml for the default callback (note that these two options are not equal):

    ; ansible.cfg
    
    [defaults]
    callback_result_format = yaml
    stdout_callback = community.general.yaml
    

    Using these, Ansible will log the variables "as is" to console. Note that is does not affect the way how the variable values are interpreted internally.