4 from urlparse import urlparse
6 from sfa.util.sfalogging import logger
10 A simple xmlrpc shell to a myplc instance
11 This class can receive all PLCAPI calls to the underlying testbed
12 For safety this is limited to a set of hard-coded calls
15 direct_calls = ['AddNode', 'AddPerson', 'AddPersonKey', 'AddPersonToSite',
16 'AddPersonToSlice', 'AddRoleToPerson', 'AddSite', 'AddSiteTag', 'AddSlice',
17 'AddSliceTag', 'AddSliceToNodes', 'BindObjectToPeer', 'DeleteKey',
18 'DeleteNode', 'DeletePerson', 'DeletePersonFromSlice', 'DeleteSite',
19 'DeleteSlice', 'DeleteSliceFromNodes', 'DeleteSliceTag', 'GetInitScripts',
20 'GetInterfaces', 'GetKeys', 'GetNodeTags', 'GetPeers',
21 'GetPersons', 'GetSlices', 'GetSliceTags', 'GetTagTypes',
22 'UnBindObjectFromPeer', 'UpdateNode', 'UpdatePerson', 'UpdateSite',
23 'UpdateSlice', 'UpdateSliceTag',
24 # also used as-is in importer
25 'GetSites','GetNodes',
26 # Lease management methods
27 'GetLeases', 'GetLeaseGranularity', 'DeleteLeases','UpdateLeases',
29 # HRN management methods
30 'SetPersonHrn', 'GetPersonHrn', 'SetSliceHrn', 'GetSliceHrn',
31 'SetNodeHrn', 'GetNodeHrn', 'GetSiteHrn', 'SetSiteHrn',
32 # Tag slice/person/site created by SFA
33 'SetPersonSfaCreated', 'GetPersonSfaCreated', 'SetSliceSfaCreated',
34 'GetSliceSfaCreated', 'SetNodeSfaCreated', 'GetNodeSfaCreated',
35 'GetSiteSfaCreated', 'SetSiteSfaCreated',
37 # support for other names - this is experimental
38 alias_calls = { 'get_authorities':'GetSites',
39 'get_nodes':'GetNodes',
43 # use the 'capability' auth mechanism for higher performance when the PLC db is local
44 def __init__ ( self, config ) :
45 url = config.SFA_PLC_URL
46 # try to figure if the url is local
47 hostname=urlparse(url).hostname
49 if hostname == 'localhost': is_local=True
50 # otherwise compare IP addresses;
51 # this might fail for any number of reasons, so let's harden that
53 # xxx todo this seems to result in a DNS request for each incoming request to the AM
54 # should be cached or improved
55 url_ip=socket.gethostbyname(hostname)
56 local_ip=socket.gethostbyname(socket.gethostname())
57 if url_ip==local_ip: is_local=True
63 # too bad this is not installed properly
64 plcapi_path="/usr/share/plc_api"
65 if plcapi_path not in sys.path: sys.path.append(plcapi_path)
67 plc_direct_access=True
69 plc_direct_access=False
70 if is_local and plc_direct_access:
71 logger.info('plshell access - capability')
72 self.plauth = { 'AuthMethod': 'capability',
73 'Username': str(config.SFA_PLC_USER),
74 'AuthString': str(config.SFA_PLC_PASSWORD),
76 self.proxy = PLC.Shell.Shell ()
79 logger.info('plshell access - xmlrpc')
80 self.plauth = { 'AuthMethod': 'password',
81 'Username': str(config.SFA_PLC_USER),
82 'AuthString': str(config.SFA_PLC_PASSWORD),
84 self.proxy = xmlrpclib.Server(url, verbose = False, allow_none = True)
86 def __getattr__(self, name):
87 def func(*args, **kwds):
89 if name in PlShell.direct_calls: actual_name=name
90 if name in PlShell.alias_calls: actual_name=PlShell.alias_calls[name]
92 raise Exception, "Illegal method call %s for PL driver"%(name)
93 result=getattr(self.proxy, actual_name)(self.plauth, *args, **kwds)
94 logger.debug('PlShell %s (%s) returned ... '%(name,actual_name))