X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=api_calls.py;h=592335dfa06010f9a4079e0046e245c5965c1838;hb=ccc7b9c4b76a89faad66867b00d16ac45333b6de;hp=1e350c7c256a80f7e71b4fe34c551e921360539d;hpb=a869b6b1e66606b97fc654001275bb50b9f63206;p=nodemanager.git diff --git a/api_calls.py b/api_calls.py index 1e350c7..592335d 100644 --- a/api_calls.py +++ b/api_calls.py @@ -1,6 +1,4 @@ -# $Id$ -# $URL$ - +# """Sliver manager API. This module exposes an XMLRPC interface that allows PlanetLab users to @@ -20,6 +18,7 @@ import socket import struct import threading import xmlrpclib +import slivermanager try: from PLC.Parameter import Parameter, Mixed @@ -28,21 +27,19 @@ except: def Mixed(a = None, b = None, c = None): pass -import accounts +import account import logger -# TODO: These try/excepts are a hack to allow doc/DocBookLocal.py to -# import this file in order to extract the documentation from each -# exported function. +# TODO: These try/excepts are a hack to allow doc/DocBookLocal.py to +# import this file in order to extract the documentation from each +# exported function. # A better approach will involve more extensive code splitting, I think. try: import database except: import logger as database -try: import sliver_vs -except: import logger as sliver_vs import ticket as ticket_module import tools -deliver_ticket = None # set in sm.py:start() +deliver_ticket = None # set in slivermanager.start() api_method_dict = {} nargs_dict = {} @@ -94,27 +91,27 @@ def export_to_docbook(**kwargs): # accepts, # returns -@export_to_docbook(roles=['self'], - accepts=[], +@export_to_docbook(roles=['self'], + accepts=[], returns=Parameter([], 'A list of supported functions')) @export_to_api(0) def Help(): """Get a list of functions currently supported by the Node Manager API""" names=api_method_dict.keys() names.sort() - return ''.join(['**** ' + api_method_dict[name].__name__ + '\n' + api_method_dict[name].__doc__ + '\n' + return ''.join(['**** ' + api_method_dict[name].__name__ + '\n' + api_method_dict[name].__doc__ + '\n' for name in names]) -@export_to_docbook(roles=['self'], - accepts=[Parameter(str, 'A ticket returned from GetSliceTicket()')], +@export_to_docbook(roles=['self'], + accepts=[Parameter(str, 'A ticket returned from GetSliceTicket()')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def Ticket(ticket): """The Node Manager periodically polls the PLC API for a list of all - slices that are allowed to exist on the given node. Before + slices that are allowed to exist on the given node. Before actions are performed on a delegated slice (such as creation), - a controller slice must deliver a valid slice ticket to NM. - + a controller slice must deliver a valid slice ticket to NM. + This ticket is the value retured by PLC's GetSliceTicket() API call.""" try: data = ticket_module.verify(ticket) @@ -126,8 +123,8 @@ def Ticket(ticket): except Exception, err: raise xmlrpclib.Fault(102, 'Ticket error: ' + str(err)) -@export_to_docbook(roles=['self'], - accepts=[Parameter(str, 'A ticket returned from GetSlivers()')], +@export_to_docbook(roles=['self'], + accepts=[Parameter(str, 'A ticket returned from GetSlivers()')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def AdminTicket(ticket): @@ -144,15 +141,15 @@ def AdminTicket(ticket): @export_to_docbook(roles=['self'], - accepts=[], + accepts=[], returns={'sliver_name' : Parameter(int, 'the associated xid')}) @export_to_api(0) def GetXIDs(): """Return an dictionary mapping Slice names to XIDs""" - return dict([(pwent[0], pwent[2]) for pwent in pwd.getpwall() if pwent[6] == sliver_vs.Sliver_VS.SHELL]) + return dict([(pwent[0], pwent[2]) for pwent in pwd.getpwall() if pwent[6] == slivermanager.sliver_password_shell]) @export_to_docbook(roles=['self'], - accepts=[], + accepts=[], returns={ 'sliver_name' : Parameter(str, 'the associated SSHKey')}) @export_to_api(0) def GetSSHKeys(): @@ -164,70 +161,70 @@ def GetSSHKeys(): return keydict -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def Create(sliver_name): """Create a non-PLC-instantiated sliver""" rec = sliver_name - if rec['instantiation'] == 'delegated': - accounts.get(rec['name']).ensure_created(rec) + if rec['instantiation'] == 'delegated': + account.get(rec['name']).ensure_created(rec) logger.log("api_calls: Create %s"%rec['name']) - else: + else: raise Exception, "Only PLC can create non delegated slivers." -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def Destroy(sliver_name): """Destroy a non-PLC-instantiated sliver""" - rec = sliver_name - if rec['instantiation'] == 'delegated': - accounts.get(rec['name']).ensure_destroyed() + rec = sliver_name + if rec['instantiation'] == 'delegated': + account.get(rec['name']).ensure_destroyed() logger.log("api_calls: Destroy %s"%rec['name']) - else: + else: raise Exception, "Only PLC can destroy non delegated slivers." -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def Start(sliver_name): """Configure and start sliver.""" rec = sliver_name - accounts.get(rec['name']).start(rec) + account.get(rec['name']).start(rec) logger.log("api_calls: Start %s"%rec['name']) -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def Stop(sliver_name): """Kill all processes belonging to the specified sliver""" rec = sliver_name - accounts.get(rec['name']).stop() + account.get(rec['name']).stop() logger.log("api_calls: Stop %s"%rec['name']) -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(int, '1 if successful')) @export_to_api(1) def ReCreate(sliver_name): """Stop, Destroy, Create, Start sliver in order to reinstall it.""" rec = sliver_name - accounts.get(rec['name']).stop() - accounts.get(rec['name']).ensure_created(rec) - accounts.get(rec['name']).start(rec) + account.get(rec['name']).stop() + account.get(rec['name']).ensure_created(rec) + account.get(rec['name']).start(rec) logger.log("api_calls: ReCreate %s"%rec['name']) -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=Parameter(dict, "A resource specification")) @export_to_api(1) def GetEffectiveRSpec(sliver_name): @@ -236,8 +233,8 @@ def GetEffectiveRSpec(sliver_name): return rec.get('_rspec', {}).copy() -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns={"resource name" : Parameter(int, "amount")}) @export_to_api(1) def GetRSpec(sliver_name): @@ -246,8 +243,8 @@ def GetRSpec(sliver_name): return rec.get('rspec', {}).copy() -@export_to_docbook(roles=['nm-controller', 'self'], - accepts=[Parameter(str, 'A sliver/slice name.')], +@export_to_docbook(roles=['nm-controller', 'self'], + accepts=[Parameter(str, 'A sliver/slice name.')], returns=[Mixed(Parameter(str, 'recipient slice name'), Parameter(str, 'resource name'), Parameter(int, 'resource amount'))]) @@ -260,13 +257,13 @@ def GetLoans(sliver_name): def validate_loans(loans): """Check that is a list of valid loan specifications.""" - def validate_loan(loan): + def validate_loan(loan): return (type(loan)==list or type(loan)==tuple) and len(loan)==3 \ and type(loan[0])==str and type(loan[1])==str and loan[1] in database.LOANABLE_RESOURCES and type(loan[2])==int and loan[2]>=0 return type(loans)==list and False not in [validate_loan(load) for loan in loans] -@export_to_docbook(roles=['nm-controller', 'self'], +@export_to_docbook(roles=['nm-controller', 'self'], accepts=[ Parameter(str, 'A sliver/slice name.'), [Mixed(Parameter(str, 'recipient slice name'), Parameter(str, 'resource name'), @@ -282,12 +279,12 @@ def SetLoans(sliver_name, loans): in the future. As well, there is currently no asynchronous notification of loss of resources.""" rec = sliver_name - if not validate_loans(loans): + if not validate_loans(loans): raise xmlrpclib.Fault(102, 'Invalid argument: the second argument must be a well-formed loan specification') rec['_loans'] = loans database.db.sync() -@export_to_docbook(roles=['nm-controller', 'self'], +@export_to_docbook(roles=['nm-controller', 'self'], returns=Parameter(dict, 'Record dictionary')) @export_to_api(0) def GetRecord(sliver_name):