-
Notifications
You must be signed in to change notification settings - Fork 5
/
scp-multi-upload.py
134 lines (113 loc) · 3.86 KB
/
scp-multi-upload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python
from getpass import getpass
from argparse import ArgumentParser
import csv
import os.path
import sys
from time import time
from concurrent.futures import ProcessPoolExecutor, wait
from netmiko import ConnLogOnly, file_transfer
# --- Define the threads
MAX_THREADS = 8
# --- Check file exists function
def is_valid_file(parser, arg):
if not os.path.exists(arg):
parser.error("The file %s does not exist!" % arg)
else:
return(arg)
# --- Confirmation function
def confirm(prompt=None, resp=False):
if prompt is None:
prompt = 'Confirm'
if resp:
prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n')
else:
prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y')
while True:
ans = input(prompt)
if not ans:
return resp
if ans not in ['y', 'Y', 'n', 'N']:
print ('please enter y or n.')
continue
if ans == 'y' or ans == 'Y':
return True
if ans == 'n' or ans == 'N':
return False
# --- Upload Netmiko function
def upload_nemiko(net_device):
print("Upload on %s:" % net_device.get('host'))
# Create the Netmiko SSH connection
ssh_conn = ConnLogOnly(**net_device)
# Test access, skip if failed
if ssh_conn is None:
print("Logging in failed... skipping")
print(40*"-")
else:
transfer_dict = {}
transfer_dict = file_transfer(ssh_conn,
source_file=SOURCE_FILE,
dest_file=SOURCE_FILE,
)
print(80*"=")
print('Results for %s:' % net_device.get('host'))
print('File exists already: ',transfer_dict['file_exists'])
print('File transferred: ',transfer_dict['file_transferred'])
print('MD5 verified :',transfer_dict['file_verified'])
# --- Init argparse
parser = ArgumentParser()
parser.add_argument("filename", help="The file to upload", metavar='FILE', type=lambda x: is_valid_file(parser, x))
args = parser.parse_args()
# --- Define the OS file to upload
SOURCE_FILE = (args.filename)
# --- Check the hosts.csv file and get the list of hosts
VENDORS_TYPES = ["cisco_ios", "arista_eos", "juniper_junos", "cisco_nxos"]
VENDOR_TYPE = ''
HOSTS_LIST = []
with open("./hosts.csv", 'r') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=',')
for row in csv_reader:
if VENDOR_TYPE in VENDORS_TYPES not in str(row[1]):
print('Invalid CSV, please check the vendor types. Must be: cisco_ios, arista_eos, juniper_junos or cisco_nxos')
sys.exit()
HOSTS_LIST.append(row[0])
# --- Ask confirmation
print(80*"=")
print('Please, confirm the upload of',SOURCE_FILE+' on: ')
print(*HOSTS_LIST, sep ='\n')
prompt = str("Proceed?")
if confirm(prompt=prompt, resp=False) == True:
# --- Get credentials
print(80*"-")
USERNAME = input('Please insert your username: ')
print("And your password")
PASSWORD = getpass()
print(80*"-")
# --- Get the time for timing
start_time = time()
# --- Set the number of threads
pool = ProcessPoolExecutor(MAX_THREADS)
# --- SCP itself, in multi-threads
SW_LIST = []
FUTURE_LIST = []
with open("./hosts.csv", 'r') as csvfile:
SW_LIST = csv.reader(csvfile, delimiter=',')
for CSV_ROW in SW_LIST:
HOST = CSV_ROW[0]
DEVICE_TYPE = CSV_ROW[1]
net_device = {
'device_type': DEVICE_TYPE,
'host': HOST,
'username': USERNAME,
'password': PASSWORD,
}
FUTURE = pool.submit(upload_nemiko, net_device)
FUTURE_LIST.append(FUTURE)
wait(FUTURE_LIST)
# --- All done confirmation
print(80*"=")
print("Uploads completed in {} seconds.".format(time() - start_time))
print(80*"=")
else:
print("Operation aborted, goodbye.")
print(80*"=")