Как сделать вывод Tidy в потоке Python Netmiko - PullRequest
0 голосов
/ 28 февраля 2019

Я написал этот код для настройки различных коммутаторов от разных производителей, используя 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)
Почему я вижу эту строку, если я использовал with ConnectHandler(**device_data), чтобы убедиться, что соединения закрыты правильно. Правильно ли обрабатывается исключение, можно ли сделать его лучше? Правильно ли я использую менеджер контекста, то есть 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)>
...