diff options
-rwxr-xr-x | cli/gobgpcli | 403 | ||||
-rw-r--r-- | tools/completion/gobgp-completion.bash | 195 |
2 files changed, 0 insertions, 598 deletions
diff --git a/cli/gobgpcli b/cli/gobgpcli deleted file mode 100755 index 6dfded5f..00000000 --- a/cli/gobgpcli +++ /dev/null @@ -1,403 +0,0 @@ -#!/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 state of a neighbor -# $ gobgpcli show neighbor 10.0.0.2 -# - get the local rib of a neighbor -# $ gobgpcli show neighbor 10.0.0.2 local -# - reset -# $ gobgpcli reset neighbor 10.0.0.2 -# - softresetin -# $ gobgpcli softresetin neighbor 10.0.0.2 -# - softresetout -# $ gobgpcli softresetout neighbor 10.0.0.2 -# - shutdown -# $ gobgpcli shutdown neighbor 10.0.0.2 - -from optparse import OptionParser -import requests -import sys -import inspect -import json -from datetime import timedelta - - -class Action(object): - def __init__(self, command, options, args): - super(Action, self).__init__() - self.command = command - 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) != 2: - return 1 - try: - r = requests.post(self.base_url + "/neighbor/" + self.args[1] + "/" + self.command) - except: - print "Failed to connect to gobgpd. It runs?" - sys.exit(1) - else: - if r.status_code == requests.codes.ok: - print "Succeed" - else: - print "Failed" - return 0 - - -class Show(object): - def __init__(self, _command, 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_global(self): - if len(self.args) != 1 and len(self.args) != 2: - return 1 - - url = self.base_url + "/global/rib" - if len(self.args) == 2: - url += "/" + self.args[1] - else: - url += "/ipv4" - - try: - r = requests.get(url) - except: - print "Failed to connect to gobgpd. It runs?" - sys.exit(1) - - f = "{:2s} {:18s} {:15s} {:10s} {:10s} {:s}" - print(f.format("", "Network", "Next Hop", "AS_PATH", "Age", "Attrs")) - - for d in r.json()["Destinations"]: - d["Paths"][d["BestPathIdx"]]["Best"] = True - self.show_routes(f, d["Paths"], True, True) - - return 0 - - def _neighbor(self, neighbor=None): - capdict = {1: "MULTIPROTOCOL", - 2: "ROUTE_REFRESH", - 4: "CARRYING_LABEL_INFO", - 64: "GRACEFUL_RESTART", - 65: "FOUR_OCTET_AS_NUMBER", - 70: "ENHANCED_ROUTE_REFRESH", - 128: "ROUTE_REFRESH_CISCO"} - try: - r = requests.get(self.base_url + "/neighbors") - except: - print "Failed to connect to gobgpd. It runs?" - sys.exit(1) - - neighbors = r.json() - if self.options.debug: - print neighbors - return 0 - for n in sorted(neighbors, key=lambda n: n["conf"]["remote_ip"]): - if neighbor is not None and neighbor != n["conf"]["remote_ip"]: - continue - print("BGP neighbor is {:s}, remote AS {:d}".format(n["conf"]["remote_ip"], n["conf"]["remote_as"])) - print(" BGP version 4, remote router ID {:s}".format(n["conf"]["id"])) - print(" BGP state = {:s}, up for {:s}".format(n["info"]["bgp_state"], str(timedelta(seconds=n["info"]["uptime"])))) - print(" BGP OutQ = {:d}, Flops = {:d}".format(n["info"]["OutQ"], n["info"]["Flops"])) - print(" Neighbor capabilities:") - allcap = set(n["conf"]["RemoteCap"]) | set(n["conf"]["LocalCap"]) - for i in sorted(allcap): - if i in capdict: - k = capdict[i] - else: - k = "UNKNOWN (" + str(i) + ")" - r = "" - if i in n["conf"]["LocalCap"]: - r += "advertised" - if i in n["conf"]["RemoteCap"]: - if len(r) != 0: - r += " and " - r += "received" - print(" {:s}: {:s}".format(k, r)) - 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(" Discarded: {:>10d} {:>10d}".format(n["info"]["DiscardedOut"], n["info"]["DiscardedIn"])) - print(" Total: {:>10d} {:>10d}".format(n["info"]["total_message_out"], n["info"]["total_message_in"])) - print("") - return 0 - - @staticmethod - def format_timedelta(sec): - days = timedelta(seconds=sec).days - t = timedelta(seconds=timedelta(seconds=sec).seconds) - if days == 0: - up = t - else: - up = str(days) + "d" + " " + str(t) - return up - - def do_neighbors(self): - if len(self.args) != 1: - return 1 - try: - r = requests.get(self.base_url + "/neighbors") - except: - print "Failed to connect to gobgpd. It runs?" - sys.exit(1) - - neighbors = r.json() - if self.options.debug: - print neighbors - return 0 - sorted_neighbors = [] - for n in sorted(neighbors, key=lambda n: n["conf"]["remote_ip"]): - sorted_neighbors.append(n) - if self.options.quiet: - sorted_neighbors_ip = [] - for n in sorted_neighbors: - print str(n["conf"]["remote_ip"]) - return 0 - maxaddrlen = 0 - maxaslen = 0 - maxtimelen = len("Up/Down") - for n in sorted_neighbors: - if len(n["conf"]["remote_ip"]) > maxaddrlen: - maxaddrlen = len(n["conf"]["remote_ip"]) - if len(str(n["conf"]["remote_as"])) > maxaslen: - maxaslen = len(str(n["conf"]["remote_as"])) - - s = n["info"]["bgp_state"] - if n["info"]["uptime"] == 0: - t = "never" - elif s == "BGP_FSM_ESTABLISHED": - t = self.format_timedelta(n["info"]["uptime"]) - else: - t = self.format_timedelta(n["info"]["downtime"]) - if len(str(t)) > maxtimelen: - maxtimelen = len(str(t)) - n["info"]["time"] = t - - h = "{:%ds} {:>%ds} {:%ds} {:11s} |" % (maxaddrlen, maxaslen, maxtimelen) - f1 = h + "#{:8s} {:8s} {:8s}" - print(f1.format("Peer", "AS", "Up/Down", "State", "Advertised", "Received", "Accepted")) - for n in sorted_neighbors: - s = n["info"]["bgp_state"] - if s == "BGP_FSM_IDLE": - state = "Idle" - elif s == "BGP_FSM_CONNECT": - state = "Connect" - elif s == "BGP_FSM_ACTIVE": - state = "Active" - elif s == "BGP_FSM_OPENSENT": - state = "Sent" - elif s == "BGP_FSM_OPENCONFIRM": - state = "Confirm" - elif s == "BGP_FSM_ESTABLISHED": - state = "Establ" - - if n["info"]["AdminState"] == "ADMIN_STATE_DOWN": - state = "Idle(Admin)" - - f2 = h + " {:>8d} {:>8d} {:>8d}" - print f2.format(n["conf"]["remote_ip"], str(n["conf"]["remote_as"]), n["info"]["time"], state, n["info"]["Advertized"], n["info"]["Received"], n["info"]["Accepted"]) - return 0 - - def _format_attrs(self, attrlist): - attrs = [] - for a in attrlist: - if a["Type"] == "BGP_ATTR_TYPE_NEXT_HOP": - pass - elif a["Type"] == "BGP_ATTR_TYPE_AS_PATH": - pass - elif a["Type"] == "BGP_ATTR_TYPE_ORIGIN": - attrs.append({"Origin": a["Value"]}) - elif a["Type"] == "BGP_ATTR_TYPE_MULTI_EXIT_DISC": - attrs.append({"Med": a["Metric"]}) - elif a["Type"] == "BGP_ATTR_TYPE_LOCAL_PREF": - attrs.append({"LocalPref": a["Pref"]}) - elif a["Type"] == "BGP_ATTR_TYPE_ATOMIC_AGGREGATE": - attrs.append("AtomicAggregate") - elif a["Type"] == "BGP_ATTR_TYPE_AGGREGATE": - attrs.append({"Aggregate": {"AS": a["AS"], "Address": a["Address"]}}) - elif a["Type"] == "BGP_ATTR_TYPE_COMMUNITIES": - wellknown = { - 0xffff0000: "planned-shut", - 0xffff0001: "accept-own", - 0xffff0002: "ROUTE_FILTER_TRANSLATED_v4", - 0xffff0003: "ROUTE_FILTER_v4", - 0xffff0004: "ROUTE_FILTER_TRANSLATED_v6", - 0xffff0005: "ROUTE_FILTER_v6", - 0xffff0006: "LLGR_STALE", - 0xffff0007: "NO_LLGR", - 0xFFFFFF01: "NO_EXPORT", - 0xFFFFFF02: "NO_ADVERTISE", - 0xFFFFFF03: "NO_EXPORT_SUBCONFED", - 0xFFFFFF04: "NOPEER"} - - l = [] - for v in a["Value"]: - if v in wellknown: - l.append(wellknown[v]) - else: - l.append(str((0xffff0000 & v) >> 16) + ":" + str(0xffff & v)) - attrs.append({"Community": l}) - elif a["Type"] == "BGP_ATTR_TYPE_ORIGINATOR_ID": - attrs.append({"Originator": a["Address"]}) - elif a["Type"] == "BGP_ATTR_TYPE_CLUSTER_LIST": - attrs.append({"Cluster": a["Address"]}) - elif a["Type"] == "BGP_ATTR_TYPE_MP_REACH_NLRI": - pass - elif a["Type"] == "BGP_ATTR_TYPE_MP_UNREACH_NLRI": - pass - elif a["Type"] == "BGP_ATTR_TYPE_AS4_PATH": - pass - else: - attrs.append({a["Type"]: a["Value"]}) - return attrs - - def do_neighbor(self): - if len(self.args) != 2 and len(self.args) != 3 and len(self.args) != 4: - return 1 - if len(self.args) == 2: - return self._neighbor(neighbor=self.args[1]) - if self.args[2] in ("local", "local-rib"): - self.args[2] = "local-rib" - elif self.args[2] in ("received-routes", "adj-rib-in", "adj-in"): - self.args[2] = "adj-rib-in" - elif self.args[2] in ("advertised-routes", "adj-rib-out", "adj-out"): - self.args[2] = "adj-rib-out" - else: - print self.args[2], ": No such command" - return 1 - - try: - r = requests.get(self.base_url + "/neighbor/" + self.args[1] + "/" + self.args[2]) - url = self.base_url + "/neighbor/" + self.args[1] + "/" + self.args[2] - if len(self.args) == 3: - if self.args[2].find(':') == -1: - url += "/ipv4" - else: - url += "/ipv6" - else: - url += "/" + self.args[3] - r = requests.get(url) - except: - print "Failed to connect to gobgpd. It runs?" - sys.exit(1) - - if self.options.debug: - print r.json() - return 0 - - timestamp = True - if self.args[2] == "adj-rib-out": - timestamp = False - - if timestamp: - f = "{:2s} {:18s} {:15s} {:10s} {:10s} {:s}" - print(f.format("", "Network", "Next Hop", "AS_PATH", "Age", "Attrs")) - else: - f = "{:2s} {:18s} {:15s} {:10s} {:s}" - print(f.format("", "Network", "Next Hop", "AS_PATH", "Attrs")) - - if self.args[2] == "local-rib": - for d in r.json()["Destinations"]: - d["Paths"][d["BestPathIdx"]]["Best"] = True - self.show_routes(f, d["Paths"], True, True) - - elif self.args[2] == "adj-rib-in" or self.args[2] == "adj-rib-out": - self.show_routes(f, r.json(), False, timestamp) - return 0 - - def show_routes(self, f, paths, showBest=False, timestamp=False): - for p in paths: - nexthop = "" - AS = "" - for a in p["Attrs"]: - if a["Type"] == "BGP_ATTR_TYPE_AS_PATH": - AS = a["AsPath"] - if showBest: - if "Best" in p: - header = "*>" - else: - header = "*" - else: - header = "" - if timestamp: - print(f.format(header, p["Network"], p["Nexthop"], AS, self.format_timedelta(p["Age"]), self._format_attrs(p["Attrs"]))) - else: - print(f.format(header, p["Network"], p["Nexthop"], AS, self._format_attrs(p["Attrs"]))) - - -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") - parser.add_option("-q", "--quiet", dest="quiet", action="store_true", - help="for shell completion") - - (options, args) = parser.parse_args() - - commands = {"show": Show, - "reset": Action, - "shutdown": Action, - "softreset": Action, - "softresetin": Action, - "softresetout": Action, - "enable": Action, - "disable": Action} - - 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]](args[0], options, args[1:])() - if ret != 0: - parser.print_help() - sys.exit(1) - -if __name__ == "__main__": - main() diff --git a/tools/completion/gobgp-completion.bash b/tools/completion/gobgp-completion.bash deleted file mode 100644 index b9e0c483..00000000 --- a/tools/completion/gobgp-completion.bash +++ /dev/null @@ -1,195 +0,0 @@ -#!bash - -__gobgp_q() { - gobgp 2>/dev/null "$@" -} - -__search_target() { - local word target c=1 - - while [ $c -lt $cword ]; do - word="${words[c]}" - for target in $1; do - if [ "$target" = "$word" ]; then - echo "$target" - return - fi - done - ((c++)) - done -} - -__gobgp_table_list() { - local table_list=("local adj-in adj-out") - local table="$(__search_target "${table_list}")" - if [ -z "$table" ]; then - case "$cur" in - *) - COMPREPLY=( $( compgen -W "${table_list}" -- "$cur") ) - ;; - esac - return - fi - COMPREPLY=( $( compgen -W "ipv4 ipv6 evpn" -- "$cur") ) - return -} - -__gobgp_neighbr_list() { - local neighbor_list=( $(__gobgp_q --quiet show neighbors) ) - local target="$(__search_target "${neighbor_list[*]}")" - if [ -z "$target" ]; then - case "$cur" in - *) - COMPREPLY=( $( compgen -W "${neighbor_list[*]}" -- "$cur") ) - ;; - esac - __ltrim_colon_completions "$cur" - return 0 - fi - return 1 -} - -_gobgp_show_neighbor() { - __gobgp_neighbr_list - if [ $? -ne 0 ] ; then - __gobgp_table_list - fi -} - -_gobgp_show_neighbors() { - case "$cur" in - *) - ;; - esac - return -} - -_gobgp_show_global() { - local targets="ipv4 ipv6 evpn" - local target="$(__search_target "$targets")" - if [ -z "$target" ]; then - case "$cur" in - *) - COMPREPLY=( $( compgen -W "${targets[*]}" -- "$cur" ) ) - ;; - esac - return - fi -} - -_gobgp_show() { - local targets="neighbor neighbors global" - local target="$(__search_target "$targets")" - if [ -z "$target" ]; then - case "$cur" in - *) - COMPREPLY=( $( compgen -W "${targets[*]}" -- "$cur" ) ) - ;; - esac - return - fi - _gobgp_show_${target} -} - -__gobgp_generic_reset() { - local targets="neighbor" - local target="$(__search_target "$targets")" - if [ -z "$target" ]; then - case "$cur" in - *) - COMPREPLY=( $( compgen -W "${targets[*]}" -- "$cur" ) ) - ;; - esac - return - fi - __gobgp_neighbr_list -} - -_gobgp_reset() { - __gobgp_generic_reset -} - -_gobgp_softreset() { - __gobgp_generic_reset -} - -_gobgp_softresetin() { - __gobgp_generic_reset -} - -_gobgp_softresetout() { - __gobgp_generic_reset -} - -_gobgp_shutdown() { - __gobgp_generic_reset -} - -_gobgp_enable() { - __gobgp_generic_reset -} - -_gobgp_disable() { - __gobgp_generic_reset -} - -_gobgp_gobgp() { - case "$prev" in - -h) - return - ;; - *) - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "-h" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) - ;; - esac -} - -_gobgp() { - local commands=( - show - reset - softreset - softresetin - softresetout - shutdown - enable - disable - ) - - COMPREPLY=() - local cur prev words cword - _get_comp_words_by_ref -n : cur prev words cword - - local command='gobgp' - local counter=1 - while [ $counter -lt $cword ]; do - case "${words[$counter]}" in - -h) - (( counter++ )) - ;; - -*) - ;; - *) - command="${words[$counter]}" - cpos=$counter - (( cpos++ )) - break - ;; - esac - (( counter++ )) - done - local completions_func=_gobgp_${command} - declare -F $completions_func > /dev/null && $completions_func - - return 0 -} - -complete -F _gobgp gobgp |