IOS-XRでpythonのipaddressが使える話


この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2024 ２枚目の12月3日向けの記事として書かれています。

https://qiita.com/advent-calendar/2024/cisco


### TL;DR
IOS-XRでもpythonのipaddressが使えます！以上。

こんな出オチの記事ある？タイトルもっと考えてつければよかった…
ここから書く意味ない気がしますが、でも初参加のアドベントカレンダーを１行で終わらせるわけにはいかないので、以下全て蛇足だけどよかったら読んでください！


### 🎄🔔🎄🔔🎄🔔🎄

みなさま今年のクリスマスは何をしていますか？
ルーターのスケール検証？わかります。クリスマスの定番ですよね。

ではスケール検証のconfigどうやって作っていますか？
イケてるツールで自動化しても一番最初のconfigとか、とりあえず一回検証したいだけだからとか、まあいろいろ自分でスケールconfig作りたいことがありますよね？

そういう時、何使ってますか？エクセル? perl? python?
IOS-XRはconfigファイルを読み込めるし、手元でファイル作ってscpすればいいですよね？

``` ファイルをconfigに強制的に流し込む方法
RP/0/RP0/CPU0:router#conf t
Sat Nov 30 06:14:36.399 UTC
RP/0/RP0/CPU0:router(config)#load ?
  WORD           Load from file
  apphost:       Load from apphost: file system
  commit         Load commit changes
  config:        Load from config: file system
  configuration  Contents of configuration
  diff           Load from diff file
  disk0:         Load from disk0: file system
  ftp:           Load from ftp: file system
  harddisk:      Load from harddisk: file system
  http:          Load from http: file system
  https:         Load from https: file system
  rollback       Load rollback changes
  rootfs:        Load from rootfs: file system
  scp:           Load from scp: file system
  script         Load Perl/Tcl/Python configuration file (must be packaged on the router)
  sftp:          Load from sftp: file system
  tftp:          Load from tftp: file system
RP/0/RP0/CPU0:router(config)#load 
```

と思いついた瞬間、「ああああ！しまったぁ。私この構成、sshログインできるように配線してなかったぁ！！！」ってことも稀によくありますよね。
あとは社内ルール的にネットワーク接続できなくてscpできない時とか。

でも、クリスマスの六本木駅でカップルをかき分けてエスカレーターを駆け上がって会社に行き、configが入ったUSB挿したり、sshできるように配線するのは死んでもやりたくないですね。
(弊社オフィスおよびラボは六本木にあります。)

そんな時は奥の手、IOS-XR上のpythonでスケールconfigを作成することにします。
これでカップルの邪魔をしなくて済みます。

ここに誰かが作ってくれたいい感じのIOS-XRでpythonスクリプトを走らせるQiitaの記事を貼る予定だったのですが、既知すぎるのかIOS-XEはあるけど、IOS-XRはどこにもありませんでした。
仕方がないから自分で書くとこんな感じで、いつものコマンドラインからシェルに入りそこでpythonが使えます。

``` IOS-XRのコンソールからpythonスクリプト実行まで
RP/0/RP0/CPU0:router#
RP/0/RP0/CPU0:router#run
Sat Nov 30 01:23:08.082 UTC
pyth[xr-vm_node0_RP0_CPU0:~]$python
Python 2.7.18 (default, Nov  5 2023, 05:15:35) 
[GCC Clang 10.0.1 (https://github.com/llvm/llvm-project ef32c611aa214dea855364e on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

参考:　[Cisco Catalyst IOS-XEでのPythonやBash](https://qiita.com/kikuta2055/items/1739d7d7063a20b1736f)

でも…インターフェイス3000個にIPアドレス振るのも、トンネル3000個設定するのも、いちいち割り算して商を入れたり、余り入れたり面倒ですよね。

```Loopback3000個作りたい
for i in range(3000):
    third_octet = 1 + i // 256 !256回に一回インクリメントする
    fourth_octet = i % 256 !256で割った余りを第四オクテットのアドレスとする
    print ("int Loopback " + str(i+100))
    print(" ipv4 address 10.0." + str(third_octet) + "." + str(fourth_octet) + " 255.255.255.255")
```
こういうやつ。

と、ずっと思っていたのですが、世の中pythonにはipaddressというモジュールがあるらしい。スケール検証をperlとエクセルでやる界隈で一人ptyhonを書いていたので全然知りませんでした。なにより普通に足し算できるのとprintが簡単なのが最高です。

```
[xr-vm_node0_RP0_CPU0:~]$python3
Python 3.8.18 (default, Aug 24 2023, 19:48:18) 
[GCC 9.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ipaddress
>>> ip = ipaddress.ip_address("10.0.1.255") 
>>> ip += 1 !10.0.1.255の1つ後ろのアドレスは…
>>> print(str(ip)) !10.0.2.0です！
10.0.2.0
>>> 
```


ipaddressに関してはQiitaに素晴らしい記事もある。最高です。

https://qiita.com/Mabuchin/items/161d33f845ec0aeeb777

でもほら、IOS-XR上のpythonで使えるの…？？
ほらないし！

```
[xr-vm_node0_RP0_CPU0:~]$python
Python 2.7.18 (default, Jun 13 2024, 23:35:33) 
[GCC Clang 10.0.1 (https://github.com/llvm/llvm-project ef32c611aa214dea855364e on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ipaddress
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named ipaddress
>>> 
```

って賢い読者の方はお気づきですね。これはpythonのバージョンが2.7です。ipaddressが追加されたのは、python3.3なので、

```
[xr-vm_node0_RP0_CPU0:~]$python3
Python 3.8.18 (default, Aug 24 2023, 19:48:18) 
[GCC 9.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ipaddress
>>> 
```

IOS-XR上のpython3にipaddressはあります！！

### コンソール接続しかできないルーターにスケールconfigを入れる具体例

というわけで、ここからさらに蛇足のコンソール接続しかできないルーターにループバックインターフェイスを3000個切る方法です。そろそろ蛇がトカゲになりそうです。

```
RP/0/RP0/CPU0:router#run !shellに入る
Sat Nov 30 08:06:41.582 UTC　
[xr-vm_node0_RP0_CPU0:~]$vi looback.py　!スクリプトファイルを編集
```
上のようにしてviを起動したら、(ChatGPTにつくらせた)スクリプトを流し込む。iを押してviを挿入モードにしてWebからコピーしたものを挿入する。

![vi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207624/f64e1a2a-310c-c0d5-9c36-5a3947b43d85.png)


上でコピペしたスクリプトはこれ。

```上でコピペしたスクリプト
import ipaddress

# Starting IP address
start_ip = ipaddress.ip_address('10.0.1.0')

# Generate and print 3000 IP addresses
for i in range(3000):
    current_ip = start_ip + i
    print(" int Loopback " + str(i+100))
    print("  ipv4 address " + str(current_ip) + " 255.255.255.255")
```
Ctrl+vで挿入できたらEscを押し、その後:wqと打つとファイルが保存される。
viを終了してshellに戻ったら以下の手順でスクリプト実行、からconfig適用だ。

```
[xr-vm_node0_RP0_CPU0:~]$python3 loopback.py > loopback_list.txt !スクリプトを実行してconfigテキストを作成
[xr-vm_node0_RP0_CPU0:~]$pwd !ファイルの位置確認
/disk0:
[xr-vm_node0_RP0_CPU0:~]$exit !shellから抜ける
logout

RP/0/RP0/CPU0:router#conf t !configモードに移行する
Sat Nov 30 08:09:59.905 UTC
RP/0/RP0/CPU0:router(config)#load disk0:loopback_list.txt
179619 bytes processed in 5 sec, current rate 35910 bytes/sec....
181479 bytes parsed in 5 sec (36290)bytes/sec
RP/0/RP0/CPU0:router(config)#commit
```

これで君の手元にはLoopbackインターフェイスが3000個あるルーターができているはずだ。
では、よいスケール検証ライフを！Happy Holidays!

(ルーターのスケール試験の際にはルーターが対応するリソースの最大数をご確認の上ご利用ください)