Question

I am using the Augeas tool for Puppet 3.2 and I am trying to create an XML file. I want to be able to add multiple fields with the same name into my XML doc. For instance, I want to separate node2/location2 from node1/location1 by placing it in its own "node" field. This is my code:

    augeas { "update template":
        lens    => "Xml.lns",
        require => File["${buildpath}/tempfile.xml"],
        incl => "${buildpath}/tempfile.xml",
        changes => [
            "set member/acceptors[#attribute]/node[#attribute]/nodeIdentity[#attribute]/#text node2",
            "set member/acceptors/node/nodeLocation[#attribute]/#text location2",
            "set member/acceptors/node/nodeIdentity[#attribute]/#text node1",
            "set member/acceptors/node/nodeLocation[#attribute]/#text location1"
        ],
   }

This is the XML output that I get:

    <member>
        <acceptors>
            <node>
                <nodeIdentity>node2</nodeIdentity>
                <nodeLocation>location2</nodeLocation>
                <nodeIdentity>node1</nodeIdentity>
                <nodeLocation>location1</nodeLocation>
            </node>
        </acceptors>
    </member>

This is the output I want:

    <member>
        <acceptors>
            <node>
                <nodeIdentity>node2</nodeIdentity>
                <nodeLocation>location2</nodeLocation>
            </node>
            <node>
                <nodeIdentity>node1</nodeIdentity>
                <nodeLocation>location1</nodeLocation>
            </node>
        </acceptors>
    </member>

I have tried adding [#attribute] to the node1 line like the following:

     "set member/acceptors/node[#attribute]/nodeIdentity[#attribute]/#text node1",

But "node1" doesn't get outputted. Any suggestions?

Was it helpful?

Solution

You need to specify the node you want to impact with the XPath expression. In your case, you can write an idempotent change by doing this:

augeas { "update template":
     lens    => "Xml.lns",
     require => File["${buildpath}/tempfile.xml"],
     incl    => "${buildpath}/tempfile.xml",
     changes => [
         "set member/acceptors/node[nodeIdentity/#text='node2']/nodeIdentity/#text node2",
         "set member/acceptors/node[nodeIdentity/#text='node2']/nodeLocation/#text location2",
         "set member/acceptors/node[nodeIdentity/#text='node1']/nodeIdentity/#text node1",
         "set member/acceptors/node[nodeIdentity/#text='node1']/nodeLocation/#text location1"
     ],
}

There is no need (that I see) to filter on the existence of #attribute sub-nodes, all the more that you don't create them, so you're changes won't be idempotent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top