whyduck
whyduck

Reputation: 53

Ansible yaml to xml

I am trying to create xml file with yaml playbook. XML should looks like this:

<accessControl>
  <ipRanges>
    <ipRange>
      <ip>
        <int>00</int>
        <int>00</int>
        <int>00</int>
        <int>000</int>
      </ip>
      <mask>
        <int>255</int>
        <int>255</int>
        <int>255</int>
        <int>0</int>
      </mask>
    </ipRange>
    <null/>
  </ipRanges>
</accessControl>

I have no idea how to create ansible task providing multiple identical tags (< int >). I am looking for something loop like or there is another way?

Edit: I.E I have XML like this:

<accessControl>
  <ipRanges>
    <ipRange>
    </ipRange>
    <null/>
  </ipRanges>
</accessControl>

And I need to add IP and MASK into tag to achieve:

<accessControl>
  <ipRanges>
    <ipRange>
      <ip>
        <int>127</int>
        <int>0</int>
        <int>0</int>
        <int>1</int>
      </ip>
      <mask>
        <int>255</int>
        <int>255</int>
        <int>255</int>
        <int>0</int>
      </mask>
    </ipRange>
    <null/>
  </ipRanges>
</accessControl>

I can provide IP and Mask in list, dict, tuple - it does not matter. For a sake of this question lets say it will be like this: ['127.0.0.1', '255.255.255.0']

Upvotes: 2

Views: 713

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68024

For example, given the data

ip: ['127.0.0.1', '255.255.255.0']

the template

shell> cat test.xml.j2
<accessControl>
  <ipRanges>
    <ipRange>
      <ip>
{% for item in ip %}
{% if loop.index is odd %}
{% for i in item.split('.') %}
        <int>{{ i }}</int>
{% endfor %}
{% endif %}
{% endfor %}
      </ip>
      <mask>
{% for item in ip %}
{% if loop.index is even %}
{% for i in item.split('.') %}
        <int>{{ i }}</int>
{% endfor %}
{% endif %}
{% endfor %}
      </mask>
    </ipRange>
    <null/>
  </ipRanges>
</accessControl>

and the task

    - template:
        src: test.xml.j2
        dest: test.xml

give

shell> cat test.xml
<accessControl>
  <ipRanges>
    <ipRange>
      <ip>
        <int>127</int>
        <int>0</int>
        <int>0</int>
        <int>1</int>
      </ip>
      <mask>
        <int>255</int>
        <int>255</int>
        <int>255</int>
        <int>0</int>
      </mask>
    </ipRange>
    <null/>
  </ipRanges>
</accessControl>

You can use slice notation instead of even/odd index testing

      <ip>
{% for item in ip[0::2] %}
{% for i in item.split('.') %}
        <int>{{ i }}</int>
{% endfor %}
{% endfor %}
      </ip>
      <mask>
{% for item in ip[1::2] %}
{% for i in item.split('.') %}
        <int>{{ i }}</int>
{% endfor %}
{% endfor %}
      </mask>

Upvotes: 2

Related Questions