Hello my friend,
We have already reviewed how to collect the operational and configuration data from Nokia SR OS devices, and even how to structure it in YANG trees, as well as how to configure network devices with Python and pySROS. You may think, that all the interesting things about Nokia pySROS are already covered. Well, we have some more aces in the pocket for you. Today you will learn some new things, such as MicroPython and how to run the pySROS code directly on Nokia SR OS based network functions.
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.
Network Automation Is So Popular These Days… Shall I Do Something Different?
Network Automaton is indeed getting more and more popular. There are a few reasons for that: one the one hand, networks getting more complex with all fancy SDx technologies (SDN, SD-WAN, SDA, etc); on the other hand, it is required to deliver new services quicker and quicker. Doing the things manually and quickly are two perfect ingredients to cook a disaster in your IT infrastructure via making mistake some mistake. All of us laugh on the memes with networking problems (e.g., “Oh my God, did you type switch port trunk vlan ADD xxx”), whereas some of us did that in reality and, for sure, it was neither funny nor painless for the network and engineers.
This is where automation is much better than we, humans: automation is much better to do standard routine and complex activities, which allows to make sure that no steps are missed, all validations (pre- and post-checks) are done, and no typos occurred.
In our Network Automation Training you will learn how to do that all relying on our real-life experience of building and automating high-scale service provider and data centre networks.
At our trainings, zero-to-hero network automation and automation with Nornir (2nd step after zero-to-hero network automation), we give you detailed knowledge of all the technologies relevant:
- Data encoding (free-text, XML, JSON, YAML, Protobuf)
- Model-driven network automation with YANG, NETCONF, RESTCONF, GNMI.
- Full configuration templating with Jinja2 based on the source of truth (NetBox).
- Best automation programming languages (Python, Bash), configuration management tools (Ansible) and automation frameworks (Nornir).
- Network automation infrastructure (Linux, Linux networking, KVM, Docker).
Anton collected a huge amount of information, which is difficult to find in any network automation training. Therefore, he handled it himself and created this Training.
Boris Hassanov @ Lead Network Architect, Yandex
Technologies themselves are good, but it is not good enough for us. Therefore, we put all of them in the context of the real use cases, which our team has solved and are solving in various projects in the service providers, enterprise and data centre networks and systems across the Europe and USA. That gives you opportunity to ask questions to understand the solutions in-depts and have discussions about your own projects. And on top of that, each technology is provided with online demos and you are doing the lab afterwards to master your skills. Such a mixture creates a unique learning environment, which all students value so much. Join us and unleash your potential.
Both trainings are available in live class and online formats. And more trainings coming soon!
Brief Description
We often hear that people are getting sick about network automation, and trying to stay away. On the one hand, the truth is that, there were Luddites in the history, who were opposed the technical progress and were destroying the machines at factory facilities. Now, they are only on history and machines are now everywhere. Same with the network automation, it doesn’t matter you like network automation or not, it is here and it will stay with us. On the other hand, network engineering is still here as well: we still run routing protocols (OSPF, ISIS, BGP, etc) and services (VPWS, VPLS, VPN, etc). Time to time we need to design new networks solutions. Time to time networks break due to various reasons and we need to perform troubleshooting, which is typically a sequential set of the commands, where we are looking for the interdependent information (e.g., take IP address, then check if it is installed in the routing table, if you have MPLS labels for it and what is the LSP, what are the BGP routes having it as a next-hop and so on).
The one could say “Okay, guys, you are preaching network network automation. Why not to run scripts remotely and connect to the device via SSH/NETCONF/GNMI?”
The question is absolutely legitimate: there is almost no reasons not to do that. However, what if the device is not reachable remotely via normal means SSH/NETCONF/GNMI and you can access it only via OOB console? Such use can be automated as well, but automation is not a golden bullet and it perfectly follows Pareto rule: 80% of use cases are solved with 20% of efforts. Therefore, instead of automating the access to network device via OOB CLI, we would rather move the execution of Python script on the network device and run it there having the same experience as if you run it from your automaton host.
Now you understand why it is needed and, therefore, can focus on how to do that. The thing, it is both easy and not easy simultaneously. Puzzled? Continue reading, my friend.
Lab Setup
Our lab setup stays unchanged since our first blog in this series:
- Servers:
- Linux Debian 11
- Python 3.9
- pySROS 21.7
- Network Device:
- Nokia SR OS 21.7.R1
In previous blogposts (part 1 and part 2) you can learn more the setup and how to build that.
Scenario Description
From the practical standpoint, we are focusing today on the following items:
- How to create script locally on the Nokia SR OS based network device?
- How to make this script executable?
- How to execute Python scripts on the Nokia SR OS based network device?
Join our Network Automation Training to learn more about Python.
Besides that, we’ll review a few useful scenarios, how to deal with exceptions, which may arise when you use pysros.
Python Script Development
Now, before we will get to the Python script itself, we need to do introduce some new concept. which is called MicroPython.
Step #0. What Is MicroPython?
To be absolutely frank, we ourselves learned this word first time, when we were paring this blogpost. In the Nokia SR OS 21.7.R1 System Management Guide, there is a following statement:
SR OS provides the MicroPython interpreter on the SR OS node. This interpreter is designed to operate using a small memory footprint, which allows SR OS to launch multiple interpreters in parallel.
System Management Guide 21.7.R1, Chapter 6.3
So, Nokia SR OS run MicroPython, not an ordinary Python. What is that? What is the difference? Some researches landed us on the official website of this project, which provides some description:
MicroPython is a lean and efficient implementation of the Python 3 programming language that includes a small subset of the Python standard library and is optimised to run on microcontrollers and in constrained environments.
www.micropython.org
So, it sound like a Python, but smaller and with limited amount of libraries, which is tailored to run on microcontrollers or embedded systems, which generally what Nokia SR OS is (at a glance, it is neither Unix/Linux, nor Windows). The full list of supported libraries in MicroPython is provided in their documentation. However, not all of them are implemented in Nokia SR OS. Per the official documentation, the following list of libraries are implemented in Nokia SR OS version of MicroPython:
Library | Description |
---|---|
binutils | Collection of binary utilities |
datetime | Manipulation of various formats for date, time, and time zone, including the SR OS model-driven standard ISO 8601 |
ubinascii | Bidirectional translation between binary data and various ASCII encodings |
ujson | Conversion between Python objects and JSON data format |
pysros | Model-driven management API for SR OS (Python for the Service Router Operating System – pySROS) |
ucollections | Advanced collection and container types to hold or accumulate various objects |
ure | Simple regular expressions |
sys | System-specific parameters and functions |
uhashlib | Binary data hashing algorithms |
ustruct | Pack and unpack primitive data types |
ipaddress | IPv4 and IPv6 address manipulation |
uio | Input and output streams |
utime | Obtaining current date and time, measuring intervals, and delays |
So, the amount of libraries is limited indeed and we cannot, at least at the moment, install more than that. To be honest, this list is not that small and we can achieve a lot with that with a certain degree of creativity.
Step #1. Create Python Script and Upload to Nokia SR OS Network Device Locally
First of all, we’ll recreate the script we have created previously in the second blogpost for standard Python version. We will though extend it a bit:
- MicroPython supports sys library. It means we can provide arguments in the CLI after the script name.
- This will allow us to provide the XPath for the resource of interest in CLI dynamically, when we call our script.
The script itself would look like that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 # Modules
import sys
import time
from pysros.management import connect
from pysros.pprint import printTree
# Variables
path = 'nokia-conf:configure/card[slot-number="1"]'
# Body
if __name__ == "__main__":
## Check input args
input_args_list = sys.argv
del input_args_list[0]
input_args_list = [path] if len(input_args_list) == 0 else input_args_list
for path_str in input_args_list:
## Get the timesamp in the beginning of the command
t1 = time.ticks_ms()
## Collect the information
connect_obj = connect()
results = connect_obj.running.get(path_str)
connect_obj.disconnect()
## Print results
print("Reuqested path: \n{}\n\nResult:".format(path_str))
printTree(results)
## Get the timesamp at the end
t2 = time.ticks_ms()
## Print time
print("\nCompleted in {} ms".format(time.ticks_diff(t2, t1)))
Please, refer to the original blogpost to get the details of this script.
There are a few enhancements to the original script:
- This one will read the arguments from CLI using sys.argv list. If you don’t provide the details, it will use a default variable for that in order not to fail.
- The class connect() doesn’t have any arguments. Per the documentation it is already assumed you are authenticated and authorised. Also, the script is executed locally; hence, there is no necessity to provide the host IP address.
- To measure the performance of the script, we would use time library instead of datetime. Despite the latter is supported as well, the decide to change that.
- The f-strings are not supported at the moment. Nokia SR OS implements MicroPython of 3.4/3.5 version, whereas f-strings in MicroPython were introduced later. As such we replace all f-strings with format() function.
Now, once you have a script you can run on the Nokia SR OS based device, you’d need to place it on the device somehow. There are generally two options:
- Store it locally on the cf3: (or any other type of local storage).
- Have it remote and download.
The second approach will be used later. For now let’s focus on the first one.
It is assumed that you are running MD-CLI.
On the one hand, there is no text editor available in the MD-CLI in Nokia SR OS. On the other hand, arguable, you highly unlikely would like to develop and debug the Python program directly on the network device, but rather you would develop it locally on your laptop and then copy the Python script to the router.
Go to the file context and create a directory to store your scripts:
1
2
3
4 A:admin@sr1# file
[/file "cf3:"]
A:admin@sr1# make-directory python_scripts
Then copy from your laptop the Python script to Nokia SR OS router using scp:
1
2
3
4 $ scp pysros_test.py admin@192.168.101.11:python_scripts/.
admin@192.168.101.11's password:
pysros_test.py
Once file is coped, you can see it on the Nokia SR OS based network device:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 [/file "cf3:"]
A:admin@sr1# list python_scripts
Volume in drive cf3 on slot A is SROS VM.
Volume in drive cf3 on slot A is formatted as FAT32
Directory of cf3:\python_scripts
11/21/2021 04:11p <DIR> ./
11/21/2021 04:11p <DIR> ../
11/22/2021 10:50p 985 pysros_test.py
1 File(s) 985 bytes.
2 Dir(s) 680636416 bytes free.
If all done properly you shall be able to see the content of the files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 [/file "cf3:"]
A:admin@sr1# show python_scripts/pysros_test.py
File: pysros_test.py
-------------------------------------------------------------------------------
# Modules
import sys
import time
from pysros.management import connect
from pysros.pprint import printTree
# Variables
path = 'nokia-conf:configure/card[slot-number="1"]'
# Body
if __name__ == "__main__":
## Check input args
input_args_list = sys.argv
del input_args_list[0]
input_args_list = [path] if len(input_args_list) == 0 else input_args_list
for path_str in input_args_list:
## Get the timesamp in the beginning of the command
t1 = time.ticks_ms()
## Collect the information
full_xpath_str = "/" + path_str
connect_obj = connect()
results = connect_obj.running.get(full_xpath_str)
connect_obj.disconnect()
## Print results
print("Reuqested path: \n{}\n\nResult:".format(full_xpath_str))
printTree(results)
## Get the timesamp at the end
t2 = time.ticks_ms()
## Print time
print("\nCompleted in {} ms".format(time.ticks_diff(t2, t1)))
===============================================================================
Step #2. Configure Script to Be Usable
Switch back to the MD-CLI:
1
2
3
4
5
6 *A:sr1>file cf3:\ # exit
*A:sr1# //
INFO: CLI #2052: Switching to the MD-CLI engine
[/]
A:admin@sr1#
Once in the MD-CLI, go to the configuration mode and create a Python script configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 [/]
A:admin@sr1# configure global
INFO: CLI #2054: Entering global configuration mode
[gl:/configure]
A:admin@sr1# python
[gl:/configure python]
A:admin@sr1# info
python-script "karneliuk_test" {
admin-state enable
urls ["cf3:\python_scripts\pysros_test.py"]
version python3
}
This configuration consists of 4 blocks:
- Naming the script context. This name you will be executing later (“karneliuk_test” in this case).
- Making script administratively enabled.
- Providing the path, where the script can be found.
- Choosing the version of the Python to run (yes, Python2 is supported, but even don’t think about using it, it is 2021 already).
Once this is done, script is ready for execution.
IMPORTANT! If you change the content of the script after you configured it in the MD-CLI, you would need to re-sync it. This you can achieve using the following command:
1
2 [/]
A:admin@sr1# tools perform python-script reload "karneliuk_test"
Use this command each time your change the content of your script
Step #3. Execute Python Script on Nokia SR OS Network Device
Finally we get the point, where you will run the script. To do that, use the pyexec CLI command followed by the script name. First of all, you can run it without any argument, as we have provided a default value:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 A:admin@sr1# pyexec "karneliuk_test"
Reuqested path:
/nokia-conf:configure/card[slot-number="1"]
Result:
+-- slot-number: 1
+-- level: he
+-- admin-state: enable
+-- card-type: iom-1
`-- mda:
`-- 1:
+-- mda-slot: 1
+-- mda-type: me6-100gb-qsfp28
`-- admin-state: enable
Completed in 7 ms
Just 7 ms to collect some information, and you can see the content of the certain configuration element in the defined YANG module.
If you worked with Nokia SR Linux, you may remember its config/state view from the CLI.
Can we collect states for Nokia SR OS as well? Yes, this script gives you exactly this possibility:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 A:admin@sr1# pyexec "karneliuk_test" "/nokia-state:state/card[slot-number=1]"
Reuqested path:
/nokia-state:state/card[slot-number=1]
Result:
`-- 1:
+-- mda:
| +-- 2:
| | +-- channels-in-use: 0
| | +-- equipped-type: unassigned
| | +-- mda-slot: 2
| | +-- minimum-channelization: unknown
| | +-- maximum-ports: 0
| | +-- transmit-timing-selected: not-applicable
| | +-- capabilities:
| | +-- maximum-channelization: unknown
| | +-- maximum-channels: 0
| | +-- equipped-ports: 0
| | +-- sync-if-timing-status: not-applicable
| | `-- hardware-data:
| | +-- part-number:
| | +-- failure-reason:
| | +-- manufacturing-deviations:
| | +-- base-mac-address: 00:00:00:00:00:00
| | +-- manufacturing-date:
| | +-- contains-temperature-sensor: False
| | +-- temperature-threshold: -1
| | +-- oper-state: empty
| | +-- alarm-state: alarm-cleared
| | +-- contained-in: Slot 1
| | +-- software-code-version:
| | +-- power-zone-location: 1
| | +-- boot-code-version:
| | +-- serial-number:
| | +-- manufacturing-assembly-number:
| | +-- common-language-equipment-identifier:
| | +-- equipped-platform-type: platform-unknown
| | +-- software-image-source: unknown
| | +-- firmware-code-version:
| | +-- firmware-revision-status: not-applicable
| | `-- field-replaceable-unit: True
| `-- 1:
| +-- channels-in-use: 0
| +-- subscriber-management:
| | `-- statistics:
| | +-- ipv4-hosts:
| | | +-- ipcp:
| | | | +-- current-value: 0
| | | | `-- counter: ipcp
!
! FURTHER OUTPUT IS TRUNCATED FOR BREVITY
You can even provide multiple XPath separated by whitespace, it will work with this script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 A:admin@sr1# pyexec "karneliuk_test" "/openconfig-interfaces:interfaces" "/openconfig-network-instance:network-instances"
Reuqested path:
/openconfig-interfaces:interfaces
Result:
`-- interface:
+-- system:
| +-- name: system
| +-- config:
| | +-- type: softwareLoopback
| | +-- enabled: True
| | `-- name: system
| +-- state:
| | +-- type: softwareLoopback
| | `-- name: system
| `-- subinterfaces:
| `-- subinterface:
| `-- 0:
| +-- config:
| | +-- enabled: True
| | `-- index: 0
| +-- ipv4:
| | `-- addresses:
| | `-- address:
| | `-- 10.0.255.11:
| | +-- ip: 10.0.255.11
| | `-- config:
| | +-- ip: 10.0.255.11
| | `-- prefix-length: 32
| `-- index: 0
+-- 1/1/c1/1:
| +-- hold-time:
| | `-- state:
| | +-- up: 0
| | `-- down: 0
| +-- name: 1/1/c1/1
| +-- ethernet:
| | `-- state:
| | +-- auto-negotiate: False
!
! OUTPUT IS TRUNCATED FOR BREVITY
!
| +-- ip: 10.0.0.0
| `-- prefix-length: 31
`-- index: 0
Completed in 123 ms
Reuqested path:
/openconfig-network-instance:network-instances
Result:
`-- network-instance:
`-- Base:
+-- state:
| +-- ecmp: 1
| +-- type: DEFAULT_INSTANCE
| +-- name: Base
| `-- router-id: 255.0.0.0
+-- config:
| +-- name: Base
| `-- type: DEFAULT_INSTANCE
+-- name: Base
+-- protocols:
| `-- protocol:
| `-- ('BGP', '0'):
| +-- name: 0
!
! FURTHER OUTPUT IS TRUNCATED FOR BREVITY
Step #4. Alternative Way of Executing Scripts
You may think that the described approach (registering and refreshing scripts) is too complicated. There is another way how you can call the script: just provide its full path in the double quotes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 A:admin@sr1# pyexec "cf3:\python_scripts\pysros_test.py" "/openconfig-interfaces:interfaces"
Reuqested path:
/openconfig-interfaces:interfaces
Result:
`-- interface:
+-- system:
| +-- name: system
| +-- config:
| | +-- type: softwareLoopback
| | +-- enabled: True
| | `-- name: system
| +-- state:
| | +-- type: softwareLoopback
| | `-- name: system
| `-- subinterfaces:
| `-- subinterface:
| `-- 0:
!
! FURTHER OUTPUT IS TRUNCATED FOR BREVITY
The main benefit of such approach is that you don’t need to create the registration of it in the configuration context and don’t need to refresh with the tool. The drawback is, tough, there is no auto-completion with the TAB-key, so you need to copy (or memorise and type) the path each time.
Examples in GitHub
You can find this and other examples in our GitHub repository.
Lessons Learned
After all, MicroPython is the same Python, just optimised and truncated. Some further researches we conducted in that area shows, that it is possible to run it directly in microcontrollers without any operating system installed. In this case the MicroPython controls all the functions of the hardware. Have you ever wanted to do the hardware programming? With MicroPython you open this exciting world to yourself.
Build your own and your network’s stable future with our Network Automation Training.
Conclusion
Having possibility to run the Python (even MicroPython) scripts directly on the network device expands your possibility to do the complex analysis when you do the troubleshooting. It also allows you to perform the configuration of the Nokia SR OS based network device, which creates an interesting opportunities for configuration scenarios of initial provisioning or services onboarding/cleanup. In the next blogpost you will learn how to store the code centrally and run it from Nokia SR OS devices. In next blogpost you will learn how to run the arbitrary CLI commands with Python on Nokia SR OS network device and how to store your scripts centrally. 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