4 from urllib.parse 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
17 'AddNode', 'AddPerson', 'AddPersonKey', 'AddPersonToSite',
18 'AddPersonToSlice', 'AddRoleToPerson', 'AddSite', 'AddSiteTag', 'AddSlice',
19 'AddSliceTag', 'AddSliceToNodes', 'BindObjectToPeer', 'DeleteKey',
20 'DeleteNode', 'DeletePerson', 'DeletePersonFromSlice', 'DeleteSite',
21 'DeleteSlice', 'DeleteSliceFromNodes', 'DeleteSliceTag', 'GetInitScripts',
22 'GetInterfaces', 'GetKeys', 'GetNodeTags', 'GetPeers',
23 'GetPersons', 'GetSlices', 'GetSliceTags', 'GetTagTypes',
24 'UnBindObjectFromPeer', 'UpdateNode', 'UpdatePerson', 'UpdateSite',
25 'UpdateSlice', 'UpdateSliceTag',
26 # also used as-is in importer
27 'GetSites', 'GetNodes', 'GetSiteTags',
28 # Lease management methods
29 'GetLeases', 'GetLeaseGranularity', 'DeleteLeases', 'UpdateLeases',
31 # HRN management methods
32 'SetPersonHrn', 'GetPersonHrn', 'SetSliceHrn', 'GetSliceHrn',
33 'SetNodeHrn', 'GetNodeHrn', 'GetSiteHrn', 'SetSiteHrn',
34 # Tag slice/person/site created by SFA
35 'SetPersonSfaCreated', 'GetPersonSfaCreated', 'SetSliceSfaCreated',
36 'GetSliceSfaCreated', 'SetNodeSfaCreated', 'GetNodeSfaCreated',
37 'GetSiteSfaCreated', 'SetSiteSfaCreated',
39 # support for other names - this is experimental
41 'get_authorities': 'GetSites',
42 'get_nodes': 'GetNodes',
45 # use the 'capability' auth mechanism for higher performance when the PLC
47 def __init__(self, config):
48 url = config.SFA_PLC_URL
49 # try to figure if the url is local
50 hostname = urlparse(url).hostname
52 if hostname == 'localhost':
54 # otherwise compare IP addresses;
55 # this might fail for any number of reasons, so let's harden that
57 # xxx todo this seems to result in a DNS request for each incoming request to the AM
58 # should be cached or improved
59 url_ip = socket.gethostbyname(hostname)
60 local_ip = socket.gethostbyname(socket.gethostname())
61 if url_ip == local_ip:
68 # too bad this is not installed properly
69 plcapi_path = "/usr/share/plc_api"
70 if plcapi_path not in sys.path:
71 sys.path.append(plcapi_path)
73 plc_direct_access = True
75 plc_direct_access = False
76 if is_local and plc_direct_access:
77 logger.debug('plshell access - capability')
79 'AuthMethod': 'capability',
80 'Username': str(config.SFA_PLC_USER),
81 'AuthString': str(config.SFA_PLC_PASSWORD),
83 self.proxy = PLC.Shell.Shell()
86 logger.debug('plshell access - xmlrpc')
88 'AuthMethod': 'password',
89 'Username': str(config.SFA_PLC_USER),
90 'AuthString': str(config.SFA_PLC_PASSWORD),
92 # minimal verification for backwards compat
94 ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
95 ssl_context.verify_mode = ssl.CERT_NONE
96 self.proxy = xmlrpc.client.ServerProxy(
97 url, verbose=False, allow_none=True, context=ssl_context)
99 def __getattr__(self, name):
100 def func(*args, **kwds):
102 if name in PlShell.direct_calls:
104 if name in PlShell.alias_calls:
105 actual_name = PlShell.alias_calls[name]
108 "Illegal method call %s for PL driver" % (name))
109 result = getattr(self.proxy, actual_name)(
110 self.plauth, *args, **kwds)
111 logger.debug('PlShell %s (%s) returned ... ' % (name, actual_name))