Skip to content

Commit 34ce02c

Browse files
author
Jérome Tissières
committed
rename of the script
1 parent 6f47975 commit 34ce02c

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

scp-multi-upload.py

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

0 commit comments

Comments
 (0)