Identifiers are used as unique keys to differentiate between two otherwise identical configuration stanzas. For example, consider the <interfaces> hierarchy, which can, and almost always does, contain multiple instances of <interface> child elements, with each of these elements being distinguished by an identifier element named <name>.
Most identifiers are conveniently named <name>, making it easy to identify the majority of identifiers by simply scanning for elements with a name of "name". This is how the jcs:emit-change template builds its change configuration hierarchies. It is provided a chunk of configuration XML along with a reference point, and it then adds the ancestors of that structure backwards, pulling out and including <name> identifiers as it goes.
Now, if all identifiers were named "name", then there would be no need for this article, but they are not. Other identifier elements include: <from-zone-name>, <to-zone-name>,<neighbor-id>, <transit-area>, and so on, and any configuration change made within one of these hierarchies, which have non-"name" identifiers, must include the identifiers in order to be valid. However, the problem is that there is no indication given within the configuration XML itself whether a particular element is an identifier or not.
Why is this a problem? Well, return to the jcs:emit-change example and assume that you want to make a change within a security policy. You would provide the code chunk to jcs:emit-change, which would happily generate a <change> element for you, and Junos OS would just as happily fail your commit with an error message.
Why? Because the generated <change> element would be invalid because that jcs:emit-change had no idea that <from-zone-name> and <to-zone-name> were identifiers and needed to be included. Now, it might be possible to go through and manually identify every single non-name identifier possible in the configuration and hard-code that into your script, but what happens if the next Junos OS version adds a new one? Is that a commitment you really want to make?
Ultimately, we need a mechanism that informs scripts whether an element is an identifier or not. This would ideally be included as an attribute of <get-configuration>, allowing you to specify whether you want identifiers identified or not. This is being requested by PR 492912, which has yet to see a fix.
In the meantime, here is a workaround that could be useful in some scenarios, but not all. The "| display xml" CLI pipe has an undocument option that can be appended, "junos-key", and if you include that option then you will get output like this:
01 jnpr@srx210> show configuration interfaces ge-0/0/0 | display xml junos-key
02 <rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.1D0/junos">
03 <configuration junos:commit-seconds="1327137218" junos:commit-localtime="2012-01-21 09:13:38 UTC" junos:commit-user="jnpr">
06 <name junos:key="key">ge-0/0/0</name>
08 <name junos:key="key">0</name>
12 <name junos:key="key">10.0.0.10/24</name>
This can be leveraged within a script as well, using code such as below:
1 var $rpc = <command> "show configuration security policies | display xml junos-key";
2 var $results = jcs:invoke( $rpc );
Here is the returned XML content:
06 <configuration xmlns:junos="http://xml.juniper.net/junos/*/junos" junos:commit-seconds="1327137218" junos:commit-localtime="2012-01-21 09:13:38 UTC" junos:commit-user="jnpr">
10 <from-zone-name junos:key="key">trust</from-zone-name>
11 <to-zone-name junos:key="key">trust</to-zone-name>
13 <name junos:key="key">example</name>
15 <source-address junos:key="key">any</source-address>
16 <destination-address junos:key="key">any</destination-address>
17 <application junos:key="key">any</application>
As you can see, all of the identifiers are now tagged with the junos:key attribute, making it possible to identify them through an attribute check (@junos:key).