Help us understand the problem. What is going on with this article?

Juniper JUNOS PyEz (python library)を試すメモ 2 ~PyEzによる情報取得~

More than 3 years have passed since last update.

前回PyEzの環境構築ができたため、今回は実際にJUNOSの情報取得を試してみる。

PyEzを使った情報取得方法はいくつかあるが、今回はこの三つを試してみました。

  1. 事前に定義されている簡単に基本的な情報を取得できるfactsの活用
  2. YAMLファイルで定義された内容を取得できるTable and Viewの活用
  3. RPC(remote procedure calls)によるJUNOS showコマンドと同等の確認

1.JUNOS情報取得(facts)

まずは、非常にシンプルだが、PyEzのHello worldとして、サーバーからJUNOSにコネクションを張り、factsにより基本的な情報(hostname,version情報など)を取得してみる。
factsは、NETCONFセッション確立時にJUNOSから収集した基本的な情報を表示する。
概要はTech Libraryに動作サンプルの動画もあるが、詳細はGitHubで確認可能。

#JUNOSと接続するためにDeviceモジュールをインポート
>>> From juniper. Junos import Device 
#デバイス情報を定義
>>> dev=Device(host='10.0.0.243', user="xxx", password="xxx", port='22')
#netconf over sshでJUNOSに接続
>>> Dev. open ()        
Device(1.1.1.1)
#factsにより基本情報表示
>>> print dev.facts 
{'domain': None, 'hostname': 'vSRX-1', 'ifd_style': 'CLASSIC', 'version_info': junos.version_info(major=(15, 1), type=X, minor=(49, 'D', 50), build=3), '2RE': False, 'serial number': 'xxxxx', 'fqdn': 'vSRX-1', 'switch_style': 'NONE', 'version': '15.1X49-xxx', 'HOME': '/var/home/vsrx', 'srx_cluster': False, 'model': 'VSRX', 'RE0': {'status': 'Testing', 'last_reboot_reason': '0x10: Misc hardware reason ', 'model': 'VSRX RE', 'up_time': '44 minutes'}, 'vc_capable': False, 'personality': 'UNKNOWN'}
#factsによりversion情報だけ表示
>>> dev.facts['version']
'15.1X49-xxx'
>>> dev.facts['hostname']
'vSRX-1‘

dev.close()
>>> quit()

factsを使ってOSのバージョン情報を取得してテキストに書き出すサンプル

from jnpr.junos import Device
from datetime import datetime

mydeviceslist=["1.1.1.1"]
f=open("my_devices_inventory.txt", "a")
f.write(str(datetime.now()) + '\n')
for item in mydeviceslist:
        dev=Device(host=item, user="xxx", password="xxx",port='22')
        dev.open()
        dev.close()
        print ("the device "+ dev.facts["hostname"]+ " is a " + dev.facts['model
'] + " running " + dev.facts["version"])
        f.write ( "the device "+ dev.facts["hostname"]+ " is a " + dev.facts['mo
del'] + " running " + dev.facts["version"] + "\n")
f.close()

実行結果

$ python print_facts.py
the device vSRX-1 is a VSRX running 15.1X49-xxx
[ec2-user@ip-10-0-0-47 facts]$ more my_devices_inventory.txt
2016-08-22 08:01:29.396263
the device vSRX_AWS-1 is a VSRX running 15.1X49-xxx

2.JUNOS情報取得(Table and view)

jnpr.junos.opモジュールを使い、YAMLで定義されたTable and Viewにより各情報の取得ができる。
現在のopモジュールとしては、ドキュメントにあるようにarp, interface情報など基本的な情報が取得可能。
例として、ArpTableメソッドを使い、arp情報を取得してみる。

>>> from jnpr.junos.op.arp import ArpTable
>>> arp1=ArpTable(dev)
>>> arp1.get() 
ArpTable:10.0.0.243: 3 items
#keyの一覧取得
>>> arp1.keys()   
['0a:de:e9:03:15:3f', '0a:ca:89:ec:9a:51', '0a:93:06:42:03:c5']
#valuesの一覧取得
>>> arp1.values()   
[[('interface_name', 'fxp0.0'), ('ip_address', '10.0.0.1'), ('mac_address', '0a:de:e9:03:15:3f')], [('interface_name', 'fxp0.0'), ('ip_address', '10.0.0.47'), ('mac_address', '0a:ca:89:ec:9a:51')], [('interface_name', 'ge-0/0/0.0'), ('ip_address', '10.0.1.1'), ('mac_address', '0a:93:06:42:03:c5')]]]

RouteTableメソッドを利用して、ルーティング情報とデフォルトゲートウェイのテーブル情報を表示するサンプル

from jnpr.junos import Device
from jnpr.junos.op.routes import RouteTable

dev = Device(host='10.0.0.243', user='xxx', password='xxx', port='22', gathe
r_facts=False)
dev.open()

tbl = RouteTable(dev)
tbl.get()

#get values and keys
for key, value in tbl.items():
    print "key:%s,\t value:%s" %(key, value)

##print only GW information
print '##this is default gateway'

gw = RouteTable(dev)
gw.get('0.0.0.0')
print gw
for item in gw:
    print 'protocol:', item.protocol
    print 'age:', item.age
    print 'via:', item.via
    print

dev.close()

実行結果

key:0.0.0.0/0,   value:[('nexthop', '10.0.0.1'), ('age', 177947), ('via', 'fxp0.0'), ('protocol', 'Static')]
key:10.0.0.0/24,         value:[('nexthop', None), ('age', 177947), ('via', 'fxp0.0'), ('protocol', 'Direct')]
key:10.0.0.243/32,       value:[('nexthop', None), ('age', 181163), ('via', 'fxp0.0'), ('protocol', 'Local')]
key:10.0.1.0/24,         value:[('nexthop', None), ('age', 181145), ('via', 'ge-0/0/0.0'), ('protocol', 'Direct')]
key:10.0.1.68/32,        value:[('nexthop', None), ('age', 181146), ('via', 'ge-0/0/0.0'), ('protocol', 'Local')]
key:10.0.2.98/32,        value:[('nexthop', None), ('age', 181144), ('via', 'ge-0/0/1.0'), ('protocol', 'Direct')]
key:10.0.3.85/32,        value:[('nexthop', None), ('age', 181144), ('via', 'ge-0/0/2.0'), ('protocol', 'Direct')]
key:192.168.0.1/32,      value:[('nexthop', None), ('age', 181162), ('via', 'lo0.0'), ('protocol', 'Direct')]
##this is default gateway
RouteTable:10.0.0.243: 1 items
protocol: Static
age: 177947
via: fxp0.0

YAMLファイルを自分で定義して、Table and Viewを取得することもできる。
Gitに落ちてたサンプルとして、例えばこんな感じ。

3.JUNOS情報取得(RPC、showコマンド)

最後に、RPCを使いCLIのshowコマンドと同等の情報を取得してみる。

・showコマンドとRPCのマッピング

JUNOS XML APIは、JUNOSのコンフィグやオペレーションモードのコマンドをXMLで表したものだが、
RPCでリクエストすることで、XMLのレスポンスを得ることができる。
PyEzでは、RPCを実行することになるが、CLIのコマンドとRPCは、マッピングできるため、使いたいCLIをRPCとして使うことになる。

そのためには、どのCLIがどのRPCなのかを確認する必要があるが、方法として、2つ紹介する。
1. JUNOSの実機でshowコマンドで確認
使いたいshowコマンドのあとに| display xml rpcで確認する。例えばshow interfaceの場合、

> show interfaces  | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1X49/junos">
    <rpc>
        <get-interface-information>
        </get-interface-information>
    </rpc>
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>

2.PyEzのdisplay_xml_rpc()メソッドで確認
 dev.open()でJUNOSと接続後、dev.display_xml_rpcメソッドで使用したいshowコマンドを指定し確認。

>>> print dev.display_xml_rpc('show interface', format='text')
<get-interface-information>
</get-interface-information>
>>>

これらの確認により、show interfaceは、<get-route-information>というタグだとわかる。
次に、タグからRPCに変換する必要があるが、ハイフン( - )をアンダースコア( _ )に変え、山括弧を排除する。
すなわち、<get-interface-information>の場合、RPCは、get_interface_information() になる。
あとはこのRPCメソッドを使えばいい。
尚、オプションを指定しない場合、XMLで返ってくるため、lxml.etreeライブラリもインポートし、整形して表示するためにetree.tostring()を使う。

・show interfaceを確認するサンプル

from jnpr.junos import Device
from lxml import etree

  dev = Device(xxxx,xxx,xxx,xx)
  dev.open()

int=dev.rpc.get_interface_information()
print(etree.tostring(int))

・showコマンドオプション利用(値なし)
尚、showコマンドのオプションで、値を使用しないものの場合、RPCメソッドのパラメータで=Trueとすれば確認できる。

例えば、show interface terseを確認するサンプル

dev.open()
int=dev.rpc.get_interface_information(terse=True)
print(etree.tostring(int))

・showコマンドオプション利用(値あり)
showコマンドのオプションで値を利用する場合は、オプションのXMLを同じようにRPCメソッドに変換し、イコールでオプション指定

例えばshow interfaceのinterfaceを指定する場合のタグは、<interface-name> だとわかる。

> show interfaces ge-0/0/0 | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1X49/junos">
    <rpc>
        <get-interface-information>
                <interface-name>ge-0/0/0</interface-name>
        </get-interface-information>
    </rpc>
    <cli>

よってRPCとしては、interface_nameとなるので、以下のように指定する。

>>> int=dev.rpc.get_interface_information(interface_name='ge-0/0/0')
>>> print(etree.tostring(int))

また、dev.rpc.rpc_method(normalize=True)とすると、返信されたXMLをノーマライズすることもできる。また、返信をXMLでない方法で表示させるのもできそう。

4.まとめ

だらだらとメモのように書きましたが、
とりあえず、PyEzを使っていくつかの方法で情報取得を試してみました。
次回は設定変更をしてみようと思います。

5.参考リンク

  PyEz サンプルスクリプト集(on Git by Nitin Kumar)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away