Cisco IOS と IOS-XR の config のテキストファイルをいい感じに grep してくれる CLI コマンドを作成しました。その名も、cfgrepです。
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2023 の 2 日目として投稿しています。
背景
多くのネットワークエンジニアは、ローカルに保存された config ファイルの内容を確認することがあると思います。そして、数千行または数万行の中から特定の内容を抽出するために、grepコマンド、lessコマンドの検索機能、またはテキストエディタの検索機能を利用していると思います。しかし、「grepで -A とか -B で近い行を抽出したいが不十分」、「検索結果が多すぎてコピーペーストが大変」といったことはないでしょうか。
そのような問題を解決するためのコマンドが cfgrep です。cfgrep はインデントの親子構造(階層構造)を理解して、 grepを行います。
できること
cfgrep で指定した文字列パターン(正規表現)が現れる行を検索し、その親行と子行を再帰的に出力します。
具体的な使用例を以下に示します。例では、interface IDを正規表現で指定し、その親行と子行を再帰的に出力しています。他に有効に使用する例を、後述の「オプション」の項で紹介します。
> cfgrep "TenGigE0/0/[0-2]/0" XR.txt
!
interface TenGigE0/0/0/0
description test1
ipv4 address 203.0.113.1 255.255.255.252
ipv6 address 2001:db8:1::1/64
!
interface TenGigE0/0/2/0
description test2
ipv4 address 203.0.113.5 255.255.255.252
ipv6 address 2001:db8:2::1/64
!
router ospf 1
area 0
interface TenGigE0/0/0/0
cost 10
network point-to-point
!
router ospf 1
area 0
interface TenGigE0/0/2/0
cost 10
network point-to-point
!
router ospfv3 1
area 0
interface TenGigE0/0/0/0
cost 10
network point-to-point
!
router ospfv3 1
area 0
interface TenGigE0/0/2/0
cost 10
network point-to-point
!
rsvp
interface TenGigE0/0/0/0
bandwidth 10000000
!
mpls traffic-eng
interface TenGigE0/0/0/0
backup-path tunnel-te 1
!
mpls ldp
interface TenGigE0/0/0/0
!
multicast-routing
address-family ipv4
interface TenGigE0/0/2/0
disable
!
router pim
address-family ipv4
interface TenGigE0/0/0/0
使用シチュエーション例
- 商用設計を確認するために、確認したい内容に関連する config を抽出して確認する。
- 商用 config から検証 config を作成するときに、必要な config だけを抽出する。
- 障害時に緊急で手順にない方法で復旧する際、焦って一部の config のみを抽出して作成するのではなく、漏れなく作成する。
- たとえば interface の設定の移設だけでなく、関連するルーティング設定の移設も漏れなく行う
インストール方法
cfgrep の利用には Python3 が必要です。事前にインストールしてください。
cfgrep は PyPI から pip でインストール可能です。
pip install cfgrep
もしインストール後も cfgrep コマンドが使用できない場合は、インストールされたディレクトリに PATH を通してください。私の Mac でpython3.8 を使用している環境では/Users/$USER/Library/Python/3.8/bin
にPATHを通す必要がありました。
PyPI からはどうしてもうまくいかない場合は、GitHubの README に他のインストール方法を記載しましたので、試してみてください。
使用方法
下記の -h オプションの通りです。
入力はファイルにのみ対応しており、パイプ処理には対応していません。
> cfgrep -h
Overview:
cfgrep(c4grep, ccccgrep) is Cisco Config Context-aware Check grep
Usage:
cfgrep <PATTERN> <FILE> [-i | --interface] [-b | --bgp] [-d | --description]
cfgrep -h | --help
Options:
-i, --interface interface mode
-b, --bgp bgp mode
-d, --description to specify PATTERN by description
-h, --help display help
オプション
help 以外では、3個のオプションがあります。
オプション | 説明 |
---|---|
-i | interface モード。interface の ipv4 と ipv6 アドレスに関連する config も出力します。 |
-b | BGP モード。BGP neighbor に紐づく route-policy(IOS-XR の場合。IOS の場合は route-map)と bgp-group(IOS-XRの場合。IOS の場合は peer-group)も出力します。 |
-d | description mode。description 行の親を PATTERN とみなして、その PATTERN で cfgrep を実行します。 |
この説明ではそれぞれのオプションがどのように役立つのか分かりにくいので、使用例を下記に示します。
interface モード(-i)の例
- interface を指定すると、それに紐づく OSPF network 行も出力されています。
> cfgrep -i "Vlan10$" ios.txt
!
interface Vlan10
description test
ip address 203.0.113.1 255.255.255.252
ip ospf cost 10
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! ipv4 address search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
router ospf 1
network 203.0.113.0 0.0.0.3 area 0
BGP モード(-b)の例
- BGP neighbor address を指定すると、それに紐づく neighbor-group と route-policy も出力されています。
> cfgrep -b 203.0.113.1 XR.txt
!
router bgp 65000
neighbor 203.0.113.1
use neighbor-group TEST
description test
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! neighbor-group search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
router bgp 65000
neighbor-group TEST
remote-as 65000
update-source Loopback0
address-family ipv4 unicast
route-policy PASS in
route-policy PASS out
next-hop-self
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! route-policy search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
route-policy PASS
pass
end-policy
description モード(-d)の例
- description として CoreGroup を指定すると、それに紐づく interface TenGigE0/0/0/0, TenGigE0/0/2/0 と BGP の neighbor 198.51.100.2 を検索し、それに対してさらに cgrep しています。
- -d オプションを使用しないと、inteface ID と neighbor address くらいしか出力されません。
> cfgrep -dbi CoreRouter XR.txt
!
interface TenGigE0/0/0/0
description CoreRouter Te0/0/0/0
ipv4 address 203.0.113.5 255.255.255.252
ipv6 address 2001:db8:beef:1::1/64
ipv6 enable
!
interface TenGigE0/1/0/0
description CoreRouter Te0/1/0/0
ipv4 address 203.0.113.9 255.255.255.252
ipv6 address 2001:db8:beef:2::1/64
ipv6 enable
!
router bgp 65000
neighbor 198.51.100.2
use neighbor-group CoreGroup
description CoreRouter
address-family ipv4 unicast
route-policy PASS out
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! route-policy search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
route-policy PASS
pass
end-policy
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! neighbor-group search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
router bgp 65000
neighbor-group CoreGroup
remote-as 65000
update-source Loopback0
address-family ipv4 unicast
route-policy DROP in
route-policy PASS out
next-hop-self
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!
! route-policy search
!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
route-policy PASS
pass
end-policy
!
route-policy DROP
drop
end-policy
対応機器
- IOS-XR
- IOS
- その他インデントで親子構造となる config の機器 (オプションは対応していません)
xmlやjsonのような構造化されたファイル形式、または IOS-XR の show run formal や JUNOS の display set のような flatten されたファイル形式には対応していません。cfgrepは、これらの機械が読みやすい(i.e. parse しやすい)形式ではなく、traditional(?)な形式のみを対象としています。
(余談ポエム)
- DevNet の Code Exchangeにも登録しています。
- オプションは私が当時すぐに欲しかった機能のみを実装しているので、物足りないかもしれません。
- 個人的にはとても便利なコマンドなのですが、公開から4年経っても、私以外に使用者はほとんどいないようで、この機会にぜひご利用いただければと思います。