11 except (socket.error, IOError, OSError):
18 _expected_methods = set(
19 ['AddNodeTag', 'AddConfFile', 'DeletePersonTag', 'AddNodeType', 'DeleteBootState', 'SliceListNames', 'DeleteKey',
20 'SliceGetTicket', 'SliceUsersList', 'SliceUpdate', 'GetNodeGroups', 'SliceCreate', 'GetNetworkMethods', 'GetNodeFlavour',
21 'DeleteNode', 'BootNotifyOwners', 'AddPersonKey', 'AddNode', 'UpdateNodeGroup', 'GetAddressTypes', 'AddIlink', 'DeleteNetworkType',
22 'GetInitScripts', 'GenerateNodeConfFile', 'AddSite', 'BindObjectToPeer', 'SliceListUserSlices', 'GetPeers', 'AddPeer', 'DeletePeer',
23 'AddRole', 'DeleteRole', 'SetPersonPrimarySite', 'AddSiteAddress', 'SliceDelete', 'NotifyPersons', 'GetKeyTypes', 'GetConfFiles',
24 'GetIlinks', 'AddTagType', 'GetNodes', 'DeleteNodeTag', 'DeleteSliceFromNodesWhitelist', 'UpdateAddress', 'ResetPassword',
25 'AddSliceToNodesWhitelist', 'AddRoleToTagType', 'AddLeases', 'GetAddresses', 'AddInitScript', 'RebootNode', 'GetPCUTypes',
26 'RefreshPeer', 'GetBootMedium', 'UpdateKey', 'UpdatePCU', 'GetSession', 'AddInterfaceTag', 'UpdatePCUType', 'GetInterfaces',
27 'SliceExtendedInfo', 'SliceNodesList', 'DeleteRoleFromTagType', 'DeleteSlice', 'GetSites', 'DeleteMessage', 'GetSliceFamily',
28 'GetPlcRelease', 'UpdateTagType', 'AddSliceInstantiation', 'ResolveSlices', 'GetSlices', 'DeleteRoleFromPerson', 'GetSessions',
29 'UpdatePeer', 'VerifyPerson', 'GetPersonTags', 'DeleteKeyType', 'AddSlice', 'SliceUserAdd', 'DeleteSession', 'GetMessages',
30 'DeletePCU', 'GetPeerData', 'DeletePersonFromSite', 'DeleteTagType', 'GetPCUs', 'UpdateLeases', 'AddMessage',
31 'DeletePCUProtocolType', 'DeleteInterfaceTag', 'AddPersonToSite', 'GetSlivers', 'SliceNodesDel', 'DeleteAddressTypeFromAddress',
32 'AddNodeGroup', 'GetSliceTags', 'DeleteSite', 'GetSiteTags', 'UpdateMessage', 'DeleteSliceFromNodes', 'SliceRenew',
33 'UpdatePCUProtocolType', 'DeleteSiteTag', 'GetPCUProtocolTypes', 'GetEvents', 'GetSliceTicket', 'AddPersonTag', 'BootGetNodeDetails',
34 'DeleteInterface', 'DeleteNodeGroup', 'AddPCUProtocolType', 'BootCheckAuthentication', 'AddSiteTag', 'AddAddressTypeToAddress',
35 'DeleteConfFile', 'DeleteInitScript', 'DeletePerson', 'DeleteIlink', 'DeleteAddressType', 'AddBootState', 'AuthCheck',
36 'NotifySupport', 'GetSliceInstantiations', 'AddPCUType', 'AddPCU', 'AddSession', 'GetEventObjects', 'UpdateSiteTag',
37 'UpdateNodeTag', 'AddPerson', 'BlacklistKey', 'UpdateInitScript', 'AddSliceToNodes', 'RebootNodeWithPCU', 'GetNodeTags',
38 'GetSliceKeys', 'GetSliceSshKeys', 'AddNetworkMethod', 'SliceNodesAdd', 'DeletePersonFromSlice', 'ReportRunlevel',
39 'GetNetworkTypes', 'UpdateSite', 'DeleteConfFileFromNodeGroup', 'UpdateNode', 'DeleteSliceInstantiation', 'DeleteSliceTag',
40 'BootUpdateNode', 'UpdatePerson', 'UpdateConfFile', 'SliceUserDel', 'DeleteLeases', 'AddConfFileToNodeGroup', 'UpdatePersonTag',
41 'DeleteConfFileFromNode', 'AddPersonToSlice', 'UnBindObjectFromPeer', 'AddNodeToPCU', 'GetLeaseGranularity', 'DeletePCUType',
42 'GetTagTypes', 'GetNodeTypes', 'UpdateInterfaceTag', 'GetRoles', 'UpdateSlice', 'UpdateSliceTag', 'AddSliceTag', 'AddNetworkType',
43 'AddInterface', 'AddAddressType', 'AddRoleToPerson', 'DeleteNodeType', 'GetLeases', 'UpdateInterface', 'SliceInfo', 'DeleteAddress',
44 'SliceTicketGet', 'GetPersons', 'GetWhitelist', 'AddKeyType', 'UpdateAddressType', 'GetPeerName', 'DeleteNetworkMethod',
45 'UpdateIlink', 'AddConfFileToNode', 'GetKeys', 'DeleteNodeFromPCU', 'GetInterfaceTags', 'GetBootStates', 'SetInterfaceSens', 'SetNodeLoadm',
46 'GetInterfaceRate', 'GetNodeLoadw', 'SetInterfaceKey', 'GetNodeSlices', 'GetNodeLoadm', 'SetSliceVref', 'GetInterfaceIwpriv', 'SetNodeLoadw',
47 'SetNodeSerial', 'GetNodePlainBootstrapfs', 'SetNodeMEMw', 'GetNodeResponse', 'SetInterfaceRate', 'SetSliceInitscript',
48 'SetNodeFcdistro', 'GetNodeLoady', 'SetNodeArch', 'SetNodeKargs', 'SetNodeMEMm', 'SetNodeBWy', 'SetNodeBWw',
49 'SetInterfaceSecurityMode', 'SetNodeBWm', 'SetNodeASType', 'GetNodeKargs', 'GetPersonColumnconf', 'GetNodeResponsem',
50 'GetNodeCPUy', 'GetNodeCramfs', 'SetNodeSlicesw', 'SetPersonColumnconf', 'SetNodeSlicesy', 'GetNodeCPUw', 'GetNodeBWy',
51 'GetNodeCPUm', 'GetInterfaceDriver', 'GetNodeLoad', 'GetInterfaceMode', 'GetNodeSerial', 'SetNodeSlicesm', 'SetNodeLoady',
52 'GetNodeReliabilityw', 'SetSliceFcdistro', 'GetNodeReliabilityy', 'SetInterfaceEssid', 'SetSliceInitscriptCode',
53 'GetNodeExtensions', 'GetSliceOmfControl', 'SetNodeCity', 'SetInterfaceIfname', 'SetNodeHrn', 'SetNodeNoHangcheck',
54 'GetNodeNoHangcheck', 'GetSliceFcdistro', 'SetNodeCountry', 'SetNodeKvariant', 'GetNodeKvariant', 'GetNodeMEMy',
55 'SetInterfaceIwpriv', 'GetNodeMEMw', 'SetInterfaceBackdoor', 'GetInterfaceFreq', 'SetInterfaceChannel', 'SetInterfaceNw',
56 'GetPersonShowconf', 'GetSliceInitscriptCode', 'SetNodeMEM', 'GetInterfaceEssid', 'GetNodeMEMm', 'SetInterfaceMode',
57 'SetInterfaceIwconfig', 'GetNodeSlicesm', 'GetNodeBWm', 'SetNodePlainBootstrapfs', 'SetNodeRegion', 'SetNodeCPU',
58 'GetNodeSlicesw', 'SetNodeBW', 'SetNodeSlices', 'SetNodeCramfs', 'GetNodeSlicesy', 'GetInterfaceKey', 'GetSliceInitscript',
59 'SetNodeCPUm', 'SetSliceArch', 'SetNodeLoad', 'SetNodeResponse', 'GetSliceSliverHMAC', 'GetNodeBWw', 'GetNodeRegion',
60 'SetNodeMEMy', 'GetNodeASType', 'SetNodePldistro', 'GetSliceArch', 'GetNodeCountry', 'SetSliceOmfControl', 'GetNodeHrn',
61 'GetNodeCity', 'SetInterfaceAlias', 'GetNodeBW', 'GetNodePldistro', 'GetSlicePldistro', 'SetNodeASNumber', 'GetSliceHmac',
62 'SetSliceHmac', 'GetNodeMEM', 'GetNodeASNumber', 'GetInterfaceAlias', 'GetSliceVref', 'GetNodeArch', 'GetSliceSshKey',
63 'GetInterfaceKey4', 'GetInterfaceKey2', 'GetInterfaceKey3', 'GetInterfaceKey1', 'GetInterfaceBackdoor', 'GetInterfaceIfname',
64 'SetSliceSliverHMAC', 'SetNodeReliability', 'GetNodeCPU', 'SetPersonShowconf', 'SetNodeExtensions', 'SetNodeCPUy',
65 'SetNodeCPUw', 'GetNodeResponsew', 'SetNodeResponsey', 'GetInterfaceSens', 'SetNodeResponsew', 'GetNodeResponsey',
66 'GetNodeReliability', 'GetNodeReliabilitym', 'SetNodeResponsem', 'SetInterfaceDriver', 'GetInterfaceSecurityMode',
67 'SetNodeDeployment', 'SetNodeReliabilitym', 'GetNodeFcdistro', 'SetInterfaceFreq', 'GetInterfaceNw', 'SetNodeReliabilityy',
68 'SetNodeReliabilityw', 'GetInterfaceIwconfig', 'SetSlicePldistro', 'SetSliceSshKey', 'GetNodeDeployment', 'GetInterfaceChannel',
69 'SetInterfaceKey2', 'SetInterfaceKey3', 'SetInterfaceKey1', 'SetInterfaceKey4'])
71 _required_methods = set()
73 def __init__(self, username=None, password=None, sessionkey=None,
74 hostname = "www.planet-lab.eu",
75 urlpattern = "https://%(hostname)s:443/PLCAPI/",
76 localPeerName = "PLE"):
77 if sessionkey is not None:
78 self.auth = dict(AuthMethod='session', session=sessionkey)
79 elif username is not None and password is not None:
80 self.auth = dict(AuthMethod='password', Username=username, AuthString=password)
82 self.auth = dict(AuthMethod='anonymous')
84 self._localPeerName = localPeerName
86 self.api = xmlrpclib.ServerProxy(
87 urlpattern % {'hostname':hostname},
95 # validate XMLRPC server checking supported API calls
96 methods = set(_retry(self.api.system.listMethods)())
97 if self._required_methods - methods:
98 warnings.warn("Unsupported REQUIRED methods: %s" % ( ", ".join(sorted(self._required_methods - methods)), ) )
100 if self._expected_methods - methods:
101 warnings.warn("Unsupported EXPECTED methods: %s" % ( ", ".join(sorted(self._expected_methods - methods)), ) )
105 network_types = _retry(self.api.GetNetworkTypes)(self.auth)
106 except (xmlrpclib.ProtocolError, xmlrpclib.Fault),e:
107 warnings.warn(str(e))
113 def network_types(self):
115 return self._network_types
116 except AttributeError:
117 self._network_types = _retry(self.api.GetNetworkTypes)(self.auth)
118 return self._network_types
123 return self._peer_map
124 except AttributeError:
125 peers = _retry(self.api.GetPeers)(self.auth, {}, ['shortname','peername','peer_id'])
126 self._peer_map = dict(
127 (peer['shortname'], peer['peer_id'])
130 self._peer_map.update(
131 (peer['peername'], peer['peer_id'])
134 self._peer_map.update(
135 (peer['peer_id'], peer['shortname'])
138 self._peer_map[None] = self._localPeerName
139 return self._peer_map
142 def GetNodeFlavour(self, node):
144 Returns detailed information on a given node's flavour, i.e. its base installation.
146 This depends on the global PLC settings in the PLC_FLAVOUR area, optionnally overridden by any of the following tags if set on that node:
147 'arch', 'pldistro', 'fcdistro', 'deployment', 'extensions'
151 * node : int or string
152 - int, Node identifier
153 - string, Fully qualified hostname
158 * extensions : array of string, extensions to add to the base install
159 * fcdistro : string, the fcdistro this node should be based upon
160 * nodefamily : string, the nodefamily this node should be based upon
161 * plain : boolean, use plain bootstrapfs image if set (for tests)
163 if not isinstance(node, (str, int, long)):
164 raise ValueError, "Node must be either a non-unicode string or an int"
165 return _retry(self.api.GetNodeFlavour)(self.auth, node)
167 def GetNodes(self, nodeIdOrName=None, fields=None, **kw):
169 Returns an array of structs containing details about nodes.
170 If nodeIdOrName is specified and is an array of node identifiers or hostnames,
171 or the filters keyword argument with struct of node attributes,
172 or node attributes by keyword argument,
173 only nodes matching the filter will be returned.
175 If fields is specified, only the specified details will be returned.
176 NOTE that if fields is unspecified, the complete set of native fields are returned,
177 which DOES NOT include tags at this time.
179 Some fields may only be viewed by admins.
183 fields: an optional list of fields to retrieve. The default is all.
185 filters: an optional mapping with custom filters, which is the only
186 way to support complex filters like negation and numeric comparisons.
188 peer: a string (or sequence of strings) with the name(s) of peers
189 to filter - or None for local nodes.
191 if fields is not None:
192 fieldstuple = (fields,)
195 if nodeIdOrName is not None:
196 return _retry(self.api.GetNodes)(self.auth, nodeIdOrName, *fieldstuple)
198 filters = kw.pop('filters',{})
201 peer = kw.pop('peer')
203 nameToId = self.peer_map.get
205 if hasattr(peer, '__iter__'):
206 # we can't mix local and external nodes, so
207 # split and re-issue recursively in that case
208 if None in peer or self._localPeerName in peer:
211 if self._localPeerName in peer:
212 peer.remove(self._localPeerName)
214 self.GetNodes(nodeIdOrName, fields, filters=filters, peer=peer, **kw)
215 + self.GetNodes(nodeIdOrName, fields, filters=filters, peer=None, **kw)
218 peer_filter = map(nameToId, peer)
219 elif peer is None or peer == self._localPeerName:
222 peer_filter = nameToId(peer)
224 filters['peer_id'] = peer_filter
227 return _retry(self.api.GetNodes)(self.auth, filters, *fieldstuple)
229 def GetNodeTags(self, nodeTagId=None, fields=None, **kw):
230 if fields is not None:
231 fieldstuple = (fields,)
234 if nodeTagId is not None:
235 return _retry(self.api.GetNodeTags)(self.auth, nodeTagId, *fieldstuple)
237 filters = kw.pop('filters',{})
239 return _retry(self.api.GetNodeTags)(self.auth, filters, *fieldstuple)
241 def GetSliceTags(self, sliceTagId=None, fields=None, **kw):
242 if fields is not None:
243 fieldstuple = (fields,)
246 if sliceTagId is not None:
247 return _retry(self.api.GetSliceTags)(self.auth, sliceTagId, *fieldstuple)
249 filters = kw.pop('filters',{})
251 return _retry(self.api.GetSliceTags)(self.auth, filters, *fieldstuple)
254 def GetInterfaces(self, interfaceIdOrIp=None, fields=None, **kw):
255 if fields is not None:
256 fieldstuple = (fields,)
259 if interfaceIdOrIp is not None:
260 return _retry(self.api.GetInterfaces)(self.auth, interfaceIdOrIp, *fieldstuple)
262 filters = kw.pop('filters',{})
264 return _retry(self.api.GetInterfaces)(self.auth, filters, *fieldstuple)
266 def GetSlices(self, sliceIdOrName=None, fields=None, **kw):
267 if fields is not None:
268 fieldstuple = (fields,)
271 if sliceIdOrName is not None:
272 return _retry(self.api.GetSlices)(self.auth, sliceIdOrName, *fieldstuple)
274 filters = kw.pop('filters',{})
276 return _retry(self.api.GetSlices)(self.auth, filters, *fieldstuple)
278 def UpdateSlice(self, sliceIdOrName, **kw):
279 return _retry(self.api.UpdateSlice)(self.auth, sliceIdOrName, kw)
282 def StartMulticall(self):
285 self.api = xmlrpclib.MultiCall(self._api)
288 def FinishMulticall(self):