Juniper router 'show chassis hardware' or 'get-chassis-inventory'? FPC -> MIC -> PIC?

3,304 views
Skip to first unread message

dave seddon

unread,
Sep 12, 2014, 2:04:52 PM9/12/14
to junos-p...@googlegroups.com
Greetings,

I hope you are well.

I'm very excited by this junos-python-ez tool, where I'm really glad not to have to parse/work-out the all the XML.  Nice work team!  Thanks!!

I'm trying to create a little bit of code to show the full interface inventory of several routers, including if SFPs are inserted or not.

To speed things up by avoiding having to log into the routers all the time, I just saved the output of 'get-chassis-inventory' for each router into multiple XML files, and am then using the 'path=' method to just load in the XML.
This makes it really fast and easy to get the FPC and PIC info.

e.g.
-------------------
from jnpr.junos.op.fpc import FpcHwTable
#https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/op/fpc.yml

from jnpr.junos.op.xcvr import XcvrTable
#https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/op/xcvr.yml

for router_xml_file in router_xml_files:

  fpcs = FpcHwTable(path=router_xml_file)

  for fpc in fpcs.get():
    print("fpc:",fpc,end='\t')
    print("serial-number:",fpc.sn)
    print("part-number:",fpc.pn)
    print("description:",fpc.desc)
    print("version:",fpc.ver)
    print("model-number:",fpc.model)

  Xcvers = XcvrTable(path=full_filename)

  for Xcver in Xcvers.get():
    print("Xcver:",Xcver,end='\t')
    print("serial-number:",Xcver.sn)
    print("part-number:",Xcver.pn)
    print("version:",Xcver.ver)
    print("description:",Xcver.type)
-------------------

However, it kind of seems like we jumped the MIC step.  I would have expected to be able to find all the FPCs, then the MICS, and then finally the PICs.  Perhaps I'm missing something?

Thanks for your help and advice in advance.

Kind regards,
Dave Seddon

---------------
me@router_name> show chassis hardware | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12xxxx/junos">
    <rpc>
        <get-chassis-inventory>
        </get-chassis-inventory>
    </rpc>
    <cli>
        <banner>{master}</banner>
    </cli>
</rpc-reply>
---------------

NitinKumar

unread,
Sep 15, 2014, 8:39:39 AM9/15/14
to dave seddon, junos-p...@googlegroups.com
Hi Dave,

You can define your own table/view and play around for MIC too. Say for example:

MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    view: _mic_hw_view

_mic_hw_view:
    fields:
        desc: description
        clei: clei-code
        ver: version
        model: model-number
        pn: part-number
        sn: serial-number

Code:
from jnpr.junos.op.fpc import MicHwTable
dev = Device(host='xxx', user='yyyy', password='zzzz')
dev.open()
mics = MicHwTable(dev)
mics.get()
print mics
for mic in mics:
        print mic.desc
        print mic.clei
        print mic.model
        print mic.pn
        print mic.sn

Thanks
Nitin Kr

--
You received this message because you are subscribed to the Google Groups "Junos Python EZ" group.
To unsubscribe from this group and stop receiving emails from it, send an email to junos-python-...@googlegroups.com.
Visit this group at http://groups.google.com/group/junos-python-ez.
To view this discussion on the web visit https://groups.google.com/d/msgid/junos-python-ez/75e75f34-5793-4792-a26a-4aef0072678f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

dave seddon

unread,
Sep 15, 2014, 1:06:29 PM9/15/14
to junos-p...@googlegroups.com, dave.se...@gmail.com, nit...@juniper.net
Greetings,

Thanks Nitin!!  That's easy!  (I'm a little unclear why the MIC stuff isn't already there then, but I'm glad it is easy to add.)

How can we commit this to the publicly available source?

Kind regards,
Dave Seddon

#========================================================================

The following are instructions for other people out in the world.  This is based on a ubuntu machine.


Find the pyez package on your machine:
-----------------------------------------
user@machine-name:~$ find /usr -name 'ethport.yml'
/usr/local/lib/python2.7/dist-packages/jnpr/junos/op/ethport.yml
-----------------------------------------

Move to that directory:
-----------------------------------------
user@machine-name:~$ cd /usr/local/lib/python2.7/dist-packages/jnpr/junos/op/
-----------------------------------------

Backup the original file:
-----------------------------------------
user@machine-name:/usr/local/lib/python2.7/dist-packages/jnpr/junos/op$ sudo cp fpc.yml fpc.yml.original
[sudo] password for user:
-----------------------------------------

Edit the file, adding new MicHwTable & view (_mic_hw_view):
-----------------------------------------
user@machine-name:/usr/local/lib/python2.7/dist-packages/jnpr/junos/op$ sudo vi fpc.yml
-----------------------------------------

Lines to add to the fpc.yml are:
-----------------------------------------

MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    view: _mic_hw_view

_mic_hw_view:
    fields:
        desc: description
        clei: clei-code
        ver: version
        model: model-number
        pn: part-number
        sn: serial-number
-----------------------------------------

Here is the diff of the edits:
-----------------------------------------
user@machine-name:/usr/local/lib/python2.7/dist-packages/jnpr/junos/op$ diff -u fpc.yml.original fpc.yml
--- fpc.yml.original    2014-09-15 09:34:14.960120986 -0700
+++ fpc.yml    2014-09-15 09:36:15.856121045 -0700
@@ -63,4 +63,16 @@
         memory: memory-heap-utilization
         cpu: cpu-total
 
+MicHwTable:
+    rpc: get-chassis-inventory
+    item: .//name[starts-with(.,'MIC')]/parent::*
+    view: _mic_hw_view
 
+_mic_hw_view:
+    fields:
+        desc: description
+        clei: clei-code
+        ver: version
+        model: model-number
+        pn: part-number
+        sn: serial-number
-----------------------------------------

Move to your home directory:
-----------------------------------------
user@machine-name:/usr/local/lib/python2.7/dist-packages/jnpr/junos/op$cd
-----------------------------------------

Create some test code:
-----------------------------------------
#!/usr/bin/python2.7
from __future__ import print_function

"""
MicHwTable Test
"""

__author__ = 'user <us...@email.com>'
__version__ = '0.1'

from jnpr.junos.op.fpc import MicHwTable

def main():

  mics = MicHwTable(path='/path/to/xml/file/my_router_name_get-chassis-inventory.xml')

  mics.get()

  print('mics:',mics)

  for mic in mics:
    print('mic.desc:',mic.desc,sep='\t')
    print('mic.clei:',mic.clei,sep='\t')
    print('mic.model:',mic.model,sep='\t')
    print('mic.pn:',mic.pn,sep='\t')
    print('mic.sn:',mic.sn,sep='\t')

if __name__ == '__main__':
  main()
-----------------------------------------

Set to executable:
-----------------------------------------
chmod 755 pyez_MicHwTable_test.py
-----------------------------------------

Run the test:
-----------------------------------------
user@machine-name:~$ ./pyez_MicHwTable_test.py
mics: MicHwTable:/path/to/xml/file/my_router_name_get-chassis-inventory.xml: 3 items
mic.desc:    3D 4x 10GE  XFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-4XGE-XFP
mic.pn:    750-028387
mic.sn:    CXXXXXX
mic.desc:    3D 4x 10GE  XFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-4XGE-XFP
mic.pn:    750-028387
mic.sn:    CXXXXXX
mic.desc:    3D 20x 1GE(LAN) SFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-20GE-SFP
mic.pn:    750-028392
mic.sn:    CXXXXXX
-----------------------------------------

Party:
-----------------------------------------
Party!!
-----------------------------------------



One more time all in one go:
-----------------------------------------
find /usr -name 'ethport.yml'
cd /usr/local/lib/python2.7/dist-packages/jnpr/junos/op/
sudo cp fpc.yml fpc.yml.original
sudo vi fpc.yml
#sudo gedit fpc.yml
#Lines to add:
#-----------------

MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    view: _mic_hw_view

_mic_hw_view:
    fields:
        desc: description
        clei: clei-code
        ver: version
        model: model-number
        pn: part-number
        sn: serial-number
#-----------------
#Test code:
#-----------------------------------------
#!/usr/bin/python2.7
from __future__ import print_function

"""
MicHwTable Test
"""

__author__ = 'user <us...@email.com>'
__version__ = '0.1'

from jnpr.junos.op.fpc import MicHwTable

def main():

  mics = MicHwTable(path='/path/to/xml/file/my_router_name_get-chassis-inventory.xml')

  mics.get()

  print('mics:',mics)

  for mic in mics:
    print('mic.desc:',mic.desc,sep='\t')
    print('mic.clei:',mic.clei,sep='\t')
    print('mic.model:',mic.model,sep='\t')
    print('mic.pn:',mic.pn,sep='\t')
    print('mic.sn:',mic.sn,sep='\t')

if __name__ == '__main__':
  main()
#-----------------------------------------
#Run the test:
#-----------------------------------------
user@machine-name:~$ ./pyez_MicHwTable_test.py
mics: MicHwTable:/path/to/xml/file/my_router_name_get-chassis-inventory.xml: 3 items
mic.desc:    3D 4x 10GE  XFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-4XGE-XFP
mic.pn:    750-028387
mic.sn:    CXXXXXX
mic.desc:    3D 4x 10GE  XFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-4XGE-XFP
mic.pn:    750-028387
mic.sn:    CXXXXXX
mic.desc:    3D 20x 1GE(LAN) SFP
mic.clei:    COUIA1XXXX
mic.model:    MIC-3D-20GE-SFP
mic.pn:    750-028392
mic.sn:    CXXXXXX
#-----------------------------------------
-----------------------------------------

Nitin Kumar

unread,
Sep 15, 2014, 1:14:07 PM9/15/14
to dave seddon, junos-p...@googlegroups.com, nit...@juniper.net

Dave,

You can send a pull request on github.

Nitin K

dave seddon

unread,
Sep 15, 2014, 4:00:30 PM9/15/14
to junos-p...@googlegroups.com, dave.se...@gmail.com, nit...@juniper.net
Greetings Nitin,

Sorry to bother you again.

The other tables have index information allowing the information to be joined.  e.g.  The FPC table has the fpc number, and XcvrTable has fpc & pic number.

However, based on this MIC example, no way to tie these to the MIC number.


Ideally:
- FPC has the fpc index (the fpc slot number)
- MIC would have fpc and mic indexes
- PIC would have fpc, mic, and pic indexes
- Xcvr has fpc, is missing mic, but has pic and Xcvr indexes

In summary it would be awesome to add this information:
- MIC needs fpc and mic indexes
- PIC needs fpc, mic, and pic indexes
- Xcvr needs mic index added

As a total guess, I tried looking at the XcvrTable example, and tried the following:


MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    key:
        - ancestor::::*[starts-with(name,'FPC')]/name
        - name
    view: _mic_hw_view

Which throws "lxml.etree.XPathEvalError: Invalid expression".

Any thoughts on the best way to be able to join all this data together?

Kind regards,
Dave

dave seddon

unread,
Sep 15, 2014, 8:20:24 PM9/15/14
to junos-p...@googlegroups.com, dave.se...@gmail.com, nit...@juniper.net
Greetings,

I've been trying more and seem to have made some promising progress.

The tables in fpc.yml are updated to be the following, please note the commented out line:
------------------------
FpcHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    view: _fpc_hw_view

FpcMiReHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    key:
        - ancestor::multi-routing-engine-item/re-name
        - name
    view: _fpc_hw_view


MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    key:
        - ancestor::*[starts-with(name,'FPC')]/name
        - name
    view: _mic_hw_view

PicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'PIC')]/parent::*

    key:
        - ancestor::*[starts-with(name,'FPC')]/name
# This next line doesn't work
#        - ancestor::*[starts-with(name,'MIC')]/name
        - name
    view: _pic_hw_view

FpcHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    view: _fpc_hw_view

FpcMiReHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    key:
        - ancestor::multi-routing-engine-item/re-name
        - name
    view: _fpc_hw_view


MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    key:
        - ancestor::*[starts-with(name,'FPC')]/name
        - name
    view: _mic_hw_view

_fpc_hw_view:
    fields:
        name: name
        ver: version
        pn: part-number
        sn: serial-number
        desc: description
        clei: clei-code
        model: model-number

_mic_hw_view:
    fields:
        name: name
        ver: version
        pn: part-number
        sn: serial-number
        desc: description
        clei: clei-code
        model: model-number

_pic_hw_view:
    fields:
        name: name
        pn: part-number
        sn: serial-number
        desc: description
------------------------

This all works really well.  Except that for the PIC, it would be great to have the MIC index also.  Based on the above yml, it has the FPC, and PIC. e.g.:

pic.name:    ('FPC 0', 'PIC 1')

But would instead want:
pic.name:    ('FPC 0', 'MIC X', 'PIC 1')

When I uncomment the MIC ancestor definition to the key for the PIC, like this:
------------------------
PicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'PIC')]/parent::*

    key:
        - ancestor::*[starts-with(name,'FPC')]/name
        - ancestor::*[starts-with(name,'MIC')]/name
        - name
    view: _pic_hw_view
------------------------

It fails, with the following error:
------------------------
pics: Traceback (most recent call last):
  File "./pyez_MicHwTable_test.py", line 50, in <module>
    main()
  File "./pyez_MicHwTable_test.py", line 38, in main
    print('pics:',pics)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/factory/table.py", line 238, in __repr__
    n_items = len(self.keys())
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/factory/table.py", line 135, in keys
    self._key_list = self._keys()
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/factory/table.py", line 127, in _keys
    return self._keys_composite(xpath, key_value)
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/factory/table.py", line 92, in _keys_composite
    return [_tkey(item) for item in self.xml.xpath(xpath)]
  File "/usr/local/lib/python2.7/dist-packages/jnpr/junos/factory/table.py", line 91, in <lambda>
    _tkey = lambda this: tuple([this.xpath(k)[0].text for k in key_list])
IndexError: list index out of range
------------------------

The weird thing is that in xcvr.yml there are two (2) ancestor entries and it works fine.  I guess I don't understand ancestors.
------------------------
XcvrTable:
  rpc: get-chassis-inventory
  item: //*[starts-with(name,"Xcvr")]

  key:
    - ancestor::*[starts-with(name,'FPC')]/name
    - ancestor::*[starts-with(name,'PIC')]/name
    - name
  view: XcvrTableView

XcvrTableView:
  fields:
    sn: serial-number
    pn: part-number
    ver: version
    type: description
------------------------

Any thoughts would be appreciated.

Kind regards,
Dave Seddon

dave seddon

unread,
Sep 17, 2014, 12:53:09 PM9/17/14
to junos-p...@googlegroups.com, Dave Seddon, nit...@juniper.net
Greetings,

Just updating the thread for some other poor person who's searching for the solution too.

I've updated the fpc.yml to now include the FPC, MIC, PIC, and Xcvr.

(I'm not really sure why Xcvr was split out into a separate file, but given this is all hardware stuff, I thought it would be easier to have it all in the same file.  Xcvr has the example for the "ancestor" stuff.)

It's still really frustrating that "XcvrHwTable" can have the PIC ancestor, but not the MIC.

Tables:
------------------------------------

FpcHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    view: _fpc_hw_view

FpcMiReHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'FPC')]/parent::*
    key:
        - ancestor::multi-routing-engine-item/re-name
        - name
    view: _fpc_hw_view

MicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'MIC')]/parent::*
    key:
        - ancestor::*[starts-with(name,'FPC')]/name
        - name
    view: _mic_hw_view

PicHwTable:
    rpc: get-chassis-inventory
    item: .//name[starts-with(.,'PIC')]/parent::*
    key:
        - ancestor::*[starts-with(name,'FPC')]/name
#        - ancestor::*[starts-with(name,'MIC')]/name
        - name
    view: _pic_hw_view

XcvrHwTable:

    rpc: get-chassis-inventory
    item: //*[starts-with(name,"Xcvr")]
    key:
        - ancestor::*[starts-with(name,'FPC')]/name
#        - ancestor::*[starts-with(name,'MIC')]/name
        - ancestor::*[starts-with(name,'PIC')]/name
        - name
    view: _xcvr_hw_view
------------------------------------

Views:
------------------------------------

_fpc_hw_view:
    fields:
        name: name
        ver: version
        pn: part-number
        sn: serial-number
        desc: description
        clei: clei-code
        model: model-number

#<version>REV 23</version>
#<part-number>750-031089</part-number>
#<serial-number>ABBR7624</serial-number>
#<description>MPC Type 2 3D</description>
#<clei-code>COUIBAYBAB</clei-code>
#<model-number>MX-MPC2-3D</model-number>


_mic_hw_view:
    fields:
        name: name
        ver: version
        pn: part-number
        sn: serial-number
        desc: description
        clei: clei-code
        model: model-number

#<name>MIC 0</name>
#<version>REV 26</version>
#<part-number>750-028387</part-number>
#<serial-number>ABBR8106</serial-number>
#<description>3D 4x 10GE  XFP</description>
#<clei-code>COUIA16BAA</clei-code>
#<model-number>MIC-3D-4XGE-XFP</model-number>


_pic_hw_view:
    fields:
        name: name
        pn: part-number
        sn: serial-number
        desc: description

#<name>PIC 0</name>
#<part-number>BUILTIN</part-number>
#<serial-number>BUILTIN</serial-number>
#<description>2x 10GE  XFP</description>

_xcvr_hw_view:

    fields:
        name: name
        ver: version  
        pn: part-number
        sn: serial-number
        desc: description
------------------------------------

The test python to see if this stuff works is now:

------------------------------------
#!/usr/bin/python2.7
from __future__ import print_function

"""
HwTable Test
"""

__author__ = 'dave <dave.se...@notmyemail.com>'
__version__ = '0.1'

from jnpr.junos.op.fpc import FpcHwTable
from jnpr.junos.op.fpc import MicHwTable
from jnpr.junos.op.fpc import PicHwTable
from jnpr.junos.op.fpc import XcvrHwTable
#https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/op/fpc.yml

def main():

  fpcs = FpcHwTable(path='/path/to/router/xml/files/router_name_get-chassis-inventory.xml')
  fpcs.get()

  print('fpcs:',fpcs)

  print('fpcs.keys():',fpcs.keys())
  print('fpcs.values()):',fpcs.values())

  for fpc in fpcs:
    print('fpc.name:',fpc.name,sep='\t')
    print('fpc.ver:',fpc.ver,sep='\t')
    print('fpc.pn:',fpc.pn,sep='\t')
    print('fpc.sn:',fpc.sn,sep='\t')
    print('fpc.desc:',fpc.desc,sep='\t')
    print('fpc.clei:',fpc.clei,sep='\t')
    print('fpc.model:',fpc.model,sep='\t')

  print('------------------------------------')

  mics = MicHwTable(path='/path/to/router/xml/files/router_name_get-chassis-inventory.xml')

  mics.get()

  print('mics:',mics)

  print('mics.keys():',mics.keys())
  print('mics.values()):',mics.values())

  for mic in mics:
    print('mic.name:',mic.name,sep='\t')
    print('mic.ver:',mic.ver,sep='\t')

    print('mic.pn:',mic.pn,sep='\t')
    print('mic.sn:',mic.sn,sep='\t')
    print('mic.desc:',mic.desc,sep='\t')
    print('mic.clei:',mic.clei,sep='\t')
    print('mic.model:',mic.model,sep='\t')

  print('------------------------------------')

  pics = PicHwTable(path='/path/to/router/xml/files/router_name_get-chassis-inventory.xml')

  pics.get()

  print('pics:',pics)

  print('pics.keys():',pics.keys())
  print('pics.values()):',pics.values())

  for pic in pics:
    print('pic.name:',pic.name,sep='\t')
    print('pic.pn:',pic.pn,sep='\t')
    print('pic.sn:',pic.sn,sep='\t')
    print('pic.desc:',pic.desc,sep='\t')

  print('------------------------------------')

  xcvrs = XcvrHwTable(path='/path/to/router/xml/files/router_name_get-chassis-inventory.xml')

  xcvrs.get()

  print('xcvrs:',xcvrs)

  print('xcvrs.keys():',xcvrs.keys())
  print('xcvrs.values()):',xcvrs.values())

  for xcvr in xcvrs:
    print('xcvr.name:',xcvr.name,sep='\t')
    print('xcvr.pn:',xcvr.pn,sep='\t')
    print('xcvr.sn:',xcvr.sn,sep='\t')
    print('xcvr.desc:',xcvr.desc,sep='\t')


if __name__ == '__main__':
  main()
------------------------------------

Kind regards,
Dave Seddon

dave seddon

unread,
Sep 18, 2014, 12:14:18 PM9/18/14
to junos-p...@googlegroups.com
Greetings,

Just another update to this thread.

My colleague, who is waaay smarter than I, worked out why the MIC thing isn't working.  The "MPC 3D 16x 10GE" cards don't have MICs, so the 'ancestor' parsing fails.  To confirm this, we manually edited the XML to remove any of the sections referring to the FPCs with the ""MPC 3D 16x 10GE" cards, and it works perfectly.  For the Xcvrs we get the really nice FCP X, MIC Y, PIC Z, Xcvr A.

The question on our mind is how to get this XML parsing to handle the case where the MIC doesn't exist, and perhaps have it default to "NO MIC".  So we'd get FCP X, MIC 'NO MIC', PIC Z, Xcvr A.

I fear that we're going to have to write our own XML parsing, which large defeats the purpose of using this PyEz.  Doh! :(

Kind regards,
Dave Seddon

Rick Sherman

unread,
Sep 18, 2014, 5:31:46 PM9/18/14
to junos-p...@googlegroups.com
Hi Dave,

It looks like you've made some great progress here!

I agree that writing your own parser isn't what we would like for you to have to do, so hopefully we can use this information to further enhance the project.

If you could please attach a sanitized version of the XML you are working with, we can give this a review (as well as give the community an opportunity to follow along).


Thanks,
-Rick
<div style="word-wrap:break-word;color:rgb(0,0,0);font-size:16px;fon
...

dave seddon

unread,
Sep 18, 2014, 8:21:15 PM9/18/14
to Rick Sherman, junos-p...@googlegroups.com
Greetings,

Cool.  Thanks, I'll be interested to see how you go.


Attached are two (2) parsed xml file.  I just replaced all the serial number lines with:

<serial-number>XXXX</serial-number>


I've also found that for some of the modules, like the PhyPortTable and LLDPNeighborView modules, that the parsing of XML files doesn't work until you remove the 'rpc' messages at the start and end of the files.  To solve this I wrote a little bit of code to strip these messages out.

<rpc-reply message-id="urn:uuid:ed11-37b8-11e4-b52c-008cf270">
</rpc-reply>

(uuid truncated by me, just in case)


Last note is that the module LLDPNeighborView does not seem to suit the MX480/MX960s.  I had to update all the fields for this module.

Kind regards,
Dave Seddon

--
You received this message because you are subscribed to a topic in the Google Groups "Junos Python EZ" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/junos-python-ez/AapcSpbDCvo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to junos-python-...@googlegroups.com.
a_router_get-chassis-inventory.xml
another_router_get-chassis-inventory.xml

Rick Sherman

unread,
Oct 1, 2014, 6:53:14 PM10/1/14
to junos-p...@googlegroups.com, rshe...@juniper.net
Hi Dave,

I spent some time looking into the details of this issue and have a proposed solution.

I've raised an issue in GitHub for comment and tracking.  I'm going to solicit some feedback on this and we'll see if this is the best fix or if there may be some other options.


Thanks,
-Rick
To unsubscribe from this group and all its topics, send an email to junos-python-ez+unsubscribe@googlegroups.com.

Rick Sherman

unread,
Oct 3, 2014, 6:13:59 PM10/3/14
to junos-p...@googlegroups.com, rshe...@juniper.net, dave.se...@gmail.com
Hello Dave,

I have created an alternate solution which sets the missing key value to None.  I have tested this against your provided sample and would like to ask you to test on your end prior to me merging in the code.

To test this please install pyez from the following:


pics: PicHwTable:1.xml: 14 items
pics.keys(): [('FPC 0', 'MIC 0', 'PIC 0'), ('FPC 0', 'MIC 0', 'PIC 1'), ('FPC 0', 'MIC 1', 'PIC 2'), ('FPC 0', 'MIC 1', 'PIC 3'), ('FPC 1', 'MIC 0', 'PIC 0'), ('FPC 1', 'MIC 0', 'PIC 1'), ('FPC 1', 'MIC 1', 'PIC 2'), ('FPC 1', 'MIC 1', 'PIC 3'), ('FPC 2', 'MIC 0', 'PIC 0'), ('FPC 2', 'MIC 0', 'PIC 1'), ('FPC 3', None, 'PIC 0'), ('FPC 3', None, 'PIC 1'), ('FPC 3', None, 'PIC 2'), ('FPC 3', None, 'PIC 3')]
{'desc': {'xpath': 'description'}, 'pn': {'xpath': 'part-number'}, 'sn': {'xpath': 'serial-number'}, 'name': {'xpath': 'name'}}
pics.values()): [[('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 0', 'MIC 0', 'PIC 0'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 0', 'MIC 0', 'PIC 1'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 0', 'MIC 1', 'PIC 2'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 0', 'MIC 1', 'PIC 3'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 1', 'MIC 0', 'PIC 0'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 1', 'MIC 0', 'PIC 1'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 1', 'MIC 1', 'PIC 2'))], [('desc', '2x 10GE  XFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 1', 'MIC 1', 'PIC 3'))], [('desc', '10x 1GE(LAN) SFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 2', 'MIC 0', 'PIC 0'))], [('desc', '10x 1GE(LAN) SFP'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 2', 'MIC 0', 'PIC 1'))], [('desc', '4x 10GE(LAN) SFP+'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 3', None, 'PIC 0'))], [('desc', '4x 10GE(LAN) SFP+'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 3', None, 'PIC 1'))], [('desc', '4x 10GE(LAN) SFP+'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 3', None, 'PIC 2'))], [('desc', '4x 10GE(LAN) SFP+'), ('pn', 'BUILTIN'), ('sn', 'XXXX'), ('name', ('FPC 3', None, 'PIC 3'))]]
pic.name: ('FPC 0', 'MIC 0', 'PIC 0')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 0', 'MIC 0', 'PIC 1')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 0', 'MIC 1', 'PIC 2')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 0', 'MIC 1', 'PIC 3')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 1', 'MIC 0', 'PIC 0')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 1', 'MIC 0', 'PIC 1')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 1', 'MIC 1', 'PIC 2')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 1', 'MIC 1', 'PIC 3')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 2x 10GE  XFP
pic.name: ('FPC 2', 'MIC 0', 'PIC 0')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 10x 1GE(LAN) SFP
pic.name: ('FPC 2', 'MIC 0', 'PIC 1')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 10x 1GE(LAN) SFP
pic.name: ('FPC 3', None, 'PIC 0')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 4x 10GE(LAN) SFP+
pic.name: ('FPC 3', None, 'PIC 1')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 4x 10GE(LAN) SFP+
pic.name: ('FPC 3', None, 'PIC 2')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 4x 10GE(LAN) SFP+
pic.name: ('FPC 3', None, 'PIC 3')
pic.pn: BUILTIN
pic.sn: XXXX
pic.desc: 4x 10GE(LAN) SFP+



dave seddon

unread,
Oct 8, 2014, 1:29:23 PM10/8/14
to Rick Sherman, junos-p...@googlegroups.com
Greetings,

Thanks for your efforts on this.  Sorry, I've take time to get back to this.

We can see you've updated the xpath stuff to do some 'catch -> None' stuff, seen here:

https://github.com/shermdog/py-junos-eznc/compare/table-missing-xpath

That looks cool, and I guess that will work.


However, there don't seem to be updates to the .yml files so I'm unclear of the proposed updates to the yaml, and then the code to test this.

Kind regards,
Dave

Rick Sherman

unread,
Oct 8, 2014, 1:53:48 PM10/8/14
to dave seddon, junos-p...@googlegroups.com

Hi Dave,

 

The solution we settled on does not require any changes to the yml files already have.

 

If a part of the compound key is missing, it will just be set to None now (as opposed to throwing and exception and dying).

 

-Rick

Reply all
Reply to author
Forward
0 new messages