检查BGP状态

时间:2019-06-14 04:22:08

标签: python-3.x

我最近接受了一次采访,被要求写一个代码登录到3台路由器中,然后每台路由器一次重新加载-在移动以重新加载下一个设备之前,检查BGP是否已建立并且接口是否已启动。我们提供了一个导入的模块,该模块可以SSH到路由器中并重新加载它。有人在想吗?我是Python的新手

尽管为SSH提供了一个模块,但我首先将其编码出来,这就是我很累的地方。只是为了了解路由器的工作方式以及我要检查的内容:

import socket
import paramiko


def run_ssh_command(username, password, host, command):
    """
    Using paramiko to SSH into remote locations and run commands
    """
    port = 22
    s = paramiko.SSHClient()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        s.connect(host, port, username, password, look_for_keys=False, timeout=5.0)
    except paramiko.AuthenticationException as e:
        print("authentication failed: ", e)
        s.close()
        return
    except socket.timeout as e:
        print("socket timeout: ", e)
        s.close()
        return
    except paramiko.SSHException as e:
        print("SSH Exception: ", e)
        s.close()
        return
    except socket.error as e:
        print("socket error: ", e)
        s.close()
        return
    (stdin, stdout, stderr) = s.exec_command(command)
    print ("ran command ", command)
    # for line in stdout.readlines():
    # print(line)
    s.close()


if __name__ == "__main__":
    while True:
        run_ssh_command("CompRouter", "backbonedevice", "10.10.10.25", "show ip bgp summary")

所以我的思路是将SSH连接到设备,发出“ show ip bgp summary”命令-该表通常如下所示:

Neighbor       V        AS    MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  Statd
10.10.10.2     4       65536       7       7        1    0    0 00:03:04      0

这个想法是要检查InQ / OutQ值是否为零或BGP邻居的非“ Down”状态,然后才重新加载下一个路由器。

尤其是在我被困的地方。给定这样的表,如何检查整个InQ / OutQ列(可能有多个邻居),然后采取必要的措施?

1 个答案:

答案 0 :(得分:1)

选择使用napalmnetmiko-就像一种魅力:

from simplecrypt import encrypt, decrypt
from pprint import pprint
from netmiko import ConnectHandler
from napalm import get_network_driver
import json
#from time import time
import time

def read_device_data(devices_filename):

    devices = {} #Create a dictionary for each IP's unique info

    with open(devices_filename) as device_info:
        for lines in device_info:
            this_dev = lines.strip().split(',')
            dev = {'ipaddr': this_dev[0],
                   'type': this_dev[1],
                   'name': this_dev[2]}
            devices[dev['ipaddr']] = dev

    print('Displaying info for all devices below: ')
    pprint(devices)
    return devices

#Create a function to decrypt and read file containing credentials encrypted in the format ip,username,password 

def read_device_creds(device_cred_filename, key):

    print('\n Decoding encrypted device credentials....')

    with open(device_cred_filename, 'rb') as device_creds_file:
        device_creds_decry = decrypt(key, device_creds_file.read())

    device_creds_list = json.loads(device_creds_decry.decode('utf-8'))
    pprint(device_creds_list)
    print('\n Displaying device credentials in dictionary format:')
    """
    Convert device_creds_list to dictionary using list comprehension
    """
    device_creds_dict = {this_dev[0]: this_dev for this_dev in device_creds_list}
    print(device_creds_dict)
    return device_creds_dict

def check_BGP(net_device, cred):


    print(f"Connecting to {net_device['ipaddr']} right now to check BGP status.....")

    while True:

        try:
            driver = get_network_driver('ios')
            iosv = driver(net_device['ipaddr'], cred[1], cred[2])
            iosv.open()

        except:
            print('Waiting to establish a socket...')

        else:
            time.sleep(30)
            ios_output = iosv.get_bgp_neighbors()

            for k,v in ios_output.items():
                for y in v.values():
                    if type(y) == dict:
                        for z in y.values():
                            print(f"BGP peer is up? {z['is_up']}")
                            return z['is_up'] == True

def reload(creds):

    iosv_device = {
        'device_type': 'cisco_ios',
        'ip': creds[0],
        'username': creds[1],
        'password': creds[2]
    }

    net_connect = ConnectHandler(**iosv_device)
    output = net_connect.send_command_timing('wr mem')
    time.sleep(10)
    output += net_connect.send_command_timing('reload')
    output += net_connect.send_command_timing('y')
    print(output)


def is_alive(alive_dev, alive_cred): #check if device is back online after reload

    while True:

        try:
            driver = get_network_driver('ios')
            iosvl2 = driver(alive_dev['ipaddr'], alive_cred[1], alive_cred[2])
            iosvl2.open()
        except:
            print(f"Attempting to reconnect to {alive_cred[0]}")
        else:
            alive_output = iosvl2.is_alive()
            print(alive_output)
            return alive_output['is_alive'] == True
            break


if __name__ == '__main__':

    net_devices = read_device_data('devices_data')
    net_creds = read_device_creds('encrypted_device_creds', 'cisco')

#    starting_time = time()

    for ipadd, device_info in net_devices.items():
        print(net_devices.items())

        while True:

            print (f'Connecting to: {ipadd}')

            if  check_BGP(device_info, net_creds[ipadd]) == True:
                print(f'Reloading {ipadd} now')
                reload(net_creds[ipadd])

            else:
                print(f'Re-checking BGP on {ipadd}')

            if is_alive(device_info, net_creds[ipadd]) == True and check_BGP(device_info, net_creds[ipadd]) == True:
                print(f'{ipadd} back online and BGP OK!')
                break
            else:
                print('Router down or BGP failed to reconverged; exiting script')
                break



#    print ('\n---- End get config sequential, elapsed time=', time() - starting_time)