First draft of the Nitos federation with SFA
[sfa.git] / sfa / nitos / nitosshell.py
1 import sys
2 import xmlrpclib
3 import socket
4 from urlparse import urlparse
5
6 from sfa.util.sfalogging import logger
7
8 class NitosShell:
9     """
10     A simple xmlrpc shell to a myplc instance
11     This class can receive all NITOS API  calls to the underlying testbed
12     For safety this is limited to a set of hard-coded calls
13     """
14     
15     direct_calls = ['getNodes','getChannels','getSlices','getUsers','getReservedNodes',
16                     'getReservedChannels','getTestbedInfo'
17                     ]
18
19
20     # use the 'capability' auth mechanism for higher performance when the PLC db is local    
21     def __init__ ( self, config ) :
22         url = config.SFA_NITOS_URL
23 #        url = "http://195.251.17.239:8080/RPC2"
24         # try to figure if the url is local
25         hostname=urlparse(url).hostname
26         is_local=False
27         if hostname == 'localhost': is_local=True
28         # otherwise compare IP addresses; 
29         # this might fail for any number of reasons, so let's harden that
30         try:
31             # xxx todo this seems to result in a DNS request for each incoming request to the AM
32             # should be cached or improved
33             url_ip=socket.gethostbyname(hostname)
34             local_ip=socket.gethostbyname(socket.gethostname())
35             if url_ip==local_ip: is_local=True
36         except:
37             pass
38
39         if is_local:
40             try:
41                 # too bad this is not installed properly
42                 plcapi_path="/usr/share/plc_api"
43                 if plcapi_path not in sys.path: sys.path.append(plcapi_path)
44                 import PLC.Shell
45                 plc_direct_access=True
46             except:
47                 plc_direct_access=False
48         if is_local and plc_direct_access:
49             logger.debug('plshell access - capability')
50             #self.plauth = { 'AuthMethod': 'capability',
51             #                'Username':   config.SFA_PLC_USER,
52             #                'AuthString': config.SFA_PLC_PASSWORD,
53             #                }
54             self.proxy = PLC.Shell.Shell ()
55
56         else:
57             logger.debug('nitosshell access - xmlrpc')
58             #self.plauth = { 'AuthMethod': 'password',
59             #                'Username':   config.SFA_PLC_USER,
60             #                'AuthString': config.SFA_PLC_PASSWORD,
61             #                }
62             self.proxy = xmlrpclib.Server(url, verbose = False, allow_none = True)
63
64     def __getattr__(self, name):
65         def func(*args, **kwds):
66             actual_name=None
67             if name in NitosShell.direct_calls: actual_name=name
68 #            if name in NitosShell.alias_calls: actual_name=NitosShell.alias_calls[name]
69             if not actual_name:
70                 raise Exception, "Illegal method call %s for NITOS driver"%(name)
71             actual_name = "scheduler.server." + actual_name
72             result=getattr(self.proxy, actual_name)(*args, **kwds)
73             logger.debug('NitosShell %s (%s) returned ... '%(name,actual_name))
74             return result
75         return func
76