From 89ab76b4288ddca8f1127d78f6542be3002605d0 Mon Sep 17 00:00:00 2001 From: Stephen Soltesz Date: Mon, 4 May 2009 23:02:54 +0000 Subject: [PATCH] updated documentation for Monitor API calls. --- docs/Monitor.xml.in | 137 +++----------------- web/MonitorWeb/monitorweb/monitor_xmlrpc.py | 60 ++++++++- 2 files changed, 75 insertions(+), 122 deletions(-) diff --git a/docs/Monitor.xml.in b/docs/Monitor.xml.in index dd38353..cb29420 100644 --- a/docs/Monitor.xml.in +++ b/docs/Monitor.xml.in @@ -6,146 +6,45 @@ - PlanetLab Node Manager API Documentation + PlanetLab Administrative-Monitor API Documentation Introduction - The PlanetLab Node Manager API (NMAPI) is the interface through + The PlanetLab Administrative-Monitor API (Admin-Mon) is the interface through which the slices access the Node API.
Authentication - Authentication for NM operations is based on the identity of the - connecting slice. For slices whose roles are defined as - 'nm-controller', the target slice must be listed delegated and as - controlled by the calling slice. + Authentication for operations is based on the identity of the + connecting user. The standard PLCAPI authetication is used here. -
-
- Delegation - None
Connection - The NM XMLRPC server listens locally on every PlanetLab node at http://localhost:812. - The NM XMLRPC server can be accessed remotely using an SSH connection through the nm-controller account. Rather than a standard shell, a special command is run that forwards all standard input to the local XMLRPC server, essentially XML-RPC over ssh. + The Admin-Mon XMLRPC server listens at http://monitor.planet-lab.org:8082. + The XMLRPC server can be accessed remotely using a standard Python XMLRPC shell.
- An Example using the PLC and NM API + An Example using the PLC and Admin-Mon API + + Access to the API is via standard XMLRPC. A simple example is below. - The nm-controller slice is given a stub account such that it can - be accessed over ssh. So rather than logging into NM server listens - locally on every PlanetLab node at http://localhost:812. - - -controller_slice_fields = {'name' : 'princeton_mycontroller', - 'instantiation' : 'nm-controller', - 'url' : 'http://www.yourhost.com', - 'description' : 'a brief description of this slice.', } -controller_slice_id = api.AddSlices(plauth, controller_slice_fields) +import xmlrpclib +auth = {'Username' : API_AUTH_USER, + 'AuthMethod' : 'password', + 'AuthString' : API_AUTH_PASSWORD} +api = xmlrpclib.Server(API_SERVER, verbose=False, allow_none=True) + +if api.upAndRunning(): + for i in api.getSiteStatus(auth): + print i - After this, the controller owner, should both add users and nodes to - this slice. As well, the controller slice is created using the standard - PlanetLab and NM mechanism. So, wait at least 15 minutes before attempting - to access the controller slice on any node. - - Subsequently, slices that will be delegated to this controller will - be registered at PLC. An example follows. - - - -delegated_slice_fields = {'name' : 'anothersite_mydelegated', - 'instantiation' : 'delegated', - 'url' : 'http://www.yourhost.com', - 'description' : 'a brief description of this slice.', } -delegated_slice_id = api.AddSlices(plauth, delegated_slice_fields) - -# Get ticket for this slice. -ticket = api.GetSliceTicket(plauth, "princetondsl_solteszdelegated") - - - After the slice is registered with PLC, and your application has the - Ticket, the last step is to redeem the ticket by presenting it to the NM - through the nm-controller account. The following code formats the message - correctly. - - -# generate an XMLRPC request. -print xmlrpclib.dumps((ticket,), 'Ticket') - - - Finally, this message must be sent to the NM using the controller - account. It should be possible to create a program that creates the ssh - connection or to use a library that does this automatically such as: - pyXMLRPCssh - - - - Or, you could use something much simpler. Assuming the output from - dumps() above, is saved to a file called - ticket.txt, you could run a command like: - - - -cat ticket.txt | ssh princeton_mycontroller@mynode.someuniversity.edu - - - Alternately, - - -p = subprocess.Popen(['/usr/bin/ssh', 'princeton_mycontroller@mynode.someuniversity.edu'], - stdin=subprocess.PIPE, stdout=subprocess.PIPE) -print >>p.stdin, xmlrpclib.dumps((ticket,), 'Ticket') -p.stdin.close() -print xmlrpclib.loads(p.stdout.read()) -p.wait() - - - The following is a stub to use as you would use the current - xmlrpclib.Server() object, but redirects the connection of SSH. - - -"""XML-RPC over SSH. - - To use, create an XmlRpcOverSsh object like so: - >>> api = XmlRpcOverSsh('princeton_deisenst@planetlab-1.cs.princeton.edu') - and call methods as with the normal xmlrpclib.ServerProxy interface. -""" - -from subprocess import PIPE, Popen -from xmlrpclib import Fault, dumps, loads - -__all__ = ['XmlRpcOverSsh'] - - -class XmlRpcOverSsh: - def __init__(self, userAtHost): - self.userAtHost = userAtHost - - def __getattr__(self, method): - return _Method(self.userAtHost, method) - - -class _Method: - def __init__(self, userAtHost, method): - self.userAtHost = userAtHost - self.method = method - - def __call__(self, *args): - p = Popen(['ssh', self.userAtHost], stdin=PIPE, stdout=PIPE) - stdout, stderr = p.communicate(dumps(args, self.method)) - if stderr: - raise Fault(1, stderr) - else: - return loads(stdout) - -
diff --git a/web/MonitorWeb/monitorweb/monitor_xmlrpc.py b/web/MonitorWeb/monitorweb/monitor_xmlrpc.py index ce1f26c..45f5c01 100644 --- a/web/MonitorWeb/monitorweb/monitor_xmlrpc.py +++ b/web/MonitorWeb/monitorweb/monitor_xmlrpc.py @@ -121,15 +121,22 @@ class MonitorXmlrpcServer(object): @cherrypy.expose @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'], accepts=[], - returns=Parameter(bool, 'True is successful')) + returns=Parameter(bool, 'True if successful')) def upAndRunning(self): - """ This is a test """ + """ This call can indicate to a script whether the server is up + and running before trying any more sophisticated operations. """ return True # SITES ------------------------------------------------------------ @cherrypy.expose + @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(list, 'array of SiteStatus records')) def getSiteStatus(self, auth): + """ This call returns a list that includes the status and observations + of all sites, including those blacklisted. At this time, there is no + indication which sites are blacklisted from this list. """ ret_list = [] sites = HistorySiteRecord.query.all() for q in sites: @@ -139,7 +146,12 @@ class MonitorXmlrpcServer(object): return ret_list @cherrypy.expose + @export_to_docbook(roles=['admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(bool, 'True on success.')) def clearSitePenalty(self, auth, loginbase): + """ Rather than waiting for monitor to run automatically, this call + will manually clear a site's penalties. """ sitehist = SiteInterface.get_or_make(loginbase=loginbase) sitehist.clearPenalty() #sitehist.applyPenalty() @@ -148,7 +160,12 @@ class MonitorXmlrpcServer(object): return True @cherrypy.expose + @export_to_docbook(roles=['admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(bool, 'True on success.')) def increaseSitePenalty(self, auth, loginbase): + """ Rather than waiting for monitor to run automatically, this call + will manually increase a site's penalties.""" sitehist = SiteInterface.get_or_make(loginbase=loginbase) sitehist.increasePenalty() #sitehist.applyPenalty() @@ -158,7 +175,13 @@ class MonitorXmlrpcServer(object): # NODES ------------------------------------------------------------ @cherrypy.expose + @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(list, 'array of NodeStatus records.')) def getNodeStatus(self, auth): + """ This call returns a list of all nodes, including those + blacklisted. The current observation and recorded status of each node + is returned.""" ret_list = [] sites = HistoryNodeRecord.query.all() for q in sites: @@ -168,14 +191,28 @@ class MonitorXmlrpcServer(object): return ret_list @cherrypy.expose + @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(bool, 'True on success.')) def getRecentActions(self, auth, loginbase=None, hostname=None): + """ Monitor takes various actions on sites (such as applying + penalties) and nodes (such as repairing a node installation via + BootManager). As well, it makes a log of every email message sent + out, or believed to be sent. This call returns a list of all actions, + filtered on site or for a specific node. """ ret_list = [] return ret_list # BLACKLIST ------------------------------------------------------------ @cherrypy.expose + @export_to_docbook(roles=['tech', 'user', 'pi', 'admin'], + accepts=[Parameter(dict, "Auth struct")], + returns=Parameter(bool, 'True on success.')) def getBlacklist(self, auth): + """ Return a list of all nodes and sites that are excluded from + penalties. Currently there is no way to exclude a node or site + from being monitored. """ bl = BlacklistRecord.query.all() ret_list = [] for q in bl: @@ -184,20 +221,37 @@ class MonitorXmlrpcServer(object): ret_list.append(d) return ret_list - # datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime, time_format))) @cherrypy.expose + @export_to_docbook(roles=['admin'], + accepts=[Parameter(dict, "Auth struct"), + Parameter(str, "hostname"), + Parameter(int, "expires number of seconds from time.now()")], + returns=Parameter(bool, 'True on success.')) def addHostToBlacklist(self, auth, hostname, expires=0): + """ Add a host to the blacklist, with an optional expiration time""" bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires) return True @cherrypy.expose + @export_to_docbook(roles=['admin'], + accepts=[Parameter(dict, "Auth struct"), + Parameter(str, "loginbase"), + Parameter(int, "expires number of seconds from time.now()")], + returns=Parameter(bool, 'True on success.')) def addSiteToBlacklist(self, auth, loginbase, expires=0): + """ Add a site to the blacklist, with an optional expiration time""" bl = BlacklistRecord.findby_or_create(hostname=hostname, expires=expires) return True @cherrypy.expose + @export_to_docbook(roles=['admin'], + accepts=[Parameter(dict, "Auth struct"), + Parameter(str, "loginbase"), + Parameter(str, "hostname"),], + returns=Parameter(bool, 'True on success.')) def deleteFromBlacklist(self, auth, loginbase=None, hostname=None): + """ Remove a host or site from the blacklist """ if (loginbase==None and hostname == None) or (loginbase != None and hostname != None): raise Exception("Please specify a single record to delete: either hostname or loginbase") elif loginbase != None: -- 2.43.0