Last active
August 29, 2015 14:13
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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] | |
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