2 # Implements support for geni records
4 # TODO: Use existing PLC database methods? or keep this separate?
8 from types import StringTypes
10 from geni.util.rspec import *
15 The GeniRecord class implements a Geni Record. A GeniRecord is a tuple
16 (Name, GID, Type, Info).
18 Name specifies the HRN of the object
19 GID is the GID of the object
20 Type is user | authority | slice | component
22 Info is comprised of the following sub-fields
23 pointer = a pointer to the record in the PL database
24 pl_info = planetlab-specific info (when talking to client)
25 geni_info = geni-specific info (when talking to client)
27 The pointer is interpreted depending on the type of the record. For example,
28 if the type=="user", then pointer is assumed to be a person_id that indexes
29 into the persons table.
31 A given HRN may have more than one record, provided that the records are
36 # Create a Geni Record
38 # @param name if !=None, assign the name of the record
39 # @param gid if !=None, assign the gid of the record
40 # @param type one of user | authority | slice | component
41 # @param pointer is a pointer to a PLC record
42 # @param dict if !=None, then fill in this record from the dictionary
44 def __init__(self, name=None, gid=None, type=None, pointer=None, dict=None, string=None):
59 self.set_pointer(pointer)
61 self.load_from_dict(dict)
63 self.load_from_string(string)
66 # Set the name of the record
68 # @param name is a string containing the HRN
70 def set_name(self, name):
72 Set the name of the record
78 # Set the GID of the record
80 # @param gid is a GID object or the string representation of a GID object
82 def set_gid(self, gid):
84 Set the GID of the record
87 if isinstance(gid, StringTypes):
90 self.gid = gid.save_to_string(save_parents=True)
94 # Set the type of the record
96 # @param type is a string: user | authority | slice | component
98 def set_type(self, type):
100 Set the type of the record
106 # Set the pointer of the record
108 # @param pointer is an integer containing the ID of a PLC record
110 def set_pointer(self, pointer):
112 Set the pointer of the record
114 self.pointer = pointer
118 # Set the PLC info of the record
120 # @param pl_info is a dictionary containing planetlab info
122 def set_pl_info(self, pl_info):
124 Set the PLC info of the record
126 if isinstance(pl_info, list):
129 # Convert any boolean strings to real bools
131 if isinstance(pl_info[key], StringTypes):
132 if pl_info[key].lower() in ["true"]:
134 elif pl_info[key].lower() in ["false"]:
136 self.pl_info = pl_info
140 # Set the geni info the record
142 # @param geni_info is a dictionary containing geni info
144 def set_geni_info(self, geni_info):
146 Set the geni info the record
148 if isinstance(geni_info, list):
149 geni_info = geni_info[0]
150 self.geni_info = geni_info
154 # Return the pl_info of the record, or an empty dictionary if none exists
156 def get_pl_info(self):
158 Return the pl_info of the record, or an empty dictionary if none exists
166 # Return the geni_info of the record, or an empty dictionary if none exists
168 def get_geni_info(self):
170 Return the geni_info of the record, or an empty dictionary if none exists
173 return self.geni_info
178 # Return the name (HRN) of the record
182 Return the name (HRN) of the record
187 # Return the type of the record
191 Return the type of the record
196 # Return the pointer of the record. The pointer is an integer that may be
197 # used to look up the record in the PLC database. The evaluation of pointer
198 # depends on the type of the record
200 def get_pointer(self):
202 Return the pointer of the record. The pointer is an integer that may be
203 used to look up the record in the PLC database. The evaluation of pointer
204 depends on the type of the record
209 # Return the GID of the record, in the form of a GID object
210 # TODO: not the best name for the function, because we have things called
211 # gidObjects in the Cred
213 def get_gid_object(self):
215 Return the GID of the record, in the form of a GID object
217 return GID(string=self.gid)
220 # Return a key that uniquely identifies this record among all records in
221 # Geni. This key is used to uniquely identify the record in the Geni
226 Return a key that uniquely identifies this record among all records in
227 Geni. This key is used to uniquely identify the record in the Geni
230 return self.name + "#" + self.type
233 # Returns a list of field names in this record. pl_info, geni_info are not
234 # included because they are not part of the record that is stored in the
235 # database, but are rather computed values from other entities
237 def get_field_names(self):
239 Returns a list of field names in this record. pl_info, geni_info are not
240 included because they are not part of the record that is stored in the
241 database, but are rather computed values from other entities
243 return ["name", "gid", "type", "pointer"]
246 # Given a field name ("name", "gid", ...) return the value of that field.
248 # @param name is the name of field to be returned
250 def get_field_value_string(self, fieldname):
252 Given a field name ("name", "gid", ...) return the value of that field.
254 if fieldname == "key":
257 val = getattr(self, fieldname)
258 if isinstance(val, str):
259 return "'" + str(val) + "'"
264 # Given a list of field names, return a list of values for those fields.
266 # @param fieldnames is a list of field names
268 def get_field_value_strings(self, fieldnames):
270 Given a list of field names, return a list of values for those fields.
273 for fieldname in fieldnames:
274 strs.append(self.get_field_value_string(fieldname))
278 # Return the record in the form of a dictionary
282 Return the record in the form of a dictionary
285 names = self.get_field_names()
287 dict[name] = getattr(self, name)
290 dict['pl_info'] = self.pl_info
293 dict['geni_info'] = self.geni_info
298 # Load the record from a dictionary
300 # @param dict dictionary to load record fields from
302 def load_from_dict(self, dict):
304 Load the record from a dictionary
306 self.set_name(dict['name'])
307 gidstr = dict.get("gid", None)
309 self.set_gid(dict['gid'])
311 self.set_type(dict['type'])
312 if "pointer" in dict:
313 self.set_pointer(dict['pointer'])
314 if "pl_info" in dict and dict['pl_info']:
315 self.set_pl_info(dict["pl_info"])
316 if "geni_info" in dict and dict['geni_info']:
317 self.set_geni_info(dict["geni_info"])
320 # Save the record to a string. The string contains an XML representation of
323 def save_to_string(self):
325 Save the record to a string. The string contains an XML representation of
328 dict = self.as_dict()
329 record = RecordSpec()
330 record.parseDict(dict)
332 #str = xmlrpclib.dumps((dict,), allow_none=True)
336 # Load the record from a string. The string is assumed to contain an XML
337 # representation of the record.
339 def load_from_string(self, str):
341 Load the record from a string. The string is assumed to contain an XML
342 representation of the record.
344 #dict = xmlrpclib.loads(str)[0][0]
346 record = RecordSpec()
347 record.parseString(str)
348 record_dict = record.toDict()
349 geni_dict = record_dict['record']
350 self.load_from_dict(geni_dict)
353 # Dump the record to stdout
355 # @param dump_parents if true, then the parents of the GID will be dumped
357 def dump(self, dump_parents=False):
359 Walk tree and dump records.
361 print "RECORD", self.name
362 print " hrn:", self.name
363 print " type:", self.type
368 self.get_gid_object().dump(8, dump_parents)
369 print " pointer:", self.pointer
372 geni_info = getattr(self, "geni_info", {})
374 for key in geni_info.keys():
375 print " ", key, ":", geni_info[key]
378 pl_info = getattr(self, "pl_info", {})
381 for key in (s for s in pl_info.keys()\
382 if (s.endswith("_ids") or s.endswith("_id")) == False):
383 print " ", key, ":", pl_info[key]
387 info = {'hrn': self.name, 'type': self.type, 'gid': self.gid}
388 geni_info = getattr(self, "geni_info", {})
389 pl_info = getattr(self, "pl_info", {})
391 info.update(geni_info)