Hey there Dermot and welcome to the Trigger community!
The default for Juniper devices is to use Junoscript.This was the original way that this was implemented in Trigger, so that's why it's not the default and in order to get CLI output you need to pass force_cli=True.
The Element object you see there is from the xml.etree.ElementTree library that comes with Python. This makes it very easy to iterate through results using XSLT. But if you want to get at the raw XML it's not terribly hard.
The quickest and easiest way is this (ran against an SRX 210 I have on my home network):
In [1]: from trigger.cmds import Commando
In [2]: c = Commando(devices=['192.168.0.202'], commands=['show version'])
In [3]: c.run()
In [4]: c.results
Now here is where you use ElementTree.tostring() method to dump the raw XML:
In [5]: import xml.etree.ElementTree as ET
In [6]: ET.tostring(c.results['192.168.0.202']['show version'])
Out[6]: '<ns0:roc-reply xmlns:ns0="http://xml.juniper.net/xnm/1.1/xnm">\n<ns0:software-information>\n<ns0:host-name>srx</ns0:host-name>\n<ns0:product-model>srx210h</ns0:product-model>\n<ns0:product-name>srx210h</ns0:product-name>\n<ns0:jsr />\n<ns0:package-information>\n<ns0:name>junos</ns0:name>\n<ns0:comment>JUNOS Software Release [12.1X44-D15.5]</ns0:comment>\n</ns0:package-information>\n</ns0:software-information>\n</ns0:rpc-reply>'
Or you can use .dump() to just print it to stdout:
In [12]: data = c.results['192.168.0.202']['show version']
In [13]: ET.dump(data)
<ns0:software-information>
<ns0:host-name>srx</ns0:host-name>
<ns0:product-model>srx210h</ns0:product-model>
<ns0:product-name>srx210h</ns0:product-name>
<ns0:jsr />
<ns0:package-information>
<ns0:name>junos</ns0:name>
<ns0:comment>JUNOS Software Release [12.1X44-D15.5]</ns0:comment>
</ns0:package-information>
</ns0:software-information>
</ns0:rpc-reply>
Of course working with XML with namespaces immediately becomes obviously horrible and ugly. There are some utilities within the Trigger libs that make this a little easier but it's not quite user-friendly just yet, but here they are. We're working on simplifying a lot of this end-user experience as we approach Trigger 2.0, so please keep this in mind. We're aware of the pain, too!
So here goes... First you want to import trigger.utils.xmltodict, and then you also want trigger.utils.strip_juniper_namespace. Then you can use these together to convert the XML to a Python dictionary and walk through the Juniper configuration logically and naturally. So we'll use the data variable we defined above that references the XML ElementTree object:
And then import those 2 functions I referenced above (trigger.utils.xmltodict and trigger.utils.strip_juniper_namespace):
In [31]: from trigger.utils import xmltodict
In [32]: from trigger.utils import strip_juniper_namespace
And then use xmltodict.parse with strip_juniper_namespace as a post-processor (This isn't really well documented right now so you'll have to trust me):
In [33]: xmltodict.parse(ET.tostring(data), postprocessor=strip_juniper_namespace)
Out[33]: OrderedDict([(u'rpc-reply', OrderedDict([(u'@xmlns:ns0', u'http://xml.juniper.net/xnm/1.1/xnm'), (u'software-information', OrderedDict([(u'host-name', u'srx'), (u'product-model', u'srx210h'), (u'product-name', u'srx210h'), (u'jsr', None), (u'package-information', OrderedDict([(u'name', u'junos'), (u'comment', u'JUNOS Software Release [12.1X44-D15.5]')]))]))]))])
You see it returns an OrderedDict, so let's capture that in a variable and then reference the "software-information/package-information/comment" key that includes the software version (it took me a few tries to remember the nested elements including "roc-reply"):
In [37]: xml_dict['rpc-reply']['software-information']['package-information']['comment']
Out[37]: u'JUNOS Software Release [12.1X44-D15.5]'
That's all for now. I hope this helps you! Please consider joining us on IRC if you can at #trigger on
irc.freenode.net!
Cheers!
jathan.