Last time, I introduced Op Script, which is one of the easy ways to use Junos On-box Python.
Continuing from the last time, I would like to introduce Commit Script this time.
A Commit Script is a script of Junos scripting mechanism called Junoscript that is executed triggered by "commit by user".
The Commit Script is called when the user executes a commit, and controls the commit or modifies the committed config depending on the information such as the committed user and time, the config to be committed, the current state of the device, etc. You can do things like do.
For example, the following use cases are possible.
In the form of saying, various usages can be considered depending on the idea.
This time, I will introduce Commit Script in On-box Python with a simple sample.
In order to use Commit Script, you need to write the script you want to use in the settings as follows.
set system scripts language python
set system scripts commit file commit-script.py
The script described here should be prepared in / var / db / scripts / commit
.
If you want to enable the * Transient Configuration * change method among the setting change methods at Commit, make the following additional settings.
set system scripts commit allow-transients
Details will be described later, but it is necessary every time there is a setting that you want to dynamically generate from the script, such as expanding the setting by macro.
Now let's try Commit Script.
For example, the script that rejects a Config that does not have a host name set is:
commit-script.py
from junos import Junos_Configuration
import jcs
def main():
root = Junos_Configuration
if root.find('./system/host-name') == None:
jcs.emit_error("Hostname is not defined!!!")
if __name__ == '__main__':
main()
There are unique terms such as Junos_Configuration
and jcs
, but Junos-Configuration
is the XML root of the Configuration that is about to be committed, and you can check this to set it. You can check and change it.
jcs
is a namespace that defines methods for event generation, status acquisition, etc. in Commit Script. See the Official Documentation (https://www.juniper.net/techpubs/en_US/junos16.1/topics/concept/junos-script-automation-junos-extension-functions-jcs-namespace.html) for more information. please.
The content of the script is simple: extract the XML at the position / system / host-name
from the configuration, and when the result is None
, call jcs.emit_error
and get an error Is output.
The output result will be as follows.
[edit]
root@vmx1# show system host-name
host-name vmx1;
[edit]
root@vmx1# delete system host-name
[edit]
root@vmx1# commit check
error: Hostname is not defined!!!
error: 1 error reported by commit scripts
error: commit script failure
[edit]
root@vmx1# rollback 0
load complete
[edit]
root@vmx1# commit check
configuration check succeeds
In this way, the Commit check will only fail if the host name is not included.
By the way, if you want to pass the Commit check but only display the warning, use jcs.emit_warning
instead of jcs.emit_error
.
Next, I would like to introduce an example of changing the settings.
There are two ways to change the settings, one is to make permanent edits like a normal user, and the other is to make non-persistent (transient) edits.
First, let's try permanent editing. For example, here is an example script that changes the system timezone to ʻAsia / Tokyo`:
commit-script.py
import jcs
def main():
xml = '<system><time-zone>Asia/Tokyo</time-zone></system>'
jcs.emit_change(xml, "change", "xml")
if __name__ == '__main__':
main()
The settings can be changed by specifying the changes, change method, and format in the jcs.emit_change
method. The format is currently xml only.
When I run this script, it looks like this:
[edit]
root@vmx1# show system time-zone
[edit]
root@vmx1# commit check
configuration check succeeds
[edit]
root@vmx1# show | compare
[edit system]
+ time-zone Asia/Tokyo;
In this way, the time zone is added when the Commit Script is executed.
The following is an example of implementing a so-called macro thing and transparently reflecting the generated settings on the device. As an example (I can't think of a simple and good example), here is an example script that defines the Default Description of an interface and sets the Default Description when there is an interface that does not contain a Description. Will be.
commit-script.py
from junos import Junos_Configuration
import jcs
def main():
root = Junos_Configuration
apply_macro = root.find("./interfaces/apply-macro[name='default-description']")
xml_tmpl = '<interfaces>{0}</interfaces>'
interface_xml_tmpl = '<interface><name>{0}</name><description>{1}</description></interface>'
xml = ""
if apply_macro:
description_template = apply_macro.find('./data/name').text
for element in root.findall("./interfaces/interface"):
if element.find('description') is None:
ifd_name = element.find('name').text
xml += interface_xml_tmpl.format(ifd_name, description_template.format(ifd_name))
xml = xml_tmpl.format(xml)
jcs.emit_change(xml, "transient-change", "xml")
if __name__ == '__main__':
main()
In this script, if Macro called default-description
is defined directly under interfaces, the interface list is checked, and for interfaces for which Description is not set, the text specified in the default-description macro is specified. Make a move.
The point of generating changes in XML is the same as before, but the second argument of jcs.emit_change
has changed from"change"
to"transient-change"
. This is an option to treat the setting as temporary and not save it in the configuration file.
As mentioned above, when using transient-change
, it is necessary to input the following settings.
set system scripts commit allow-transients
When this script is applied, it behaves as follows.
root@vmx1# show interfaces | display set
set interfaces apply-macro default-description "Description is not configured({0})"
set interfaces ge-0/0/0 disable
set interfaces ge-0/0/0 vlan-tagging
set interfaces ge-0/0/0 unit 1001 vlan-id 1001
set interfaces ge-0/0/0 unit 1001 family inet address 10.0.1.1/24
set interfaces ge-0/0/1 description test
set interfaces ge-0/0/1 unit 0 family inet
set interfaces fxp0 unit 0 family inet address 172.23.1.111/24
[edit]
root@vmx1# commit
commit complete
[edit]
root@vmx1# run show interfaces descriptions
Interface Admin Link Description
ge-0/0/0 down down Description is not configured(ge-0/0/0)
ge-0/0/1 up down test
fxp0 up up Description is not configured(fxp0)
[edit]
root@vmx1# run show configuration interfaces | display set
set interfaces apply-macro default-description "Description is not configured({0})"
set interfaces ge-0/0/0 disable
set interfaces ge-0/0/0 vlan-tagging
set interfaces ge-0/0/0 unit 1001 vlan-id 1001
set interfaces ge-0/0/0 unit 1001 family inet address 10.0.1.1/24
set interfaces ge-0/0/1 description test
set interfaces ge-0/0/1 unit 0 family inet
set interfaces fxp0 unit 0 family inet address 172.23.1.111/24
Can you see the difference from the previous one? In # 2, the settings were changed during the commit check stage, and the changes appeared in the settings. On the other hand, if you use transient-change
, it seems that the config has not been changed at first glance, but if you check the actual operation, you can see that the Description is set in Interface.
With transient-change
, it is possible to macroize the settings in this way and hide the actual device settings other than the essential parameters. For example, if there are a large number of customers and a large number of settings are required, but the differences between customers are insignificant, it will be possible to make settings efficiently and with good visibility.
By the way, if you want to check the settings that are actually running on the device, you can check as follows.
root@vmx1> show configuration interfaces | display set | display commit-scripts
set interfaces apply-macro default-description "Description is not configured({0})"
set interfaces ge-0/0/0 description "Description is not configured(ge-0/0/0)"
set interfaces ge-0/0/0 disable
set interfaces ge-0/0/0 vlan-tagging
set interfaces ge-0/0/0 unit 1001 vlan-id 1001
set interfaces ge-0/0/0 unit 1001 family inet address 10.0.1.1/24
set interfaces ge-0/0/1 description test
set interfaces ge-0/0/1 unit 0 family inet
set interfaces fxp0 description "Description is not configured(fxp0)"
set interfaces fxp0 unit 0 family inet address 172.23.1.111/24
This time, I introduced Commit Script as one of the uses of Junoscript by On-box Python. I hope you can understand that there are many possible uses. The contents introduced this time can only be implemented using XSLT / Slax, but I think that it has become possible to write in Python and it has become very easy to get involved.
Next time, I would like to introduce how to use it in Event Script.
Recommended Posts