##
-# Implements support for geni records
+# Implements support for SFA records
#
# TODO: Use existing PLC database methods? or keep this separate?
##
-### $Id$
-### $URL$
-
from types import StringTypes
-from sfa.trust.gid import *
+from sfa.trust.gid import GID
-import sfa.util.report
-from sfa.util.rspec import *
-from sfa.util.parameter import *
+from sfa.util.parameter import Parameter
+from sfa.util.xrn import get_authority
+from sfa.util.row import Row
+from sfa.util.xml import XML
-class GeniRecord(dict):
+class SfaRecord(Row):
"""
- The GeniRecord class implements a Geni Record. A GeniRecord is a tuple
+ The SfaRecord class implements an SFA Record. A SfaRecord is a tuple
(Hrn, GID, Type, Info).
Hrn specifies the Human Readable Name of the object
of different types.
"""
+ table_name = 'sfa'
+
+ primary_key = 'record_id'
+
### the wsdl generator assumes this is named 'fields'
+ internal_fields = {
+ 'record_id': Parameter(int, 'An id that uniquely identifies this record', ro=True),
+ 'pointer': Parameter(int, 'An id that uniquely identifies this record in an external database ')
+ }
+
fields = {
+ 'authority': Parameter(str, "The authority for this record"),
+ 'peer_authority': Parameter(str, "The peer authority for this record"),
'hrn': Parameter(str, "Human readable name of object"),
'gid': Parameter(str, "GID of the object"),
'type': Parameter(str, "Record type"),
- 'last_updated': Parameter(int, 'Date and time of last update'),
- 'date_created': Parameter(int, 'Date and time this record was created'),
+ 'last_updated': Parameter(int, 'Date and time of last update', ro=True),
+ 'date_created': Parameter(int, 'Date and time this record was created', ro=True),
}
-
+ all_fields = dict(fields.items() + internal_fields.items())
##
- # Create a Geni Record
+ # Create an SFA Record
#
# @param name if !=None, assign the name of the record
# @param gid if !=None, assign the gid of the record
# @param pointer is a pointer to a PLC record
# @param dict if !=None, then fill in this record from the dictionary
- def __init__(self, hrn=None, gid=None, type=None, pointer=None, dict=None, string=None):
+ def __init__(self, hrn=None, gid=None, type=None, pointer=None, peer_authority=None, dict=None, string=None):
self.dirty = True
self.hrn = None
self.gid = None
self.type = None
self.pointer = None
+ self.set_peer_auth(peer_authority)
if hrn:
self.set_name(hrn)
if gid:
if string:
self.load_from_string(string)
-
+
+ def validate_last_updated(self, last_updated):
+ return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
+
def update(self, new_dict):
if isinstance(new_dict, list):
new_dict = new_dict[0]
Set the name of the record
"""
self.hrn = hrn
+ self['hrn'] = hrn
self.dirty = True
##
if isinstance(gid, StringTypes):
self.gid = gid
+ self['gid'] = gid
else:
self.gid = gid.save_to_string(save_parents=True)
+ self['gid'] = gid.save_to_string(save_parents=True)
self.dirty = True
##
Set the type of the record
"""
self.type = type
+ self['type'] = type
self.dirty = True
##
Set the pointer of the record
"""
self.pointer = pointer
+ self['pointer'] = pointer
+ self.dirty = True
+
+
+ def set_peer_auth(self, peer_authority):
+ self.peer_authority = peer_authority
+ self['peer_authority'] = peer_authority
self.dirty = True
##
return GID(string=self.gid)
##
- # Return a key that uniquely identifies this record among all records in
- # Geni. This key is used to uniquely identify the record in the Geni
- # database.
-
- def get_key(self):
- """
- Return a key that uniquely identifies this record among all records in
- Geni. This key is used to uniquely identify the record in the Geni
- database.
- """
- return self.hrn + "#" + self.type
+ # Returns the value of a field
+
+ def get_field(self, fieldname, default=None):
+ # sometimes records act like classes, and sometimes they act like dicts
+ try:
+ return getattr(self, fieldname)
+ except AttributeError:
+ try:
+ return self[fieldname]
+ except KeyError:
+ if default != None:
+ return default
+ else:
+ raise
##
# Returns a list of field names in this record.
"""
Given a field name ("hrn", "gid", ...) return the value of that field.
"""
- if fieldname == "key":
- val = self.get_key()
+ if fieldname == "authority":
+ val = get_authority(self['hrn'])
else:
- val = getattr(self, fieldname)
+ try:
+ val = getattr(self, fieldname)
+ except:
+ val = self[fieldname]
if isinstance(val, str):
return "'" + str(val) + "'"
else:
"""
Given a list of field names, return a list of values for those public.
"""
- strs = []
- for fieldname in fieldnames:
- strs.append(self.get_field_value_string(fieldname))
- return strs
+ return [ self.get_field_value_string (fieldname) for fieldname in fieldnames ]
##
# Return the record in the form of a dictionary
"""
recorddict = self.as_dict()
filteredDict = dict([(key, val) for (key, val) in recorddict.iteritems() if key in self.fields.keys()])
- record = RecordSpec()
- record.parseDict(filteredDict)
+ record = XML('<record/>')
+ record.parse_dict(filteredDict)
str = record.toxml()
- #str = xmlrpclib.dumps((dict,), allow_none=True)
return str
##
"""
#dict = xmlrpclib.loads(str)[0][0]
- record = RecordSpec()
- record.parseString(str)
- record_dict = record.toDict()
- geni_dict = record_dict['record']
- self.load_from_dict(geni_dict)
+ record = XML(str)
+ self.load_from_dict(record.todict())
##
# Dump the record to stdout
# self.get_gid_object().dump(8, dump_parents)
#print " pointer:", self.pointer
- order = GeniRecord.fields.keys()
+ order = SfaRecord.fields.keys()
for key in self.keys():
if key not in order:
order.append(key)
for key in order:
- if key in (self and self.fields):
+ if key in self and key in self.fields:
if key in 'gid' and self[key]:
gid = GID(string=self[key])
print " %s:" % key
return dict(self)
-class UserRecord(GeniRecord):
+class UserRecord(SfaRecord):
fields = {
'email': Parameter(str, 'email'),
'first_name': Parameter(str, 'First name'),
'last_name': Parameter(str, 'Last name'),
'phone': Parameter(str, 'Phone Number'),
- 'key': Parameter(str, 'Public key'),
+ 'keys': Parameter(str, 'Public key'),
'slices': Parameter([str], 'List of slices this user belongs to'),
}
- fields.update(GeniRecord.fields)
+ fields.update(SfaRecord.fields)
-class SliceRecord(GeniRecord):
+class SliceRecord(SfaRecord):
fields = {
'name': Parameter(str, 'Slice name'),
'url': Parameter(str, 'Slice url'),
'expires': Parameter(int, 'Date and time this slice exipres'),
'researcher': Parameter([str], 'List of users for this slice'),
+ 'PI': Parameter([str], 'List of PIs responsible for this slice'),
'description': Parameter([str], 'Description of this slice'),
}
- fields.update(GeniRecord.fields)
+ fields.update(SfaRecord.fields)
-class NodeRecord(GeniRecord):
+class NodeRecord(SfaRecord):
fields = {
'hostname': Parameter(str, 'This nodes dns name'),
'node_type': Parameter(str, 'Type of node this is'),
'latitude': Parameter(str, 'latitude'),
'longitude': Parameter(str, 'longitude'),
}
- fields.update(GeniRecord.fields)
+ fields.update(SfaRecord.fields)
-class AuthorityRecord(GeniRecord):
+class AuthorityRecord(SfaRecord):
fields = {
'name': Parameter(str, 'Name'),
'login_base': Parameter(str, 'login base'),
'researcher': Parameter([str], 'List of researchers'),
'PI': Parameter([str], 'List of Principal Investigators'),
}
- fields.update(GeniRecord.fields)
+ fields.update(SfaRecord.fields)