-
Notifications
You must be signed in to change notification settings - Fork 0
/
3_complete.py
92 lines (75 loc) · 3.1 KB
/
3_complete.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
# This example show how to execute a command in several devices devices.
# The list of devices and credentials is specified in an external yaml file.
# Then with an input string filter we select which one are we interesting in.
# This filter can be by partial or full, name or IP, or 'all'
# It will also print how long it took to execute the command
# Change import settings
import yaml
import sys
import time
from netmiko import ConnectHandler, NetmikoTimeoutException, NetmikoAuthenticationException
# Reusable send command function
def send_command(dev: dict, cmd: str) -> str:
"""
Send command to device using Netmiko
:param dev: device info
:param cmd: command to execute
:return: Command output from device
"""
hostname = dev['hostname']
# remove key hostname from dictionary since it is not expected/valid for netmiko
del dev['hostname']
try:
# Use context manager to open and close the SSH session
with ConnectHandler(**dev) as ssh:
ssh.enable()
output = ssh.send_command(cmd)
output = output.strip()
except NetmikoTimeoutException:
output = 'Connection timed out'
except NetmikoAuthenticationException:
output = 'Authentication failed'
# re add key for future use
dev['hostname'] = hostname
return output
def get_devices(device_filter: str) -> dict:
"""
Get match devices from inventory bases on name or IP
:param device_filter: string to look for
:return: matching inventory
"""
with open('inventory.yml') as f:
inventory = yaml.safe_load(f.read())
matched_devices = []
if device_filter != 'all':
for device in inventory['hosts']:
if device_filter in device['hostname'] or device_filter in device['host']:
matched_devices.append(device)
inventory['hosts'] = matched_devices
return inventory
if __name__ == "__main__":
# get parameters from CLI. Choose the following 2 lines OR the next 2
# device_filter = sys.argv[1]
# command = ' '.join(sys.argv[2:])
device_filter = input('\nSpecify device filter: ')
command = input('\nCommand to run: ')
# Load devices from file with the filter
inventory = get_devices(device_filter)
# get the common variables for all devices
credentials = inventory['common_vars']
devices_counter = len(inventory['hosts'])
print(f'\nExecuting command: {command}\n')
# Start timer variable
execution_start_timer = time.perf_counter()
# Loop to repeat the command in all the inventory
for device in inventory['hosts']:
# update the device dictionary with the credentials and send command
device.update(credentials)
print('*** host: {} - ip: {}'.format(device['hostname'], device['host']))
# send command and store results
result = send_command(device, command)
# show result
print(f'{result}\n')
# Get and print finishing time
elapsed_time = time.perf_counter() - execution_start_timer
print(f"\n\"{command}\" executed in {devices_counter} devices in {elapsed_time:0.2f} seconds.\n")