Site icon Karneliuk

pygnmi 3. Usage of gNMI Capabilities.

Hello my friend,

Some time ago we’ve started sharing with you the details of pygnmi – our new open-source Python library created to simplify the management of the network elements with gNMI. The library is already almost fully operational and we want to start sharing the usage scenarios with you.


1
2
3
4
5
No part of this blogpost could be reproduced, stored in a
retrieval system, or transmitted in any form or by any
means, electronic, mechanical or photocopying, recording,
or otherwise, for commercial purposes without the
prior permission of the author.

Don’t you want to automate boring stuff?

Every job, especially network operation, has lots of routing tasks, which are boing and time consuming. Some of such tasks could be already automated in your company, but the vast majority is still waiting you. In our trainings:

Our network automation training has two faces: either live or self-paced. So you can choose yourself, what works better for you. On our side, we guide you from the foundation of the automation for the small networks till advanced automation use cases in big data centres, service providers, and clouds. You will lean how to structure the data using YANG modules, how to serialise it using JSON, XML, Protocol Buffers (Protobuf) depending on the application requirements and how to manage the fleet of your IT and network workloads relying gRPC, gNMI, NETCONF, RESTCONF, REST API and many others with Bash, Ansible and Python. In addition to that you will master the solid foundation in Linux administration, Linux networking, network function virtualisation (NFV) with KVM and containerisation with Docker. And on top of that we share some very useful open source tools with you. That is all you need to be successful in network automation in one place.

Start your automation training today.

Brief description

The pygnmi has one very important advantage of any other library existing in Python: it converts the request into a native Python dictionary format, so that you don’t need to bother how to read Protobuf and how to convert data in the Protobuf format. As such, you can just focus on the logic of your script and integration with other applications (e.g. NetBox via REST API).

The library is now in the beta test and we are actively working on testing it on various platforms. So far we’ve tested the Nokia SR OS and Arista EOS. Both of them are working perfectly fine for all four operation types: Capabilities, Get, Set, and Subscribe. In today’s blogpost we will cover the first one.

gNMI Capabilities RPC

Capabilities allows you get the following information from the target network element:

From the logic perspective, the Capabilities should be the first request you perform towards the network element to learn about it and decide what are the next requests and using which YANG modules you should perform. With the pygnmi the code example is very simple:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
#(c)2020, karneliuk.com

# Modules
from pygnmi.client import gNMIclient

# Variables
host = ('fd17:625c:f037:2::100',6030)

# Body
if __name__ == '__main__':
    with gNMIclient(target=host, username='aaa', password='aaa', insecure=True) as gc:
        response = gc.capabilities()

    print(response)

First of all, install pygni using pip: pip install pygnmi

Once that is done in your code you cam import gNMIclient from pygnmi.client, which is class working as context manager. It means you can use a simple nice construction with … as …, which will handle the session management for you.

That is the same approach you have, if you have worked with ncclient.

The are several parameter you need to provide:

Others key are optional. However, you should better provide either:

Whatever path you follow, depends on your requirement. You can start familiarisation with insecure channel, as that is easier to build, and then switch to secure one, what requires a bit more efforts.

The details on the secure channel will be shard in the coming demos.

The result of the Python’s script execution would be the following:


1
2
 python gnmi_get.py
{'notification': [{'timestamp': 0}, {'timestamp': 0, 'update': [{'path': 'interfaces/interface[name=Ethernet1]', 'json_ietf_val': {'openconfig-interfaces:config': {'description': 'pygnmi-controlled', 'enabled': True, 'arista-intf-augments:load-interval': 300, 'loopback-mode': False, 'mtu': 0, 'name': 'Ethernet1', 'openconfig-vlan:tpid': 'openconfig-vlan-types:TPID_0X8100', 'type': 'iana-if-type:ethernetCsmacd'}, 'openconfig-if-ethernet:ethernet': {'config': {'arista-intf-augments:fec-encoding': {'disabled': False, 'fire-code': False, 'reed-solomon': False, 'reed-solomon544': False}, 'openconfig-hercules-interfaces:forwarding-viable': True, 'mac-address': '00:00:00:00:00:00', 'port-speed': 'SPEED_UNKNOWN', 'arista-intf-augments:sfp-1000base-t': False}, 'arista-intf-augments:pfc': {'priorities': {'priority': [{'index': 0, 'state': {'in-frames': '0', 'index': 0, 'out-frames': '0'}}, {'index': 1, 'state': {'in-frames': '0', 'index': 1, 'out-frames': '0'}}, {'index': 2, 'state': {'in-frames': '0', 'index': 2, 'out-frames': '0'}}, {'index': 3, 'state': {'in-frames': '0', 'index': 3, 'out-frames': '0'}}, {'index': 4, 'state': {'in-frames': '0', 'index': 4, 'out-frames': '0'}}, {'index': 5, 'state': {'in-frames': '0', 'index': 5, 'out-frames': '0'}}, {'index': 6, 'state': {'in-frames': '0', 'index': 6, 'out-frames': '0'}}, {'index': 7, 'state': {'in-frames': '0', 'index': 7, 'out-frames': '0'}}]}}, 'state': {'auto-negotiate': False, 'counters': {'in-crc-errors': '0', 'in-fragment-frames': '0', 'in-jabber-frames': '0', 'in-mac-control-frames': '0', 'in-mac-pause-frames': '0', 'in-oversize-frames': '0', 'out-mac-control-frames': '0', 'out-mac-pause-frames': '0'}, 'duplex-mode': 'FULL', 'enable-flow-control': False, 'openconfig-hercules-interfaces:forwarding-viable': True, 'hw-mac-address': '08:00:27:04:eb:42', 'mac-address': '08:00:27:04:eb:42', 'negotiated-port-speed': 'SPEED_UNKNOWN', 'port-speed': 'SPEED_UNKNOWN', 'arista-intf-augments:supported-speeds': ['SPEED_40GB', 'SPEED_25GB', 'SPEED_10MB', 'SPEED_100GB_2LANE', 'SPEED_100MB', 'SPEED_50GB_1LANE', 'SPEED_50GB', 'SPEED_200GB_4LANE', 'SPEED_10GB', 'SPEED_5GB', 'SPEED_1GB', 'SPEED_100GB', 'SPEED_2500MB', 'SPEED_200GB_8LANE', 'SPEED_400GB']}}, 'openconfig-interfaces:hold-time': {'config': {'down': 0, 'up': 0}, 'state': {'down': 0, 'up': 0}}, 'openconfig-interfaces:name': 'Ethernet1', 'openconfig-interfaces:state': {'admin-status': 'UP', 'counters': {'in-broadcast-pkts': '0', 'in-discards': '0', 'in-errors': '0', 'in-fcs-errors': '0', 'in-multicast-pkts': '0', 'in-octets': '0', 'in-unicast-pkts': '0', 'out-broadcast-pkts': '0', 'out-discards': '0', 'out-errors': '0', 'out-multicast-pkts': '87', 'out-octets': '10345', 'out-unicast-pkts': '0'}, 'description': 'pygnmi-controlled', 'enabled': True, 'openconfig-platform-port:hardware-port': 'Port1', 'ifindex': 1, 'arista-intf-augments:inactive': False, 'last-change': '1605736734320210176', 'loopback-mode': False, 'mtu': 0, 'name': 'Ethernet1', 'oper-status': 'UP', 'openconfig-vlan:tpid': 'openconfig-vlan-types:TPID_0X8100', 'type': 'iana-if-type:ethernetCsmacd'}, 'openconfig-interfaces:subinterfaces': {'subinterface': [{'config': {'description': 'pygnmi-controlled', 'enabled': True, 'index': 0}, 'index': 0, 'openconfig-if-ip:ipv4': {'addresses': {'address': [{'config': {'arista-intf-augments:addr-type': 'PRIMARY', 'ip': '10.1.2.0', 'prefix-length': 31}, 'ip': '10.1.2.0', 'state': {'arista-intf-augments:addr-type': 'PRIMARY', 'ip': '10.1.2.0', 'origin': 'STATIC', 'prefix-length': 31}}]}, 'config': {'dhcp-client': False, 'enabled': True, 'mtu': 1500}, 'state': {'dhcp-client': False, 'enabled': True, 'mtu': 1500}, 'unnumbered': {'config': {'enabled': False}, 'interface-ref': {'config': {}, 'state': {}}, 'state': {'enabled': False}}}, 'openconfig-if-ip:ipv6': {'config': {'dhcp-client': False, 'enabled': False, 'mtu': 1500}, 'state': {'dhcp-client': False, 'enabled': False, 'mtu': 1500}}, 'state': {'counters': {'in-fcs-errors': '0'}, 'description': 'pygnmi-controlled', 'enabled': True, 'index': 0}}]}}}]}]}

As you can see from the format, that is native Python dictionary, which you can directly use without any further conversions.

If you prefer video

You can watch it in our channel on YouTube:

Lessons learned

We’ve had to rewrite part of the code, including capabilities requests compared to previous scenario, as it was missing not parsing all the necessary arguments. Now the parser is extended for almost the full coverage; however, there might be still some bits and pieces missing. Let us know, please, or raise issue at GitHub, if you spot anything.

Conclusion

We already started using this library for our purposes in our own projects and start getting benefit from that, we don’t need work with all complex Protobuf parsing all the time. However, we are still working on the further development and bug fixing of this library. Within the next few weeks we will cover three other calls. Stay tuned. Take care and good bye.

Support us






P.S.

If you have further questions or you need help with your networks, we are happy to assist you, just send us a message. Also don’t forget to share the article on your social media, if you like it.

BR,

Anton Karneliuk

Exit mobile version