てくなべ (tekunabe)

ansible / network / automation / StackStorm

【nornir】Python 製自動化フレームワーク「nornir」かんたんチュートリアル(Ansibleと比較しながら)

■ nornir とは

nornir は、Python 製の新しい自動化フレームワークです。バージョン 1.0.0 は2018年5月にリリースされました。 netmiko や NAPALM も取り込んでいるため、ネットワーク機器にも対応しています。 この記事では、ネットワーク機器を対象としたチュートリアルをご紹介します。

github.com

https://nornir.readthedocs.io/en/stable/index.html

Ansible との比較

Ansible や Salt は構成の定義を YAMLDSLという見方もできると思います)で記述します。 一方 nornir は純粋に Python のライブラリなので、実現したいことを Python でコーディングします。 Ansible で Playbook を書いていて、だんだん複雑になり「コードで書きたいな・・」と思ったときに、代替手段になるかもしれません。

netmiko や NAPALM との比較

ネットワーク機器への自動化といえば、netmikoNAPALMといった、Python ライブラリもあります。 nornir は これらのライブラリの機能に、インベントリや変数管理の仕組みをつけたフレームワークのようなものです。

requirements.txt を確認すると分かるように、nornir をインストールすると、netmiko や NAPALM もインストールされます。


■ インストールは pip install nornir

nornir のインストール手順は以下の通りです。

pip install nornir

必要に応じて virtualenv などを利用して、環境を分けてください。


チュートリアル: Junos の 2台 の show version 結果を表示

インストールができたところで、Juniper Junos の 2台の show version コマンド結果を表示するチュートリアルをはじめます。 説明のために、同じことを Ansible で実現する場合と比較しながら説明します。

インベントリと変数定義の準備

対象ホストを定義するインベントリと、それらに適用される変数定義のファイルを準備します。

nornir の場合

hosts.yaml(今回のコードの場合、ファイル名は固定)で、ホストの名前、所属させるグループ、実際に接続する IP アドレスを定義します。

vsrx1:
  groups:
    - junos
  nornir_host: 172.16.0.1
vsrx2:
  groups:
    - junos
  nornir_host: 172.16.0.2

続いて、groups.yaml(今回のコードの場合、ファイル名は固定)で、グループの名前、と利用する変数(ログイン情報など)を定義します。

junos:
  nornir_username: root
  nornir_password: pasword9999
  nornir_nos: junos

hosts.yaml 内の groups で指定した junos が、groups.yml 内の junos に対応します。

Ansible の場合

Ansible の場合は、以下のようなインベントリファイルと、グループ変数定義ファイルを用意します。

  • inventory.ini
[junos]
vsrx1 ansible_host=172.16.0.1
vsrx2 ansible_host=172.16.0.2
  • group_vars/junos.yaml
---
ansible_network_os: junos
ansible_connection: netconf   # 今回は network_cli でも可
ansible_user: root
ansible_password: pasword9999

実行ファイルの準備

nornir の場合

hosts.yamlgroups.yaml と同じディレクトに、以下の Python スクリプトを作成します。

  • show_version.py
from nornir.core import InitNornir
from nornir.plugins.functions.text import print_result
from nornir.plugins.tasks.networking import napalm_cli

# オブジェクトの初期化
nr = InitNornir()

# 実行
results = nr.run(
    # コマンドを直接実行するタスク napalm_cli を呼び出して、コマンドは show version を指定
    task=napalm_cli, commands=["show version"]  
)

# nornir 用の出力関数で結果を出力
print_result(results)

今回は、何も指定していませんが、InitNorir で初期化時に、パラメータを渡すことによって、ホストファイル名の指定などの設定ができます。詳細は API ドキュメントを参照してください。

Ansible の場合

以下の Playbook を作成します。

  • show_version.yml
- hosts: all
  gather_facts: no

  tasks:
    - name: show version
      junos_command:
        commands:
          - show version
      register: result

    - name: debug version
      debug:
        msg: "{{ result.stdout_lines[0] }}"

実行

nornir の場合

python コマンドで、先ほど作成したスクリプトを実行します。

$ python test.py
napalm_cli**********************************************************************
* vsrx1 ** changed : False *****************************************************
vvvv napalm_cli ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
{ u'show version': u'\nHostname: vsrx1\nModel: firefly-perimeter\nJUNOS Software Release [12.1X47-D15.4]\n'}
^^^^ END napalm_cli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* vsrx2 ** changed : False *****************************************************
vvvv napalm_cli ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
{ u'show version': u'\nHostname: vsrx2\nModel: firefly-perimeter\nJUNOS Software Release [12.1X47-D15.4]\n'}
^^^^ END napalm_cli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

nornir を利用したコードで、無事に show version コマンドの結果が表示されました。

以下のような色になります。 f:id:akira6592:20181016172526p:plain

Ansible の場合

$ ansible-playbook -i inventory.ini show_versoin.yml

PLAY [all] *******************************************************************

TASK [show version] **********************************************************
ok: [vsrx1]
ok: [vsrx2]

TASK [debug version] *********************************************************
ok: [vsrx1] => {
    "msg": [
        "Hostname: vsrx1",
        "Model: firefly-perimeter",
        "JUNOS Software Release [12.1X47-D15.4]"
    ]
}
ok: [vsrx2] => {
    "msg": [
        "Hostname: vsrx2",
        "Model: firefly-perimeter",
        "JUNOS Software Release [12.1X47-D15.4]"
    ]
}

PLAY RECAP *******************************************************************
vsrx1                      : ok=2    changed=0    unreachable=0    failed=0
vsrx2                      : ok=2    changed=0    unreachable=0    failed=0

こちらも無事に show version コマンドの結果が表示されました。


■ まとめ

今回は、簡単な show コマンド実行するだけのサンプルをご紹介しました。 他にも、設定系コマンドや、show コマンドの結果をパースして表示する機能などもあります。

「コードで処理を書きたい。でも Ansible のようなインベントリや変数管理の仕組みは欲しい。」という場合に、nornir が候補になるかもしれません。


■ 参考


Nornir - Python automation framework [Part 16] Network Programmability Stream