如何在python netmiko线程中使输出整洁

时间:2019-02-28 08:07:44

标签: python-3.x ssh python-multithreading

我已经编写了这段代码,以使用python 3 netmiko配置来自不同供应商的不同开关。我还尝试从github上的netmiko示例中实现线程。

我对输出的打印方式不满意,这简直是混乱和混乱。我也有几个问题:

  1. 如何确保每个开关的输出正确地封装在其相应的打印语句中。我不在乎<Thread(Thread-1, started 7132)>,因为可能无法用相应的实际开关输出来打印此行,因为我需要这些行来打印它们的键入方式:
print('======= IP: %s ======= %i\n' % (device_data['ip'], counter))
print(output)
print('==================================== %i\n' % counter)
  1. 为什么我看到此行,所以我使用with ConnectHandler(**device_data)以确保正确关闭连接。
  2. 异常处理的方式是否正确,可以做得更好吗?
  3. 这是我使用上下文管理器的正确方法,即with ConnectHandler(**device_data)具有线程功能。

实际代码:

#!/usr/bin/env python3

import os
import threading
import logging
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException
from paramiko.ssh_exception import SSHException
from netmiko.ssh_exception import AuthenticationException
from netaddr import valid_ipv4
from contextlib import contextmanager

# directories containing required files to run this script
ip_files_dir = 'IP_Lists'

#cmd_files_dir = 'NTP'
#cmd_files_dir = 'SNMP'
#cmd_files_dir = 'SSH_Security'
cmd_files_dir = 'timeout'

# files containing IP addresses for each device_category
# 0: ['HP_ACCESS_IP.txt', 'COMMANDS_ACCESS_HP.txt', 'hp_procurve', 'manager', 'uop@edges@2000'],
# 1: ['RUCKUS_ACCESS_IP.txt', 'COMMANDS_ACCESS_RUCKUS.txt', 'brocade_fastiron', 'manager', 'uop@edges@2000'],
# 2: ['RUCKUS_EDGES_IP.txt', 'COMMANDS_EDGE_RUCKUS.txt', 'brocade_fastiron', 'manager', 'pu@uopnetwork2000'],
# 3: ['RUCKUS_CORE_IP.txt', 'COMMANDS_CORE_RUCKUS.txt', 'brocade_fastiron', 'manager', 'pu@uopnetwork2100']
def device_file_list_select(argument):
    return {
        0: ['HP_ACCESS_IP.txt', 'HP_ACCESS_COMMANDS.txt', 'hp_procurve', 'manager', 'uop@edges@2000'],
        1: ['RUCKUS_ACCESS_IP.txt', 'RUCKUS_ACCESS_COMMANDS.txt', 'brocade_fastiron', 'manager', 'uop@edges@2000'],
        2: ['RUCKUS_EDGES_IP.txt', 'RUCKUS_EDGES_COMMANDS.txt', 'brocade_fastiron', 'manager', 'pu@uopnetwork2000'],
        3: ['RUCKUS_CORE_IP.txt', 'RUCKUS_CORE_COMMANDS.txt', 'brocade_fastiron', 'manager', 'pu@uopnetwork2100']
        # 0 is default if argument not found
    }.get(argument, ['HP_ACCESS_IP.txt', 'HP_ACCESS_COMMANDS.txt', 'hp_procurve', 'manager', 'uop@edges@2000'])


def connect(device_data, device_commands_1ist, counter):
    try:
        with ConnectHandler(**device_data) as connection_handler:
            try:
                output = connection_handler.send_config_set(device_commands_1ist)
                print('======= IP: %s ======= %i\n' % (device_data['ip'], counter))
                print(output)
                print('==================================== %i\n' % counter)
            except NetMikoTimeoutException:
                logging.error('Connection timeout while executing commands: %s' % device_data['ip'])
                connected = False
            except EOFError:
                logging.error('End of File while attempting device: %s' % device_data['ip'])
                connected = False
            except SSHException:
                logging.error('SSH issue while executing commands: %s' % device_data['ip'])
                connected = False
            except Exception as unknown_error:
                logging.error('Some other error while executing commands: %s' % device_data['ip'], unknown_error.__str__())
                connected = False            
    except AuthenticationException:
        logging.error('Authentication failure: %s' % device_data['ip'])
        connected = False
    except NetMikoTimeoutException:
        logging.error('Connection timeout: %s' % device_data['ip'])
        connected = False
    except EOFError:
        logging.error('End of File while attempting device: %s' % device_data['ip'])
        connected = False
    except SSHException:
        logging.error('SSH issue while trying to connect to %s' % device_data['ip'])
        connected = False
    except Exception as unknown_error:
        logging.error('Some other error while trying to connect to %s: %s' % device_data['ip'], unknown_error.__str__())
        connected = False


def main():
    # select IP addresses file, commands file, and device type in one go
    device_ip_file, commands_file, device_type, username, password = device_file_list_select(1)

    with open(os.path.join(ip_files_dir, device_ip_file)) as f:
        device_ip_list = f.read().splitlines()
    device_ip_list.sort()
    #print(device_ip_list)

    with open(os.path.join(cmd_files_dir, commands_file)) as f:
        device_commands_1ist = f.read().splitlines()
        #print(device_commands_1ist)

    counter = 0
    for ip_address in device_ip_list:

        if valid_ipv4(ip_address):
            device_data = {
                'device_type': device_type,
                'ip': ip_address,
                'username': username,
                'password': password
            }
            #connect(device_data, device_commands_1ist, counter)
            counter += 1
            my_thread = threading.Thread(target=connect, args=(device_data, device_commands_1ist, counter))
            my_thread.start()   
        else:
            print('Invalid IP address: %s' % ip_address )  

    main_thread = threading.currentThread()
    for some_thread in threading.enumerate():
        if some_thread != main_thread:
            print(some_thread)
            some_thread.join()    


# Start here
if __name__ == '__main__':

    #todo: I need to add a format to the logs to make them tidier. check python doc
    logging.getLogger().setLevel(logging.ERROR)

    main()

输出样本:

<Thread(Thread-1, started 7132)>
======= IP: 192.168.1.130 ======= 11

config term

SW-130(config)#console timeout 0

SW-130(config)#wr mem

SW-130(config)#end

SW-130#
==================================== 11

======= IP: 192.168.1.245 ======= 43

config term

SW-245(config)#console timeout 0

SW-245(config)#wr mem

SW-245(config)#end

SW-245#
==================================== 43

======= IP: 192.168.1.106 ======= 4

config term

SW-106(config)#console timeout 0

SW-106(config)#wr mem

SW-106(config)#end

SW-106#
==================================== 4

======= IP: 192.168.1.230 ======= 38

config term

SW-230(config)#console timeout 0

SW-230(config)#wr mem

SW-230(config)#end

SW-230#
==================================== 38

======= IP: 192.168.1.199 ======= 28

config term

Warning: 1 user(s) already in config mode.
SW-199(config)#console timeout 0

SW-199(config)#wr mem

SW-199(config)#end

SW-199#
==================================== 28

======= IP: 192.168.1.239 ======= 40

config term

SW-239(config)#console timeout 0

SW-239(config)#wr mem

SW-239(config)#end

SW-239#
==================================== 40

======= IP: 192.168.1.231 ======= 39

config term

SW-231(config)#console timeout 0

SW-231(config)#wr mem

SW-231(config)#end

SW-231#
==================================== 39

======= IP: 192.168.1.244 ======= 42

config term

SW-244(config)#console timeout 0

SW-244(config)#wr mem

SW-244(config)#end

SW-244#
==================================== 42

======= IP: 192.168.1.108 ======= 6
======= IP: 192.168.1.104 ======= 2

config term

SW-108(config)#console timeout 0

SW-108(config)#wr mem

SW-108(config)#end

SW-108#

config term

SW-104(config)#console timeout 0

SW-104(config)#wr mem

SW-104(config)#end

SW-104#
==================================== 6

==================================== 2

======= IP: 192.168.1.110 ======= 8
======= IP: 192.168.1.149 ======= 13

config term

SW-110(config)#console timeout 0

SW-110(config)#wr mem

SW-110(config)#end

SW-110#
==================================== 8


config term

SW-149(config)#console timeout 0

SW-149(config)#wr mem

SW-149(config)#end

SW-149#
==================================== 13

======= IP: 192.168.1.161 ======= 20
======= IP: 192.168.1.240 ======= 41

config term

SW-161(config)#console timeout 0

SW-161(config)#wr mem

SW-161(config)#end

SW-161#

config term

SW-240(config)#console timeout 0

SW-240(config)#wr mem

SW-240(config)#end

SW-240#
==================================== 20

==================================== 41

======= IP: 192.168.1.157 ======= 15

config term

SW-157(config)#console timeout 0

SW-157(config)#wr mem

SW-157(config)#end

SW-157#
==================================== 15

======= IP: 192.168.1.153 ======= 14

config term

SW-153(config)#console timeout 0

SW-153(config)#wr mem

SW-153(config)#end

SW-153#
==================================== 14

======= IP: 192.168.1.181 ======= 25
======= IP: 192.168.1.145 ======= 12
======= IP: 192.168.1.160 ======= 19

config term

SW-160(config)#console timeout 0

SW-160(config)#wr mem

SW-160(config)#end

SW-160#
config term

SW-145(config)#console timeout 0

SW-145(config)#wr mem

SW-145(config)#end

SW-145#
==================================== 12


config term

SW-181(config)#console timeout 0

SW-181(config)#wr mem

SW-181(config)#end

SW-181#

==================================== 19

==================================== 25

======= IP: 192.168.1.107 ======= 5
======= IP: 192.168.1.3 ======= 45

config term

SW-003(config)#console timeout 0

SW-003(config)#wr mem

SW-003(config)#end

SW-003#======= IP: 192.168.1.105 ======= 3

config term

SW-105(config)#console timeout 0

SW-105(config)#wr mem

SW-105(config)#end

SW-105#

==================================== 45


config term

SW-107(config)#console timeout 0

SW-107(config)#wr mem

SW-107(config)#end

SW-107#
==================================== 3

==================================== 5

======= IP: 192.168.1.112 ======= 10
======= IP: 192.168.1.180 ======= 24
======= IP: 192.168.1.66 ======= 48

config term

SW-066(config)#console timeout 0

SW-066(config)#wr mem

SW-066(config)#end

SW-066#

config term

SW-ROOM(config)#console timeout 0

SW-ROOM(config)#wr mem

SW-ROOM(config)#end

SW-ROOM#
==================================== 48


==================================== 24

======= IP: 192.168.1.227 ======= 37

config term

SW-227(config)#console timeout 0

SW-227(config)#wr mem

SW-227(config)#end

SW-227#
==================================== 37
config term

SW-112(config)#console timeout 0

SW-112(config)#wr mem

SW-112(config)#end

SW-112#
==================================== 10


======= IP: 192.168.1.17 ======= 22

config term

SW-017(config)#console timeout 0

SW-017(config)#wr mem

SW-017(config)#end

SW-017#
==================================== 22

======= IP: 192.168.1.214 ======= 34

config term

SW-214(config)#console timeout 0

SW-214(config)#wr mem

SW-214(config)#end

SW-214#
==================================== 34

======= IP: 192.168.1.8 ======= 49
======= IP: 192.168.1.103 ======= 1

config term

SW-008(config)#console timeout 0

SW-008(config)#wr mem

SW-008(config)#end

SW-008#

==================================== 49

config term

Warning: 1 user(s) already in config mode.
SW-103(config)#console timeout 0

SW-103(config)#wr mem

SW-103(config)#end

SW-103#
==================================== 1

======= IP: 192.168.1.196 ======= 27
======= IP: 192.168.1.194 ======= 26
======= IP: 192.168.1.158 ======= 16

config term

SW-158(config)#console timeout 0

SW-158(config)#wr mem

SW-158(config)#end

SW-158#======= IP: 192.168.1.109 ======= 7

config term

SW-109(config)#console timeout 0

SW-109(config)#wr mem

SW-109(config)#end

SW-109#
==================================== 7

======= IP: 192.168.1.63 ======= 46

config term

SW-063(config)#console timeout 0

SW-063(config)#wr mem

SW-063(config)#end

SW-063#

==================================== 16

==================================== 46

config term

SW-194(config)#console timeout 0

SW-194(config)#wr mem

SW-194(config)#end

SW-194#
==================================== 26


======= IP: 192.168.1.21 ======= 29
config term

SW-196(config)#console timeout 0

SW-196(config)#wr mem

SW-196(config)#end

SW-196#

config term

SW-021(config)#console timeout 0

SW-021(config)#wr mem

SW-021(config)#end

SW-021#
==================================== 29


==================================== 27

======= IP: 192.168.1.212 ======= 32
======= IP: 192.168.1.215 ======= 35
======= IP: 192.168.1.210 ======= 30

config term

SW-210(config)#console timeout 0

SW-210(config)#wr mem

SW-210(config)#end

SW-210#
config term

SW-215(config)#console timeout 0

SW-215(config)#wr mem

SW-215(config)#end

SW-215#


config term

SW-212(config)#console timeout 0

SW-212(config)#wr mem

SW-212(config)#end

SW-212#
==================================== 32

==================================== 30

==================================== 35

======= IP: 192.168.1.216 ======= 36
======= IP: 192.168.1.99 ======= 50

config term

SW-099(config)#console timeout 0

SW-099(config)#wr mem

SW-099(config)#end

SW-099#======= IP: 192.168.1.159 ======= 17

config term

SW-159(config)#console timeout 0

SW-159(config)#wr mem

SW-159(config)#end

SW-159#
==================================== 17


==================================== 50


config term

SW-216(config)#console timeout 0

SW-216(config)#wr mem

SW-216(config)#end

SW-216#
==================================== 36
======= IP: 192.168.1.65 ======= 47

config term

SW-065(config)#console timeout 0

SW-065(config)#wr mem

SW-065(config)#end

SW-065#
==================================== 47


======= IP: 192.168.1.28 ======= 44

config term

SW-028(config)#console timeout 0

SW-028(config)#wr mem

SW-028(config)#end

SW-028#
==================================== 44

======= IP: 192.168.1.111 ======= 9
======= IP: 192.168.1.162 ======= 21
======= IP: 192.168.1.211 ======= 31

config term

SW-211(config)#console timeout 0

SW-211(config)#wr mem

SW-211(config)#end

SW-211#

config term

SW-162(config)#console timeout 0

SW-162(config)#wr mem

SW-162(config)#end

SW-162#
==================================== 21


==================================== 31

config term

SW-111(config)#console timeout 0

SW-111(config)#wr mem

SW-111(config)#end

SW-111#
==================================== 9

======= IP: 192.168.1.213 ======= 33

config term

SW-213(config)#console timeout 0

SW-213(config)#wr mem

SW-213(config)#end

SW-213#
==================================== 33

======= IP: 192.168.1.172 ======= 23

config term

Warning: 1 user(s) already in config mode.
SW-SW(config)#console timeout 0

SW-SW(config)#wr mem

SW-SW(config)#end

SW-SW#
==================================== 23

======= IP: 192.168.1.16 ======= 18

config term

SW-016(config)#console timeout 0

SW-016(config)#wr mem

SW-016(config)#end

SW-016#
==================================== 18

<Thread(Thread-2, stopped 16804)>
<Thread(Thread-3, stopped 17916)>
<Thread(Thread-4, stopped 11896)>
<Thread(Thread-5, stopped 20080)>
<Thread(Thread-6, stopped 15532)>
<Thread(Thread-7, started 20408)>
<Thread(Thread-8, stopped 11456)>
<Thread(Thread-9, started 564)>
<Thread(Thread-10, stopped 18940)>
<Thread(Thread-11, stopped 17404)>
<Thread(Thread-12, stopped 10824)>
<Thread(Thread-13, stopped 6676)>
<Thread(Thread-14, stopped 5596)>
<Thread(Thread-15, stopped 15480)>
<Thread(Thread-16, stopped 19524)>
<Thread(Thread-17, stopped 12048)>
<Thread(Thread-18, started 15988)>
<Thread(Thread-19, stopped 17740)>
<Thread(Thread-20, stopped 20304)>
<Thread(Thread-21, stopped 14104)>
<Thread(Thread-22, stopped 16340)>
<paramiko.Transport at 0x1e9ec2e8 (unconnected)>
<Thread(Thread-24, stopped 18164)>
<paramiko.Transport at 0x1e9ec8d0 (unconnected)>
<Thread(Thread-26, stopped 14248)>
<paramiko.Transport at 0x1e9ecd30 (unconnected)>
<paramiko.Transport at 0x1e9ec780 (unconnected)>
<paramiko.Transport at 0x1e94da20 (unconnected)>
<paramiko.Transport at 0x1e9f71d0 (unconnected)>
<paramiko.Transport at 0x1e9ecb00 (unconnected)>
<Thread(Thread-32, stopped 13636)>
<Thread(Thread-36, stopped 10472)>
<paramiko.Transport at 0x1e9f7cc0 (unconnected)>
<paramiko.Transport at 0x1e9f7ef0 (unconnected)>
<paramiko.Transport at 0x1ea04a20 (unconnected)>
<paramiko.Transport at 0x1ea04160 (unconnected)>
<paramiko.Transport at 0x1e9f7630 (unconnected)>
<paramiko.Transport at 0x1ea04390 (unconnected)>
<paramiko.Transport at 0x1ea04c50 (unconnected)>
<paramiko.Transport at 0x1e9f7400 (unconnected)>
<Thread(Thread-42, stopped 17680)>
<paramiko.Transport at 0x1ea046a0 (unconnected)>
<Thread(Thread-45, stopped 18884)>
<paramiko.Transport at 0x1ea0f0b8 (unconnected)>
<paramiko.Transport at 0x1e9ecf60 (unconnected)>
<Thread(Thread-47, stopped 12056)>
<Thread(Thread-48, stopped 16540)>
<paramiko.Transport at 0x1e9f7a90 (unconnected)>
<paramiko.Transport at 0x1ea2c1d0 (unconnected)>
<paramiko.Transport at 0x1ea20668 (unconnected)>
<Thread(Thread-52, stopped 11860)>
<paramiko.Transport at 0x1ea0f208 (unconnected)>
<Thread(Thread-54, stopped 18416)>
<Thread(Thread-56, stopped 15760)>
<paramiko.Transport at 0x1ea047f0 (unconnected)>
<paramiko.Transport at 0x1eb362b0 (unconnected)>
<Thread(Thread-58, stopped 19744)>
<Thread(Thread-60, stopped 15468)>
<paramiko.Transport at 0x1e1f7940 (unconnected)>
<Thread(Thread-61, stopped 2940)>
<paramiko.Transport at 0x1eb36ef0 (unconnected)>
<Thread(Thread-63, stopped 5980)>
<Thread(Thread-64, stopped 2184)>
<Thread(Thread-65, stopped 16848)>
<Thread(Thread-66, stopped 18964)>
<Thread(Thread-67, stopped 20416)>
<paramiko.Transport at 0x1eb45470 (unconnected)>
<Thread(Thread-69, stopped 12828)>
<paramiko.Transport at 0x1eb45f28 (unconnected)>
<Thread(Thread-71, stopped 5436)>
<Thread(Thread-72, stopped 17076)>
<Thread(Thread-73, stopped 5876)>
<paramiko.Transport at 0x1eb3f400 (unconnected)>
<Thread(Thread-75, stopped 15804)>
<paramiko.Transport at 0x1eb3fb00 (unconnected)>
<Thread(Thread-77, stopped 17612)>
<paramiko.Transport at 0x1eb3ff28 (unconnected)>
<paramiko.Transport at 0x1eb3f860 (unconnected)>
<Thread(Thread-80, stopped 5204)>
<paramiko.Transport at 0x1eb5f470 (unconnected)>
<Thread(Thread-82, stopped 18892)>
<Thread(Thread-83, stopped 1492)>

0 个答案:

没有答案