I tried using PyEZ and JSNAPy. It is a sequel to. This time, I will introduce the contents of using PyEZ.
-I tried using PyEZ and JSNAPy. Part 1: Overview -I tried using PyEZ and JSNAPy. Part 2: I tried using PyEZ (Imakoko) -I tried using PyEZ and JSNAPy. Part 3: I tried using JSNAPy -I tried using PyEZ and JSNAPy. Part 4: Automating ISP setting work with PyEZ and JSNAPy
PyEZ is a Python library for configuring JUNOS routers. By the way, it seems that a Ruby library called RubyEZ is also available.
Communication with the router uses NETCONF over SSH and is designed to operate on the TCP 830 port recommended by RFC by default.
PyEZ seems to be available from JUNOS version 11.4. Compared to other manufacturers, automation tools can only be used with newer OS versions in many cases, but with the combination of JUNOS + PyEZ, it can be used with JUNOS routers that have already been installed and operated at many operation sites. Therefore, it can be said that it is an easy-to-use tool due to the low threshold of introduction. (In the actual network operation site, in order to avoid performance deterioration and defects, many organizations may adopt only the OS version with dead bugs. "The new OS cannot be used unless the bugs are dead." "Results I imagine that there may be cases where the consideration and introduction of automation is postponed by several years.)
--Router config input --load (merge / overload / replace option can be specified)
I haven't tried all the features, but it seems like I can almost do it manually with PyEZ. If you find something you can't do while using PyEZ, please share your knowledge.
Understanding will be quicker if you proceed while looking at the following articles / documents. They are arranged in the order that was helpful.
Japanese introduction blog -Note 1 to try Juniper JUNOS PyEz (python library) ~ PyEz Overview ~ -Note 2 to try Juniper JUNOS PyEz (python library) ~ ~ Get information by PyEz ~ -Note 3 to try Juniper JUNOS PyEz (python library) ~ ~ Change settings by PyEz ~
PyEZ Github
Juniper Official Document
Here, Python 2.7.10 is used as the server that runs the tool, and firefly is used as the JUNOS router.
First, install PyEZ with the pip command. Here, the latest version 2.0.1 is used.
pip install junos-eznc
pip list
junos-eznc (2.0.1)
Also, on the JUNOS router side, input the settings to enable NETCONF.
Router information
root@firefly1> show version
Hostname: firefly1
Model: firefly-perimeter
JUNOS Software Release [12.1X47-D20.7]
NETCONF enabled configuration
system {
services {
netconf {
ssh;
}
}
}
}
Simply configure the router as above and it will start listening for TCP 830 for NETCONF over SSH.
root@firefly1> show system connections | grep 830
tcp4 0 0 *.830 *.* LISTEN
The minimum configuration program for PyEZ to run is shown below. Here, the host name is changed from firefly1 to firefly1_changed_by_PyEZ.
set_firefly1_change_hostname.Excerpt from py's PyEZ setting part only
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
#Define the information to be controlled
dev1 = Device(
host="192.168.34.16",
user="user1",
password="password1"
)
dev1.open()
#Establish a session
dev1.open()
dev1.bind(cu=Config)
#Show host name
print "Hostname : ",
print dev1.facts["hostname"]
#Locked so that settings are not changed from other sessions
dev1.cu.lock()
#Configuration file(./configs/change_hostname.conf")Read
#At this point, the candidate config is only updated, and commit has not been executed.
conf_filename = "./configs/change_hostname.conf"
dev1.cu.load(path=conf_filename, format="text", merge=True)
#Execute commit check. Judge whether there is a problem with the settings.
print "Commit Check : ",
if dev1.cu.commit_check() :
print "OK"
else:
print "Error"
#Entrust the user to choose whether or not to commit(Of course, automatic commit is also possible)
print "Do you commit? y/n"
choice = raw_input().lower()
if choice == "y":
#Commit.
dev1.cu.commit()
print "Commit candidate config : OK"
else:
#Rollback without commit. The candidate config is deleted.
dev1.cu.rollback()
print "Rollback : OK"
#Session unlock
dev1.cu.unlock()
#End of session
dev1.close()
:./configs/change_hostname.conf
system {
host-name firefly1_changed_by_PyEZ;
}
With the above program, it is possible to submit the host name change config.
As a demo code, the one implemented with the display part added is published on github. https://github.com/taijiji/sample_pyez/blob/master/set_firefly1_change_hostname.py
The execution result is as follows.
I was able to change the Hostname using the same execution procedure as the manual setting. Of course, I was able to confirm that the host name of the actual router was changed.
Check the host name on the router
root@firefly1_changed_by_PyEZ>
root@firefly1_changed_by_PyEZ> show version
Hostname: firefly1_changed_by_PyEZ
Model: firefly-perimeter
JUNOS Software Release [12.1X47-D20.7]
Earlier, we used a statically generated config file in advance, but with PyEZ, it is possible to make a part of the config file variable as shown below by using the template engine.
interfaces {
{{ if_name }} {
unit 0 {
description {{ if_description }};
family inet {
address {{ if_address_ipv4 }}/{{ if_subnet_ipv4 }};
}
}
}
}
When using static config, it is necessary to prepare / manage similar config files for configuration settings with multiple parameters such as interface and BGP neighbor, and as a result, it is necessary to manage a large number of config files. It will come out. By making a part of the configuration file variable / template here, you can reduce the target of the configuration file to be managed.
PyEZ uses Jinaja2, one of the template engines, to make the config file variable. I have introduced Jinja2 on my blog in the past, so please refer to it here. How to use Template Engine for Network Engineer
Here, only the difference from PyEZ usage example 1 is introduced. Please check github for the sample code for the demo that you actually wrote. https://github.com/taijiji/sample_pyez/blob/master/set_firefly1_add_interface.py
set_firefly1_add_interface.Excerpt from py
dev1 = Device(
host="192.168.34.16",
user="user1",
password="password1"
)
dev1.open()
# interface ge-0/0/Display the settings of 2 in RPC format
if_info = dev1.rpc.get_interface_information(
interface_name='ge-0/0/2',
terse=True)
print etree.tostring(if_info)
#Specify the template file name
template_filename = "./configs/add_interface.jinja2"
#Specify variables in the template file
add_if_param = {
'if_name' : 'ge-0/0/2',
'if_description' : 'add_by_PyEZ',
'if_address_ipv4' : '192.168.35.1',
'if_subnet_ipv4' : '30'
}
#Load the config using the template file
dev1.cu.load(
template_path=template_filename,
template_vars=add_if_param,
format="text",
merge=True
)
#Commit config
dev1.cu.commit()
:./configs/add_interface.jinja2
interfaces {
{{ if_name }} {
unit 0 {
description {{ if_description }};
family inet {
address {{ if_address_ipv4 }}/{{ if_subnet_ipv4 }};
}
}
}
}
This is the execution result of the demo program.
Execution result
% python set_firefly1_add_interface.py
##### Operation : Start #######
Connecting to device : OK
Hostname : firefly1
Interfaces ge-0/0/2 :
##############################
<interface-information style="terse">
<physical-interface>
<name>
ge-0/0/2
</name>
<admin-status>
up
</admin-status>
<oper-status>
up
</oper-status>
</physical-interface>
</interface-information>
##############################
Load config :
OK
Target template : ./configs/add_interface.jinja2
##############################
interfaces {
ge-0/0/2 {
unit 0 {
description add_by_PyEZ;
family inet {
address 192.168.35.1/30;
}
}
}
}
##############################
Diff :
##############################
[edit interfaces]
+ ge-0/0/2 {
+ unit 0 {
+ description add_by_PyEZ;
+ family inet {
+ address 192.168.35.1/30;
+ }
+ }
+ }
##############################
Commit Check : OK
Do you commit? y/n
y
Commit candidate config : OK
Interfaces ge-0/0/2 :
##############################
<interface-information style="terse">
<physical-interface>
<name>
ge-0/0/2
</name>
<admin-status>
up
</admin-status>
<oper-status>
up
</oper-status>
<logical-interface>
<name>
ge-0/0/2.0
</name>
<admin-status>
up
</admin-status>
<oper-status>
up
</oper-status>
<description>
add_by_PyEZ
</description>
<filter-information>
</filter-information>
<address-family>
<address-family-name>
inet
</address-family-name>
<interface-address>
<ifa-local emit="emit">
192.168.35.1/30
</ifa-local>
</interface-address>
</address-family>
</logical-interface>
</physical-interface>
</interface-information>
##############################
##### Operation : End #####
It is a little difficult to understand because the information acquisition with PyEZ is in XML-RPC format, but you can see that the IP address and description are set to ge-0 / 0/2, which was not before the setting.
If you check it with an actual router, you can see that it is set as follows.
Check with router
root@firefly1> show configuration interfaces ge-0/0/2
unit 0 {
description add_by_PyEZ;
family inet {
address 192.168.35.1/30;
}
}
This time, we introduced PyEZ with a focus on usage examples. I have tried some functions that I did not introduce in this article, so please refer to the sample code on Github. https://github.com/taijiji/sample_pyez
Next time, I will introduce JSNAPy. I tried using PyEZ and JSNAPy. Part 3: I tried using JSNAPy
Recommended Posts