Skip to content

Instantly share code, notes, and snippets.

@noahwilliamsson
Created July 31, 2019 10:55
Show Gist options
  • Save noahwilliamsson/75217d8cfad227caecbc177ee94754cf to your computer and use it in GitHub Desktop.
Save noahwilliamsson/75217d8cfad227caecbc177ee94754cf to your computer and use it in GitHub Desktop.
Execute a list of (hard-coded) commands against Ubiquiti EdgeSwitches
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Execute a list of (hard-coded) commands against Ubiquiti EdgeSwitches
#
# The output will look similar to this:
# lon-sw-core01 [show client-info] show client-info
# lon-sw-core01 [show client-info]
# lon-sw-core01 [show client-info] VLAN-ID MAC Address Intf Hostname IP Address
# lon-sw-core01 [show client-info] ------- ----------------- ----- ----------------------- -----------------------
# lon-sw-core01 [show client-info] 1 00:00:74:FA:0C:5E 0/8 33.20.1.49
#
# Usage:
# ./edgeswitch-exec-commands.py <hostname|prefix|all> [[[<username] <password>] <enable password>]
#
# Examples:
# ./edgeswitch-exec-commands.py switch.example.com # using default credentials
# ./edgeswitch-exec-commands.py switch.example.com ubnt userP4ssword enabl3P4assword
#
# Assuming generate_switch_hostnames() yields a list of hostnames:
# ./edgeswitch-exec-commands.py lon-sw-core01 ubnt userP4ssword enabl3P4assword
# ./edgeswitch-exec-commands.py rkv-sw-core ubnt password
# ./edgeswitch-exec-commands.py all | tee all-switch-statuses.txt
#
# Install:
# apt-get install -y python-pexpect
#
# -- noah@hack.se, 2019
#
import pexpect
import subprocess
import sys
from datetime import datetime
# Default credentials and prompt
user = 'ubnt'
password = user
enable = user
prompt = '\S+ (\([A-Za-z0-9 /,-]\))?[#>]'
# List of commands to send
command_list = [
'show sysinfo',
'show client-info',
'show mbuf total',
'show mbuf detail',
'show process cpu',
'show tech-support',
]
# Generate hostnames to known switches (for the 'all' hostname argument)
def generate_switch_hostnames():
switches = []
# London, UK
site = 'lon'
for i in range(2):
switches.append('{}-sw-core{:02d}'.format(site, i+1))
for i in range(2):
switches.append('{}-sw-up{:02d}'.format(site, i+1))
for i in range(16):
switches.append('{}-sw-access{:02d}'.format(site, i+1))
# Reykjavik, IS
site = 'rkv'
for i in range(2):
switches.append('{}-sw-core{:02d}'.format(site, i+1))
for i in range(8):
switches.append('{}-sw-access{:02d}'.format(site, i+1))
if len(sys.argv) > 4:
(host, user, password, enable) = sys.argv[1:5]
elif len(sys.argv) > 3:
(host, user, password) = sys.argv[1:4]
enable = password
elif len(sys.argv) > 2:
(host, user) = sys.argv[1:3]
password = enable = user
elif len(sys.argv) > 1:
host = sys.argv[1]
password = enable = user
else:
print('Usage: {} <switch-hostname|switch-hostname-prefix|all> [<user> [<password> [enable password]]]'.format(sys.argv[0]))
sys.exit(0)
# Seed list of switch hostnames with a generator function
switches = generate_switch_hostnames()
if host != 'all':
# Assume we were given an switch hostname prefix
switches = filter(lambda k: host in k, switches)
if not switches:
# Assume a switch hostname was supplied on the command line
switches = [host]
# Authenticate and execute commands on each switch
for switch in switches:
args = ['-o', 'StrictHostKeyChecking=no', '@'.join([user, switch])]
proc = pexpect.spawn('ssh', args)
# Login
proc.expect('password:')
proc.send(password + "\n")
proc.expect(prompt)
# Enable
proc.send("en\n")
proc.expect('Password:')
proc.send(enable + "\n")
proc.expect(prompt)
# Turn off pagination
proc.send("terminal length 0\n")
proc.expect(prompt)
# Extract data
for cmd in command_list:
now = datetime.now()
proc.send("{}\n".format(cmd))
proc.expect(prompt)
data = proc.before.decode('utf-8')
for line in data.strip().split('\n'):
print(' '.join(['[{}]'.format(now.strftime('%F %T')), switch, '[{}]'.format(cmd), line]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment