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