Проблема с многопоточностью при подключении к нескольким устройствам одновременно

1

Я определяю основную функцию с def get_info(). Эта функция не принимает аргументы. Эта программа использует argumentParser для анализа аргументов из командной строки. Предоставленный аргумент представляет собой CSV файл с --csv. Это подбирает csv файл из текущего каталога и считывает строки, каждый из которых содержит IP-адрес, регистрируется в устройствах последовательно и запускает несколько команд, возвращая выходные данные и добавляя их в текстовый файл. При запуске кода он удаляет старый текстовый файл из каталога и создает новый выходной текстовый файл при его выполнении. Проблема: я хочу добиться этого с помощью модуля потоковой передачи, чтобы он брал 5 устройств параллельно и выводил их в файл. Проблема, которую я запускаю, связана с проблемами блокировки, поскольку один и тот же объект используется одним и тем же процессом одновременно. Вот пример кода, который я написал. Концепция резьбы для меня очень новая, поэтому, пожалуйста, поймите.

импорт getpass импорт csv импорт время импорт os импорт netmiko импорт paramiko из argparse import ArgumentParser из многопроцессорного импорта процесс, очередь

def get_ip (device_ip, output_q):

        try:
            ssh_session = netmiko.ConnectHandler(device_type='cisco_ios', ip=device_row['device_ip'],
                                                 username=ssh_username, password=ssh_password)
            time.sleep(2)
            ssh_session.clear_buffer()
        except (netmiko.ssh_exception.NetMikoTimeoutException,
                netmiko.ssh_exception.NetMikoAuthenticationException,
                paramiko.ssh_exception.SSHException) as s_error:
            print(s_error)

def main():

show_vlanfile = "pool.txt"
if os.path.isfile(show_vlanfile):
  try:
    os.remove(show_vlanfile)
  except OSError as e:
    print("Error: %s - %s." %(e.filename, e.strerror))

parser = ArgumentParser(description='Arguments for running oneLiner.py')
parser.add_argument('-c', '--csv', required=True, action='store', help='Location of CSV file')             
args = parser.parse_args()                                                                                 

ssh_username = input("SSH username: ")                                                                     
ssh_password = getpass.getpass('SSH Password: ')                                                           

with open(args.csv, "r") as file:                                                                          
    reader = csv.DictReader(file)                                                                          
    output_q = Queue(maxsize=5)                                                                            
    procs = []                                                                                             
    for device_row in reader:                                                                              
       # print("+++++ {0} +++++".format(device_row['device_ip']))                                          
         my_proc = Process(target=show_version_queue, args=(device_row, output_q))                         
         my_proc.start()                                                                                   
         procs.append(my_proc)                                                                             

# Make sure all processes have finished                                                                    
    for a_proc in procs:                                                                                   
        a_proc.join()                                                                                      

            commands = ["terminal length 0","terminal width 511","show run | inc hostname","show ip int brief | ex una","show

vlan brief "," длина терминала 70 "]
output = ''
для команд cmd:
output + = "\n"
output + = ssh_session.send_command (cmd)
output + = "\n"
с открытым ("pool.txt", 'a') в качестве выходного файла:
а не output_q.empty():
output_queue = output_q.get()
для x в output_queue:
outputfile.write (х)

если name == " main ":
главный()

Теги:
multithreading

1 ответ

0

Похоже, у вас есть код из примера Django:

def main():
    '''
    Use threads and Netmiko to connect to each of the devices in the database.
    '''
    devices = NetworkDevice.objects.all()

Вы должны переместить парсинг аргументов в основной поток. Вы должны прочитать CSV файл в основном потоке. У каждого дочернего потока должно быть соединение Netmiko-SSH.

Я говорю это как ваше текущее решение - все соединения SSH происходят в одном потоке, который вам не подходит.

На верхнем уровне main() должен иметь синтаксический анализ аргументов, удалять старый выходной файл, получать имя пользователя/пароль (при условии, что они одинаковы для всех устройств), перебирать CSV файл, получая IP-адрес для каждого устройства.

После того, как у вас есть IP-адрес, вы создаете поток, поток использует Netmiko-SSH для подключения к каждому устройству и получения вашего вывода. Затем я использовал очередь для передачи результатов с каждого устройства (обратно в основной поток).

Затем в основном потоке вы должны записать весь вывод в один файл.

Это выглядело бы примерно так:

https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case16_concurrency/threads_netmiko.py

Вот пример использования очереди (с многопроцессорностью), хотя вы, вероятно, можете легко адаптировать ее с помощью потока-очереди довольно легко.

https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case16_concurrency/processes_netmiko_queue.py

  • 0
    Спасибо за ответ. Я новичок в Python и обучения. Когда вы говорите, получить IP из CSV и создать поток, не могли бы вы предоставить мне фрагмент кода о том, как будет выглядеть код, так как это поможет мне построить на этом. Я никогда не занимался потоками ранее, что приводит меня к еще большему замешательству.
  • 0
    Согласно вашим инструкциям, я изменил код, но, похоже, не правильно. Не могли бы вы перейти и сообщить мне, если это нужно исправить. Я отредактировал основной код и вставил поверх него. Заранее спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню