09-18-2019 06:50 AM
The below is a modification to the CDB that we use for if a command is supported or not by a device. I would like to perform an xpath eval on the below, without having to specify the interface, Vlan{1}, in the keypath. Is there a way that I can use a wildcard for part of the 'name' leaf in the xpath eval? I would like to use these lookups in my XML template, not just for viewing as I have shown below.
You can see that with the full 'name' leaf filled out I get a response back with one of the entries, but any attempt to use a wildcard, *, character fails.
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan{*}/ipv6/flow/monitor{input}/name']
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/Vlan/ipv6/flow/monitor{input}/name']
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[name='ios:interface/*/ipv6/flow/monitor{input}/name']
Any thoughts on how I can have part of a leaf value in a xpath eval be wildcard?
Solved! Go to Solution.
09-18-2019 09:32 AM
Okay, I don't think I knew about some of the xpath functions that existed. After seeing the starts-with, it looks like I can use that and a contains to accomplish what I'm after. Wish it was a little more direct, but this will work.
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[starts-with(.,'ios:interface/Vlan')][contains(.,'/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{output}/name']
09-18-2019 07:47 AM
09-18-2019 08:09 AM
I know that I can omit the filter, but there are other 'name's, such as 'ios:flow/record', 'ios:flow/exporter', etc.
I would like to just grab all of the ones with interface in the text, or a specific interface type. I know that for just doing an xpath eval I could do a `| include interface` to help accomplish this, however I am using these xpath lookups in my XML template in an <?if?> statement to see if the command is supported or not, so I am unable to use the pipe command.
Example from the XML template:
<?if {not(/config-support[device-name=$DEVICE_NAME]/keypath[name="ios:flow/record\{DISCOVERY-UNUSED-RECORD\}/collect/datalink/mac/source/address/input"]/support = 'false')}?>
<input/>
<?end?>
I would like to do something like that for the monitor as well, however the name is interface value specific, in the below case I want just Vlan, not Vlan{1} specific.
<Vlan>
<name>{./name}</name>
<ip>
<flow tags="merge">
<?if {not(/config-support[device-name=$DEVICE_NAME]/keypath[name="ios:interface/Vlan{1}/ipv6/flow/monitor\{input\}/name"]/support = 'false')}?>
<monitor>
<name>{$PREPEND_FLOW_NAME}-IPV4-MONITOR-IN</name>
<direction>input</direction>
</monitor>
<?end?>
09-18-2019 08:32 AM
09-18-2019 09:32 AM
Okay, I don't think I knew about some of the xpath functions that existed. After seeing the starts-with, it looks like I can use that and a contains to accomplish what I'm after. Wish it was a little more direct, but this will work.
admin@nso(config)# xpath eval /config-support[device-name='device1']/keypath[starts-with(.,'ios:interface/Vlan')][contains(.,'/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{input}/name']
/config-support[device-name='device1']/keypath[name='ios:interface/Vlan{1}/ipv6/flow/monitor{output}/name']
09-18-2019 10:07 AM
09-18-2019 10:48 AM
config-support is a CDB modification we've made to the CDB for being able to store if configuration is supported on the device. The cisco-ios NED does not have the intelligence to determine if a device supports a command or not, so if I push a command to the device that it doesn't support in of our services, it will fail the deployment, and we'd have to modify the service or just not deploy it. This is for enterprise deployments of things like NTP, NetFlow, etc.
Some examples, ntp update-calendar is hardware reliant, some devices and other don't. The NED has no intelligence to determine this. We started with hard coding the models that don't support. Now with NetFlow, it's not just model, but also OS, and even license. Once again, no intelligence from the NED to deal with this, so we built a tool to automate checking if it's supported and storing it in the CDB (config-support), then we just do an xpath lookup in the XML template and if the entry exists with a support='false', we don't deploy that command.
This is an enterprise issue for a large brown field of Cisco devices. For example, inside of flexible NetFlow, it was 50% of the devices that supported flexible NetFlow supported certain collect commands. So we want to push what we can to the devices as we can. Pretty cool tool, but got stuck on these XPath lookups.
Thanks for you help.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide