Skip to content

Instantly share code, notes, and snippets.

@jathanism
Last active August 29, 2015 14:13
Show Gist options
  • Save jathanism/a6bb04c0d6d0fc8eed6f to your computer and use it in GitHub Desktop.
Save jathanism/a6bb04c0d6d0fc8eed6f to your computer and use it in GitHub Desktop.
An example of fetching the time on any device where a specific user is found to be logged in. It's not the most useful example, but it's simple and gets the idea across on how to build workflows using ReactorlessCommando. It's also not super efficient, because it requires a new connection to each device for each subsequent step.
"""
user_example.py - Sample flow of using ReactorlessCommando.
This is an example of the following:
1. Run 'show users' on a list of devices.
2. Check if a certain user is found in the output for each device.
3. Execute 'show clock' on each device where user was found.
4. Display the results
"""
__author__ = 'Jathan McCollum'
__email__ = '[email protected]'
__version__ = '0.1.1'
import sys
from twisted.internet import defer, task, reactor
from twisted.python import log
# Uncomment me for verbose logging. Start the logging before any Trigger imports
# happen for MAXIMUM LOGGING. :)
#log.startLogging(sys.stdout, setStdout=False)
from trigger.cmds import ReactorlessCommando
class ShowClock(ReactorlessCommando):
commands = ['show clock']
class ShowUsers(ReactorlessCommando):
commands = ['show users']
def check_user(result, username):
"""
Check if ``username`` found in result for each device.
If it is, return a list of devices, or ``None``.
Since this result is coming back from a stock Commando subclass,
``result`` is a dictionary keyed by device hostname. This can be
customized in your Commando subclasses using ``.from_{vendor}()``
methods.
"""
clock_devices = [] # To track devices we want to check
for devname, results in result.items():
r = results['show users']
if username in r:
print 'FOUND %r logged in on %r!' % (username, devname)
clock_devices.append(devname)
return clock_devices or None
def check_time(result):
"""
Check the time or do nothing. The ``result`` is expected to be a list of
device names or ``None``.
Run 'show clock' on the devices and return that result, otherwise just pass
``None`` through to the end.
"""
# Result is a list of device hostnames
devices = result # For readability
if devices is not None:
print 'Fetching time for %r' % (devices,)
return ShowClock(devices).run()
return None
def stop_reactor(result):
"""Stop the reactor and pass the incoming ``result`` through."""
if reactor.running:
log.msg('STOPPING REACTOR!')
reactor.stop()
return result
def display_results(result, username, command):
# Let's print the results!
if result is None:
print 'User %r not found anywhere.' % (username,)
else:
print '\nResults for user %r:\n' % (username,)
for devname, results in result.items():
print devname
print '=' * len(devname)
print results[command]
print
def main(devices, username):
# Fetch the output of 'show users'
d = ShowUsers(devices).run()
# Check if ``username`` is logged in.... If no users are logged in
# check_user will return None. The result of check_user gets passed to the
# next callback (check_time)
d.addCallback(check_user, username)
# Run 'show clock' on the devices and return that result, otherwise just
# pass ``None`` through to the end.
d.addCallback(check_time)
# Stop the reactor once everything is done.
d.addBoth(stop_reactor)
reactor.run()
# d.result will be a dictionary keyed by device hostname, for any device on
# which the username was found to be logged in.
return d
if __name__ == '__main__':
devices = ['r1', 'r2'] # Replace me with your device names.
# User to check for. Flip this to test positive vs. negative results.
username = 'wood'
# username = 'bogus'
# Our master Deferred. Once we're done ``d.result`` has our dictionary of
# devices where ``username`` was found to be logged in or ``None``.
d = main(devices, username)
# And print the results.
display_results(d.result, username, 'show clock')
# Output for user 'wood':
"""
FOUND 'wood' logged in on 'r2':
Fetching time for ['r2']
Results for user 'wood':
r2
==
Wed Jan 7 12:18:09 2015
Timezone: PST8PDT
Clock source: NTP server (10.16.16.11)
"""
# Output for user 'bogus':
"""
User 'bogus' not found anywhere.
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment