LoginSignup
3

More than 5 years have passed since last update.

posted at

updated at

Juniper JUNOS PyEz (python library)を試すメモ 3 ~PyEzによる設定変更~

時間が空いてしまいましたが、前回までに環境構築とJUNOSの情報取得をしたため、今回は、JUNOSの設定変更を試してみる。

1.概要

PyEzのjnpr.junos.utils.config.Configモジュールを使用することで、ASCII text, Junos XML, or Junos OS setコマンドのファイルを読み込み、設定変更をしたり、Jinja2 Template objectsを使ったテンプレートベースの設定変更が可能。

設定変更を行う場合は、JUNOSのCLIと同じように設定読込とCommitによる反映という、以下のようなプロセスで行われる。

Configuration Process

  • lock() - コンフィグレーションのロック
  • load() - 設定の読込 (rollback()やrescue()による設定戻しも可)
  • commit() - 設定の反映
  • unlock() - コンフィグレーションのアンロック

commit時のオプションを指定して、コメントを残したり、RE冗長時にsynchさせたりすることもできる。

尚、設定の読込は、 こちらもJUNOSのCLIの load replace, load merge, or load overwriteと同じく、上書きや追加の指定して設定変更する。
これは、loadオペレーションのときに、mergeおよびoverwriteパラメータを指定することで、選択可能。

今回はASCII textのファイルを読み込んで設定追加をする方法と、Jinja2を使ったテンプレートベースの設定追加を試してみる。

2.ファイルからのコンフィグレーション読み込み

ファイルの読み込みの場合、拡張子でASCII text(.conf,.text,.txt), Junosのsetコマンド(.set), XML(.xml)を指定する。

読み読み時に、pathパラメータでファイルのパスを指定することで、そのファイルを読み込む。
例えば、

conf_file = "configs/junos-config-add-syslog-ntp.conf"
cu.load(path=conf_file, format="text", merge=True)

サンプルとして、syslogのntp notice設定を追加するのをPyEzで行う場合を示す。
pythonファイルの他に読込用のコンフィグレーションファイルを用意。

junos-config-add-syslog-ntp.conf
system {
    syslog {
        file messages {
            ntp notice;
        }
    }
}

こちらがPythonのサンプル。

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()

尚、 jnpr.junos.exceptionモジュールでexceptionも用意されているため、実行できなかったときのエラー確認のために、それぞれのプロセスでexceptしておくと以下のようになる。

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()

3.Jinja2テンプレートの活用

Jinja2を使うことで、テンプレートを利用して、類似コンフィグが容易に作成することもできる。
Jinja2とは、Pythonのテンプレートエンジンで、名前の由来は、テンプレート ⇒ テンプル ⇒ 神社、のようだ。
Jinja2のテンプレートは、ファイル読込と同じく、サポートされたフォーマットのASCII text, Junos XML elements, Junos OS setコマンドを使用する。
Jinjaのテンプレートのフォーマットは、{% ... %} や {{ ... }} が可変部分で、それ以外の部分はすべて定型文となる。
 {% ... %} は変数宣言・代入やループ処理などを実行
 {{ ... }} は結果の表示
{%に使用するの制御構造はこちらを参照。

テンプレートを使用する方法は、load()メソッドのオプションでテンプレートを指定。
template_pathでテンプレートのファイルを指定し、template_varsでパラメータを指定。

cu.load(template_path=conf_file, template_vars=config, merge=True)

今回は、各interfaceにmpls,rsvpの設定追加をするテンプレートを使用し、パラメータであるinterface名などはyamlファイルで読込んでみる。テンプレートもASCII textにしている。

テンプレートファイルはこちら

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 %}
    }

}

パラメータファイルはこちら

mpls_interface.yml
---
interfaces:
    - ge-0/0/0
    - ge-0/0/1
description: 'MPLS interface'
family: mpls

基本的には、ファイル読み込みの時と同じスクリプト(ch-config-ntp-exception.py)をベースにして、load()でテンプレートやパラメータを指定しているだけのため、異なる部分だけ抜粋する。

add-config-mpls-template.py抜粋

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)

これで指定したinterfaceに対するmpls, rsvpの設定が追加できる。

4.まとめ

今回もつらつら書いたが、PyEzを使って、JUNOSの設定変更ができることが確認できた。
PyEzでは、情報取得や設定変更以外にも、configの比較、OSのアップグレード、scpによるファイル転送なども可能。

JUNOSとPyEzの両方を把握しないと触りにくいかもしれないが、Pythonを詳しく知らないエンジニアでも、簡単に必要なパラメータの確認や、設定変更ができそう。これらを使って、webで叩けるように仕組みを作っておくと、エキスパートのネットワークエンジニア以外でも確認や変更ができたり、他システムと連携させることで、ダイナミックに状況にあわせて設定変更が可能なネットワークインフラを作るなど、アイデア次第で活用方法は広がりそうだ。

今後は不定期に、ほかのAutomation Stackなども試してみる予定。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3