import sys import xmlrpclib import socket from urlparse import urlparse from sfa.util.sfalogging import logger class NitosShell: """ A simple xmlrpc shell to a myplc instance This class can receive all NITOS API calls to the underlying testbed For safety this is limited to a set of hard-coded calls """ direct_calls = ['getNodes','getChannels','getSlices','getUsers','getReservedNodes', 'getReservedChannels','getTestbedInfo' ] # use the 'capability' auth mechanism for higher performance when the PLC db is local def __init__ ( self, config ) : url = config.SFA_NITOS_URL # url = "http://195.251.17.239:8080/RPC2" # try to figure if the url is local hostname=urlparse(url).hostname is_local=False if hostname == 'localhost': is_local=True # otherwise compare IP addresses; # this might fail for any number of reasons, so let's harden that try: # xxx todo this seems to result in a DNS request for each incoming request to the AM # should be cached or improved url_ip=socket.gethostbyname(hostname) local_ip=socket.gethostbyname(socket.gethostname()) if url_ip==local_ip: is_local=True except: pass if is_local: try: # too bad this is not installed properly plcapi_path="/usr/share/plc_api" if plcapi_path not in sys.path: sys.path.append(plcapi_path) import PLC.Shell plc_direct_access=True except: plc_direct_access=False if is_local and plc_direct_access: logger.debug('plshell access - capability') #self.plauth = { 'AuthMethod': 'capability', # 'Username': config.SFA_PLC_USER, # 'AuthString': config.SFA_PLC_PASSWORD, # } self.proxy = PLC.Shell.Shell () else: logger.debug('nitosshell access - xmlrpc') #self.plauth = { 'AuthMethod': 'password', # 'Username': config.SFA_PLC_USER, # 'AuthString': config.SFA_PLC_PASSWORD, # } self.proxy = xmlrpclib.Server(url, verbose = False, allow_none = True) def __getattr__(self, name): def func(*args, **kwds): actual_name=None if name in NitosShell.direct_calls: actual_name=name # if name in NitosShell.alias_calls: actual_name=NitosShell.alias_calls[name] if not actual_name: raise Exception, "Illegal method call %s for NITOS driver"%(name) actual_name = "scheduler.server." + actual_name result=getattr(self.proxy, actual_name)(*args, **kwds) logger.debug('NitosShell %s (%s) returned ... '%(name,actual_name)) return result return func