diff --git a/confluent/console.py b/confluent/console.py index b0d53a6e..a7edab7d 100644 --- a/confluent/console.py +++ b/confluent/console.py @@ -14,6 +14,21 @@ import random _handled_consoles = {} +class Console(object): + """This is the class defining the interface a console plugin must return + for the _console/session element""" + def __init__(self, node, config): + raise NotImplementedException("Subclassing required") + + def connect(self, callback): + raise NotImplementedException("Subclassing required") + + def write(self, data): + raise NotImplementedException("Subclassing required") + + def wait_for_data(self, timeout=600): + raise NotImplementedException("Subclassing required") + class _ConsoleHandler(object): def __init__(self, node, configmanager): self._console = plugin.handle_path("/node/%s/_console/session" % node, diff --git a/confluent/httpapi.py b/confluent/httpapi.py index a501de5a..9a146016 100644 --- a/confluent/httpapi.py +++ b/confluent/httpapi.py @@ -200,7 +200,7 @@ def resourcehandler(env, start_response): yield "404 - Request path not recognized" return for rsp in hdlr: - yield json.dumps(rsp, separators=(',', ':')) + yield rsp.json() def serve(): diff --git a/confluent/pluginapi.py b/confluent/pluginapi.py index 6b3dfcf0..50d9fd55 100644 --- a/confluent/pluginapi.py +++ b/confluent/pluginapi.py @@ -17,6 +17,7 @@ # functions. Console is special and just get's passed through # see API.txt +import confluent.console as console import os import sys @@ -68,6 +69,11 @@ nodeelements = { } } +def stripnode(iterablersp, node): + for i in iterablersp: + i.strip_node(node) + yield i + def handle_path(path, operation, configmanager): '''Given a full path request, return an object. @@ -89,12 +95,18 @@ def handle_path(path, operation, configmanager): [node], plugroute['pluginattrs']) for attrname in plugroute['pluginattrs']: if attrname in nodeattr[node]: - return pluginmap[nodeattr[node][attrname]['value']].__dict__[operation]( + passvalue = pluginmap[nodeattr[node][attrname]['value']].__dict__[operation]( nodes=(node,), element=element, configmanager=configmanager) if plugroute['default']: - return pluginmap[plugroute['default']].__dict__[operation]( + passvalue pluginmap[plugroute['default']].__dict__[operation]( nodes=(node,), element=element, configmanager=configmanager) + if isinstance(passvalue, console.Console): + return passvalue + else: + return stripnode(passvalue) + else: + raise Exception("TODO: notfoundexception") diff --git a/plugins/ipmi.py b/plugins/ipmi.py index bfddccab..52169d43 100644 --- a/plugins/ipmi.py +++ b/plugins/ipmi.py @@ -1,4 +1,6 @@ import collections +import confluent.console +import confluent.messages as msg import eventlet import eventlet.event import eventlet.greenpool as greenpool @@ -90,7 +92,7 @@ def get_conn_params(node, configdata): } -class Console(object): +class IpmiConsole(confluent.console.Console): def __init__(self, node, config): crypt = config.decrypt config.decrypt = True @@ -250,13 +252,15 @@ class IpmiHandler(object): wait_on_ipmi() if self.element == 'power/state': if 'read' == self.op: - return self.call_ipmicmd(self.ipmicmd.get_power) + power = self.call_ipmicmd(self.ipmicmd.get_power) + return msg.PowerState(node=self.node, + state=power['powerstate']) def create(nodes, element, configmanager): if element == '_console/session': if len(nodes) > 1: raise Exception("_console/session does not support multiple nodes") - return Console(nodes[0], configmanager) + return IpmiConsole(nodes[0], configmanager) else: raise Exception( "TODO(jbjohnso): ipmi api implementation of %s" % element)