Home > Enterprise >  Threading an upload to multiple devices with Python
Threading an upload to multiple devices with Python

Time:04-12

I'm trying to upload a file to a couple devices at the same time but without success so far. What I'm trying to do is to create 2 workers that follow up a csv containing a list of ips but it duplicates the same task:

import csv
from datetime import datetime
from netmiko import ConnectHandler, file_transfer
from netmiko.ssh_exception import NetmikoTimeoutException, NetmikoAuthenticationException
import threading

def parse_csv(filename) -> list:
    with open(filename, mode="r") as csv_file:
        csv_reader = csv.DictReader(csv_file)
        rows = [row for row in csv_reader]
    return rows

source_file = "/home/dev/file_to_upload" #file i want to upload
dest_file = "uploaded_file"
direction = "put"

def run_commands(ip):
    ios_device = {
        "device_type": "cisco_ios",
        "ip": ip,
        "username": "admin",
        "password": "password1",
        "fast_cli": False,
        "global_delay_factor": 4,
        "file_system": "flash:",
    }

    try:
        file_system = ios_device.pop("file_system")
        print(f'transffering to {ip}:')
        ssh_conn = ConnectHandler(**ios_device)
        ssh_conn.enable()
        transfer_dict = file_transfer(
            ssh_conn,
            source_file=source_file,
            dest_file=dest_file,
            file_system=file_system,
            direction=direction,
        overwrite_file=True,
        )
        print(transfer_dict)

    except ValueError or NetmikoTimeoutException as error:
        print(error)
        
    ssh_conn.disconnect()
    return

def main():
    FILENAME = "ios_update.csv"
    hosts = parse_csv(FILENAME)

    for host in hosts:
        t1 = threading.Thread(target=run_commands(host["ip"]), args=('Thread 1', 1))
        t2 = threading.Thread(target=run_commands(host["ip"]), args=('Thread 2', 2))
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        print(t1)
        print(t2)

if __name__ == "__main__":
    main()

The code works but it duplicates the task instead of doing it one by one. What's the correct approach in this case? Thanks!

CodePudding user response:

with open(filename, mode="r") as csv_file:

I could not test the code because this file does not exist, but I made configuration entries on many devices at the same time with the code below and I recommend it to you.

Instead of a single config line, you can convert it to filename as in your code. I hope that will be useful.

def _ssh_(nodeip):
    try:
        device = {
            'device_type': 'cisco',
            'ip': X.X.X.X,
            'username': username,
            'password': password,
       }
       net_connect = Netmiko(**device)
       print(nodeip.strip()   "  "   "success enter")
    except Exception as e:
        print(e)
        f_3.write(nodeip.strip()   "\n")
        return
                
    prompt_config_fnk = net_connect.find_prompt()
    hostname_fnk = prompt_config_fnk.strip("<"   ">")
    print(hostname_fnk)
    net_connect.send_command_timing("enable")
    output = net_connect.send_command_timing("config")
    print("config mode entered")
    net_connect.send_command_timing("acl 2010 ")
    net_connect.send_command_timing("quit")
    net_connect.send_command_timing("save")
                
    print("config done")
    with open("List_OK_2.txt", "a") as f:
        f.write(nodeip   "\n")  
    net_connect.disconnect()
                
with open("ip_list.txt", "r") as f_2:
    ip_list = f_2.readlines()

with open("ssh_unsuccess_2.txt", "w") as f_3:
    myPool = ThreadPool(100)
    result = myPool.map(_ssh_, ip_list)
  • Related