I have some time left, but since I had built the environment and acquired JUNOS information by the last time, I will try changing the JUNOS settings this time. ..
By using PyEz's jnpr.junos.utils.config.Config module, you can read ASCII text, Junos XML, or Junos OS set command files and change settings, or template-based settings using Jinja2 Template objects. Can be changed.
When changing the settings, the process is as follows: reading the settings and reflecting them by Commit, just like the JUNOS CLI.
Configuration Process
Specify [Options] at commit (https://www.juniper.net/techpubs/en_US/junos-pyez1.2/topics/task/program/junos-pyez-program-configuration-committing.html) You can also leave a comment or synch when RE is redundant.
As for reading the settings, like load replace, load merge, or load overwrite of JUNOS CLI, specify overwrite or add and change the settings. This is when you do a load operation, specify merge and overwrite parameters (https://www.juniper.net/techpubs/en_US/junos-pyez1.2/topics/reference/general/junos-pyez-configuration- Can be selected by (process-and-data-formats.html).
This time, I will try the method of reading an ASCII text file and adding settings, and adding template-based settings using Jinja2.
Extension for Load File (https://www.juniper.net/techpubs/en_US/junos-pyez1.2/topics/task/program/junos-pyez-program-configuration-data-loading.html) Specify ASCII text (.conf, .text, .txt), Junos set command (.set), XML (.xml) as children.
When reading, the file is read by specifying the path of the file with the path parameter. For example
conf_file = "configs/junos-config-add-syslog-ntp.conf"
cu.load(path=conf_file, format="text", merge=True)
As a sample, the case where adding the ntp notice setting of syslog is performed by PyEz is shown. Prepare a configuration file for reading in addition to the python file.
junos-config-add-syslog-ntp.conf
system {
syslog {
file messages {
ntp notice;
}
}
}
Here is a Python sample.
ch-config-ntp.py
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
conf_file = 'configs/junos-config-add-syslog-ntp.conf'
# open a connection with the device and start a NETCONF session
dev = Device(host='10.0.0.243', user='xxx', password='xxx', port='22', gather_facts=False)
dev.open()
dev.bind(cu=Config)
# Lock the configuration, load configuration changes, and commit as load merge
print "Locking the configuration"
dev.cu.lock()
print "Loading configuration changes"
dev.cu.load(path=conf_file, merge=True)
print "Committing the configuration"
dev.cu.commit(comment='Loaded by example.')
print "Unlocking the configuration"
dev.cu.unlock()
# End the NETCONF session and close the connection
dev.close()
An exception is also available in the jnpr.junos.exception module. Therefore, in order to check the error when it cannot be executed, if you exclude it in each process, it will be as follows.
ch-config-ntp-exception.py
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import ConnectError
from jnpr.junos.exception import LockError
from jnpr.junos.exception import UnlockError
from jnpr.junos.exception import ConfigLoadError
from jnpr.junos.exception import CommitError
conf_file = 'configs/junos-config-add-syslog-ntp.conf'
def main():
# open a connection with the device and start a NETCONF session
try:
dev = Device(host='10.0.0.243', user='xxxx', password='xxxx', port='22
', gather_facts=False)
dev.open()
except ConnectError as err:
print "Cannot connect to device: {0}".format(err)
return
dev.bind(cu=Config)
# Lock the configuration, load configuration changes, and commit
print "Locking the configuration"
try:
dev.cu.lock()
except LockError as err:
print "Unable to lock configuration: {0}".format(err)
dev.close()
return
print "Loading configuration changes"
try:
dev.cu.load(path=conf_file, merge=True)
except (ConfigLoadError, Exception) as err:
print "Unable to load configuration changes: {0}".format(err)
print "Unlocking the configuration"
try:
dev.cu.unlock()
except UnlockError:
print "Unable to unlock configuration: {0}".format(err)
dev.close()
return
print "Committing the configuration"
try:
dev.cu.commit(comment='Loaded by example.')
except CommitError as err:
print "Unable to commit configuration: {0}".format(err)
print "Unlocking the configuration"
try:
dev.cu.unlock()
except UnlockError as err:
print "Unable to unlock configuration: {0}".format(err)
dev.close()
return
print "Unlocking the configuration"
try:
dev.cu.unlock()
except UnlockError as err:
print "Unable to unlock configuration: {0}".format(err)
# End the NETCONF session and close the connection
dev.close()
if __name__ == "__main__":
main()
By using Jinja2, you can easily create similar configs using templates. Jinja2 is a Python template engine, and Origin of the name seems to be template ⇒ temple ⇒ shrine. Jinja2 templates use ASCII text, Junos XML elements, and Junos OS set commands in supported formats, just like reading files. In the Format of the Jinja template, {% ...%} and {{...}} are variable parts. So, all other parts are fixed phrases. {% ...%} executes variable declaration / assignment, loop processing, etc. {{...}} is the result display See here for the control structures used for {%.
To use the template, use the load () method under Options [https://www.juniper.net/techpubs/en_US/junos-pyez1.2/topics/task/program/junos-pyez-program-configuration- Specify the template in data-loading.html). Specify the template file with template_path and the parameters with template_vars.
cu.load(template_path=conf_file, template_vars=config, merge=True)
This time, I will use a template to add mpls and rsvp settings to each interface, and read the interface name etc. which are parameters with a yaml file. The template is also ASCII text.
Click here for template file
junos-config-interfaces-mpls.conf
interfaces {
{% for item in interfaces %}
{{ item }} {
description "{{ description }}";
unit 0 {
family {{ family }};
}
} {% endfor %}
}
protocols {
mpls {
{% for item in interfaces %}
interface {{ item }};
{% endfor %}
}
rsvp {
{% for item in interfaces %}
interface {{ item }};
{% endfor %}
}
}
Click here for parameter file
mpls_interface.yml
---
interfaces:
- ge-0/0/0
- ge-0/0/1
description: 'MPLS interface'
family: mpls
Basically, based on the same script (ch-config-ntp-exception.py) as when reading the file, only the template and parameters are specified by load (), so only the different parts are extracted.
add-config-mpls-template.py excerpt
import yaml
conf_file = 'configs/junos-config-interfaces-mpls.conf'
yml_config = yaml.load(open('configs/mpls_interface.yml'))
dev.cu.load(template_path=conf_file, template_vars=yml_config, merge=Tru
e)
With this, mpls and rsvp settings for the specified interface can be added.
As I wrote a lot this time, I was able to confirm that JUNOS settings can be changed using PyEz. In PyEz, in addition to information acquisition and setting change, config comparison, OS upgrade, file transfer by scp, etc. are also possible.
It may be difficult to touch without understanding both JUNOS and PyEz, but even engineers who are not familiar with Python can easily check the necessary parameters and change the settings. If you create a mechanism that allows you to hit on the web using these, even non-expert network engineers can check and change, and by linking with other systems, you can dynamically change settings according to the situation. Utilization methods are likely to expand depending on ideas such as creating infrastructure.
In the future, I plan to try other Automation Stacks on an irregular basis.
Recommended Posts