diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-04 23:14:02 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-04 23:14:02 +0900 |
commit | 2bbd4147aa7a9e39b9da325191d7415d090fc2ec (patch) | |
tree | f140ba6773e15ddbe7a953dd8f8e8e73137da9b7 /cli/gobgpcli | |
parent | 52ddad958f10ae9ea7ab8c40130825c903d08c52 (diff) |
cli: add CLI utility
The tool internally talks with gobgpd via REST API.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'cli/gobgpcli')
-rwxr-xr-x | cli/gobgpcli | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/cli/gobgpcli b/cli/gobgpcli new file mode 100755 index 00000000..7d54ffd5 --- /dev/null +++ b/cli/gobgpcli @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Examples +# +# - get the state of neighbors +# $ gobgpcli show neighbors +# - get the local rib of a neighbor +# $ gobgpcli show neighbor 10.0.0.2 local + +from optparse import OptionParser +import requests +import sys +import inspect +import json +from datetime import timedelta + + +class Show(object): + def __init__(self, options, args): + super(Show, self).__init__() + self.options = options + self.args = args + self.base_url = self.options.url + ":" + str(self.options.port) + "/v1/bgp" + + def __call__(self): + if len(self.args) == 0: + return 1 + + for f in inspect.getmembers(self, inspect.ismethod): + func_name = f[0] + if func_name == "do_" + self.args[0]: + return f[1]() + return 1 + + def do_neighbors(self): + r = requests.get(self.base_url + "/neighbors") + neighbors = r.json() + if self.options.debug: + print neighbors + return 0 + for n in sorted(neighbors, key=lambda n: n["conf"]["remote_ip"]): + print("BGP neighbor is {:s}, remote AS {:d}".format(n["conf"]["remote_ip"], n["conf"]["remote_as"])) + print("BGP state = {:s}, up for {:s}".format(n["info"]["bgp_state"], str(timedelta(seconds=n["info"]["uptime"])))) + print("Message statistics:") + print(" Sent Rcvd") + print(" Opens: {:>10d} {:>10d}".format(n["info"]["open_message_out"], n["info"]["open_message_in"])) + print(" Notifications: {:>10d} {:>10d}".format(n["info"]["notification_out"], n["info"]["notification_in"])) + print(" Updates: {:>10d} {:>10d}".format(n["info"]["update_message_out"], n["info"]["update_message_in"])) + print(" Keepalives: {:>10d} {:>10d}".format(n["info"]["keepalive_message_out"], n["info"]["keepalive_message_in"])) + print(" Route Refesh: {:>10d} {:>10d}".format(n["info"]["refresh_message_out"], n["info"]["refresh_message_in"])) + print(" Total: {:>10d} {:>10d}".format(n["info"]["total_message_out"], n["info"]["total_message_in"])) + print("") + return 0 + + def do_neighbor(self): + if len(self.args) != 3: + return 1 + if self.args[2] == "local": + self.args[2] = "local-rib" + r = requests.get(self.base_url + "/neighbor/" + self.args[1] + "/" + self.args[2]) + if self.options.debug: + print r.json() + return 0 + print(" Network Next Hop AS Attrs") + for d in r.json()["Destinations"]: + for p in d["Paths"]: + nexthop = "" + AS = "" + for a in p["Attrs"]: + if a["Type"] == "BGP_ATTR_TYPE_NEXT_HOP": + nexthop = a["Nexthop"] + elif a["Type"] == "BGP_ATTR_TYPE_AS_PATH": + AS = a["AsPath"] + print(" {:s} {:s} {:s} {:s}".format(p["Network"], + nexthop, AS, p["Attrs"])) + return 0 + + +def main(): + usage = "gobpgcli [options] <command> <args>" + parser = OptionParser(usage) + + parser.add_option("-u", "--url", dest="url", default="http://localhost", + help="specifying an url (http://localhost by default)") + parser.add_option("-p", "--port", dest="port", default=8080, + help="specifying a port (8080 by default)") + parser.add_option("-d", "--debug", dest="debug", action="store_true", + help="dump raw json") + + (options, args) = parser.parse_args() + + commands = {"show": Show} + + if len(args) == 0: + parser.print_help() + sys.exit(1) + + if args[0] not in commands: + parser.print_help() + sys.exit(1) + + ret = commands[args[0]](options, args[1:])() + if ret != 0: + parser.print_help() + sys.exit(1) + +if __name__ == "__main__": + main() |