1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

jmespathは便利だけど(私は)直感的に書けない

アットホームな職場のアドベントカレンダー2日目です。
私の誕生日である12/02に投稿する予定だったのに、いざ書き始めると難しくて日をまたいでしまいました。

さて、今日のお題はjmespathです。
かれこれ3年くらい使っているのに、ちょっと凝ったことをやろうと思うといつも手こずります。
そんなわけで、備忘録。

対象のデータはjuniperのshow command

私は主にNW機器の設定値をansible経由でjsonで取得して、そこから扱いやすいように整形する用途でcommunity.general.json_query filter(中身はjmespath)を使用しています。
今回もjuniperのvlabsの機器でshow commandを実行した結果を使用します。

余談ですが、juniperのvlabsは無料で使えて、予めtopologyもたくさん用意してくれている素晴らしいサービスです。
juniper vlabs

そして、juniperとかaristaの機器は、json出力する機能が備わっているため、パースする必要がないところが最高です。

jmespathの公式サイトでテスト

jmespathの公式はjson dataとqueryからresultを出力してくれるので、機密情報を含まないデータをさくっと確認したいときにはとても便利です。

image.png

また、リファレンスも充実してて、整形方法が分からないときはいつもここで調べています。
注意点として、queryが間違っているときにはresultが更新されないので、そこは意識してください。
どういうことかというと、もともとこういうqueryを入れていたとして、

image.png

WAをNYに変えようかなとbackspaceで消してみても、「そのqueryは間違っている」というようなメッセージは出ないです。

image.png

なので、誤ったqueryでresultが出せていると誤認する可能性があるので気を付けてね!ということでした。

今回もここを使ってテストしています。

まずはjson dataを取得してみます

これは本題ではないのですが、イメージしやすいようにvlabsの検証環境の構成図を載せておきます。

image.png

この環境の中の左上のrouterで show route を実行すると、こんな感じでrouting tableが得られます。

show route
jcladmin@vMX1> show route

inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

0.0.0.0/0          *[Static/5] 00:15:44
                    >  to 100.123.0.1 via fxp0.0
10.100.12.0/24     *[Direct/0] 00:12:33
                    >  via ge-0/0/0.0
10.100.12.1/32     *[Local/0] 00:12:33
                       Local via ge-0/0/0.0
10.100.13.0/24     *[Direct/0] 00:12:33
                    >  via ge-0/0/2.0
10.100.13.1/32     *[Local/0] 00:12:33
                       Local via ge-0/0/2.0
10.100.14.0/24     *[OSPF/10] 00:00:10, metric 3
                    >  to 10.100.12.2 via ge-0/0/0.0
                       to 10.100.13.2 via ge-0/0/2.0
10.100.14.1/32     *[Local/0] 00:00:11
                       Reject
10.100.23.0/24     *[OSPF/10] 00:11:22, metric 2
                       to 10.100.12.2 via ge-0/0/0.0
                    >  to 10.100.13.2 via ge-0/0/2.0
10.100.24.0/24     *[OSPF/10] 00:00:10, metric 2
                    >  to 10.100.12.2 via ge-0/0/0.0
10.100.34.0/24     *[OSPF/10] 00:00:10, metric 2
                    >  to 10.100.13.2 via ge-0/0/2.0
10.100.100.1/32    *[Direct/0] 00:12:33
                    >  via lo0.0
10.100.100.2/32    *[OSPF/10] 00:11:28, metric 1
                    >  to 10.100.12.2 via ge-0/0/0.0
10.100.100.3/32    *[OSPF/10] 00:11:22, metric 1
                    >  to 10.100.13.2 via ge-0/0/2.0
10.100.100.4/32    *[OSPF/10] 00:00:10, metric 2
                       to 10.100.12.2 via ge-0/0/0.0
                    >  to 10.100.13.2 via ge-0/0/2.0
100.123.0.0/16     *[Direct/0] 00:15:44
                    >  via fxp0.0
100.123.1.0/32     *[Local/0] 00:15:44
                       Local via fxp0.0
224.0.0.5/32       *[OSPF/10] 00:12:33, metric 1
                       MultiRecv

inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

ff02::2/128        *[INET6/0] 00:15:44
                       MultiRecv

今回は10.100.100.4/32宛のルートを対象にアレコレやっていきます。
構成図でいう右下のrouterのloopbackです。
左上から右下のrouterへの経路は、ge-0/0/0とge-0/0/2経由の2つがあります。

10.100.100.4/32    *[OSPF/10] 00:00:10, metric 2
                       to 10.100.12.2 via ge-0/0/0.0
                    >  to 10.100.13.2 via ge-0/0/2.0

では、show routeコマンドをjsonで出力してみます。
juniper機器では command | display json とすればjson形式の出力を得られます。

長いので折りたたみます
show route | display json
{
    "route-information" : [
    {
        "attributes" : {"xmlns" : "http://xml.juniper.net/junos/21.1R0/junos-routing"},
        "route-table" : [
        {
            "comment" : "keepalive",
            "table-name" : [
            {
                "data" : "inet.0"
            }
            ],
            "destination-count" : [
            {
                "data" : "17"
            }
            ],
            "total-route-count" : [
            {
                "data" : "17"
            }
            ],
            "active-route-count" : [
            {
                "data" : "17"
            }
            ],
            "holddown-route-count" : [
            {
                "data" : "0"
            }
            ],
            "hidden-route-count" : [
            {
                "data" : "0"
            }
            ],
            "rt" : [
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "0.0.0.0/0"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Static"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "5"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:17:20",
                        "attributes" : {"junos:seconds" : "1040"}
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "100.123.0.1"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "fxp0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.12.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Direct"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.12.1/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "nh" : [
                    {
                        "nh-local-interface" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.13.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Direct"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.13.1/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "nh" : [
                    {
                        "nh-local-interface" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.14.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:01:46",
                        "attributes" : {"junos:seconds" : "106"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "3"
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    },
                    {
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.14.1/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:01:47",
                        "attributes" : {"junos:seconds" : "107"}
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "Reject"
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.23.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:12:58",
                        "attributes" : {"junos:seconds" : "778"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "2"
                    }
                    ],
                    "nh" : [
                    {
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    },
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.24.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:01:46",
                        "attributes" : {"junos:seconds" : "106"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "2"
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.34.0/24"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:01:46",
                        "attributes" : {"junos:seconds" : "106"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "2"
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.100.1/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Direct"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "via" : [
                        {
                            "data" : "lo0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.100.2/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:13:04",
                        "attributes" : {"junos:seconds" : "784"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "1"
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.100.3/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:12:58",
                        "attributes" : {"junos:seconds" : "778"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "1"
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.100.4/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:01:46",
                        "attributes" : {"junos:seconds" : "106"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "2"
                    }
                    ],
                    "nh" : [
                    {
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    },
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "100.123.0.0/16"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Direct"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:17:20",
                        "attributes" : {"junos:seconds" : "1040"}
                    }
                    ],
                    "nh" : [
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "via" : [
                        {
                            "data" : "fxp0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "100.123.1.0/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:17:20",
                        "attributes" : {"junos:seconds" : "1040"}
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "Local"
                    }
                    ],
                    "nh" : [
                    {
                        "nh-local-interface" : [
                        {
                            "data" : "fxp0.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "224.0.0.5/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:14:09",
                        "attributes" : {"junos:seconds" : "849"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "1"
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "MultiRecv"
                    }
                    ]
                }
                ]
            }
            ]
        },
        {
            "table-name" : [
            {
                "data" : "inet6.0"
            }
            ],
            "destination-count" : [
            {
                "data" : "1"
            }
            ],
            "total-route-count" : [
            {
                "data" : "1"
            }
            ],
            "active-route-count" : [
            {
                "data" : "1"
            }
            ],
            "holddown-route-count" : [
            {
                "data" : "0"
            }
            ],
            "hidden-route-count" : [
            {
                "data" : "0"
            }
            ],
            "rt" : [
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "ff02::2/128"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "INET6"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "0"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "00:17:20",
                        "attributes" : {"junos:seconds" : "1040"}
                    }
                    ],
                    "nh-type" : [
                    {
                        "data" : "MultiRecv"
                    }
                    ]
                }
                ]
            }
            ]
        }
        ]
    }
    ]
}
構造化データって長いですよねー。

json query 基本形

さて、ここから 10.100.100.4/32宛のnexthopを取り出してみます。
ただし、ここではまだrt[13]のように、rtのlistの中でも"13番目の要素"という指定の仕方をします。

queryと結果はこうです。

query
"route-information"[0]."route-table"[0].rt[13]."rt-entry"[0].nh
result
[
  {
    "to": [
      {
        "data": "10.100.12.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/0.0"
      }
    ]
  },
  {
    "selected-next-hop": [
      {
        "data": [
          null
        ]
      }
    ],
    "to": [
      {
        "data": "10.100.13.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/2.0"
      }
    ]
  }
]

このqueryだけでも頭が痛くなりそうですが、よく見るとただtreeを辿っているだけなんです。
keyの部分にダブルクオーテーションがあったりなかったりするのは、-(ハイフン)を含むかどうかで変わります。
jsonでは-が演算子なので、ダブルクオーテーションで囲ってやる必要があります。
もちろん、-が含まれていないデータをダブルクオーテーションで囲っても問題ないので、それで統一する方が分かりやすいかもしれないですね。

ちょっとだけ応用編

では、"13番目の要素" ではなく、"10.100.100.4/32 宛のルート" というように、扱うデータのリストの順番が分かってなくても取得できるようにqueryを変更してみます。

query
"route-information"[0]."route-table"[0].rt[?"rt-destination"[0].data == '10.100.100.4/32']."rt-entry"[0].nh[]
result
[
  {
    "to": [
      {
        "data": "10.100.12.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/0.0"
      }
    ]
  },
  {
    "selected-next-hop": [
      {
        "data": [
          null
        ]
      }
    ],
    "to": [
      {
        "data": "10.100.13.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/2.0"
      }
    ]
  }
]

肝はrt[?"rt-destination"[0].data == '10.100.100.4/32']ですね。
無事取得できましたが、もっと頭が痛くなってきました。

ご安心ください、機器側で宛先を絞れます

実はshow route コマンドはdestinationを指定することもできます。

show route 10.100.100.4/32
jcladmin@vMX1> show route 10.100.100.4/32

inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

10.100.100.4/32    *[OSPF/10] 01:00:59, metric 2
                       to 10.100.12.2 via ge-0/0/0.0
                    >  to 10.100.13.2 via ge-0/0/2.0

jsonでは

show route 10.100.100.4/32 | display json
jcladmin@vMX1> show route 10.100.100.4/32 | display json

{
    "route-information" : [
    {
        "attributes" : {"xmlns" : "http://xml.juniper.net/junos/21.1R0/junos-routing"},
        "route-table" : [
        {
            "comment" : "keepalive",
            "table-name" : [
            {
                "data" : "inet.0"
            }
            ],
            "destination-count" : [
            {
                "data" : "17"
            }
            ],
            "total-route-count" : [
            {
                "data" : "17"
            }
            ],
            "active-route-count" : [
            {
                "data" : "17"
            }
            ],
            "holddown-route-count" : [
            {
                "data" : "0"
            }
            ],
            "hidden-route-count" : [
            {
                "data" : "0"
            }
            ],
            "rt" : [
            {
                "attributes" : {"junos:style" : "brief"},
                "rt-destination" : [
                {
                    "data" : "10.100.100.4/32"
                }
                ],
                "rt-entry" : [
                {
                    "active-tag" : [
                    {
                        "data" : "*"
                    }
                    ],
                    "current-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "last-active" : [
                    {
                        "data" : [null]
                    }
                    ],
                    "protocol-name" : [
                    {
                        "data" : "OSPF"
                    }
                    ],
                    "preference" : [
                    {
                        "data" : "10"
                    }
                    ],
                    "age" : [
                    {
                        "data" : "01:01:26",
                        "attributes" : {"junos:seconds" : "3686"}
                    }
                    ],
                    "metric" : [
                    {
                        "data" : "2"
                    }
                    ],
                    "nh" : [
                    {
                        "to" : [
                        {
                            "data" : "10.100.12.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/0.0"
                        }
                        ]
                    },
                    {
                        "selected-next-hop" : [
                        {
                            "data" : [null]
                        }
                        ],
                        "to" : [
                        {
                            "data" : "10.100.13.2"
                        }
                        ],
                        "via" : [
                        {
                            "data" : "ge-0/0/2.0"
                        }
                        ]
                    }
                    ]
                }
                ]
            }
            ]
        }
        ]
    }
    ]
}

ここからはこちらのデータを使っていきます。

応用編 中くらい

では、この中からselected pathの方を抽出してみましょう。

まずはnexthopまで辿ってみます。

query
"route-information"[0]."route-table"[0].rt[0]."rt-entry"[0].nh
result
[
  {
    "to": [
      {
        "data": "10.100.12.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/0.0"
      }
    ]
  },
  {
    "selected-next-hop": [
      {
        "data": [
          null
        ]
      }
    ],
    "to": [
      {
        "data": "10.100.13.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/2.0"
      }
    ]
  }
]

さて、先程の例では rt[?"rt-destination"[0].data == '10.100.100.4/32'] のように、とあるkeyに対するvalueがこうだったらという方法で特定しましたが、今回はselected-next-hopのkeyを含むだけでOKです。
これは意外と簡単で、

query
"route-information"[0]."route-table"[0].rt[0]."rt-entry"[0].nh[?"selected-next-hop"]
result
[
  {
    "selected-next-hop": [
      {
        "data": [
          null
        ]
      }
    ],
    "to": [
      {
        "data": "10.100.13.2"
      }
    ],
    "via": [
      {
        "data": "ge-0/0/2.0"
      }
    ]
  }
]

いい感じに絞れていますね。

応用編 好みの形にしてしまおう

さて、これをもっとこの後の作業、例えば想定値と実際の比較を行うにあたって使いやすい形に整形してみましょう。
こんな形を目指します。

{
"destination": "10.100.100.4/32",
"paths": [
    {
    "nexthop": "10.100.12.2",
    "interface": "ge-0/0/0.0",
    },
    {
    "nexthop": "10.100.13.2",
    "interface": "ge-0/0/2.0",
    }
  ]
}

dictにするには素直に{}で囲ってそれっぽく指定すればできます。

query
"route-information"[0]."route-table"[0].rt[0].{destination:"rt-destination"[0], paths:"rt-entry"[0].nh[].{nexthop:to[0].data, interface:via[0].data}}
result
{
  "destination": {
    "data": "10.100.100.4/32"
  },
  "paths": [
    {
      "nexthop": "10.100.12.2",
      "interface": "ge-0/0/0.0"
    },
    {
      "nexthop": "10.100.13.2",
      "interface": "ge-0/0/2.0"
    }
  ]
}

一旦目標の形にはなりました。
けど、どちらがselected pathなのかも盛り込みたいですよね。

応用編 頭痛Max

目指したい形は以下です。

{
  "destination": {
    "data": "10.100.100.4/32"
  },
  "paths": [
    {
      "nexthop": "10.100.12.2",
      "interface": "ge-0/0/0.0",
      "selected": false
    },
    {
      "nexthop": "10.100.13.2",
      "interface": "ge-0/0/2.0",
      "selected": true
    }
  ]
}

少しずつ紐解きましょう。

まず、selected pathには"selected-next-hop"というkeyが入ります。
なので、このkeyを含むか否かを判定すれば良さそう。

では、keyをどうやって引っ張るかというと、ちゃんと公式に書いてあります。

keys

@でそれまでqueryした内容を引数にできるんですね。

"route-information"[0]."route-table"[0].rt[0]."rt-entry"[0].nh[].keys(@)

result
[
  [
    "to",
    "via"
  ],
  [
    "selected-next-hop",
    "to",
    "via"
  ]
]

ちゃんと引っ張れてます。よしよし。

では、keyがlistに含まれればtrueとするにはどうするかというと、これも公式に書いてあります。
contains

query
"route-information"[0]."route-table"[0].rt[0]."rt-entry"[0].nh[].keys(@).contains(@,'selected-next-hop')
result
[
  false,
  true
]

あとは先程作ったqueryと組み合わせれば、完成!

query
"route-information"[0]."route-table"[0].rt[0].{destination:"rt-destination"[0], paths:"rt-entry"[0].nh[].{nexthop:to[0].data, interface:via[0].data, selected:keys(@).contains(@,'selected-next-hop')}}
result
{
  "destination": {
    "data": "10.100.100.4/32"
  },
  "paths": [
    {
      "nexthop": "10.100.12.2",
      "interface": "ge-0/0/0.0",
      "selected": false
    },
    {
      "nexthop": "10.100.13.2",
      "interface": "ge-0/0/2.0",
      "selected": true
    }
  ]
}

いやー難しかった。
けど、困ったときはこれを見返せば大抵のことは大丈夫そう。

1
0
0

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
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?