save_records_to_file(outfile, records)
- def _record_dict(self, xrn=None, type=None, url=None, key=None, \
- description=None, slices='', researchers=''):
+ def _record_dict(self, xrn=None, type=None,
+ url=None, description=None, email='',
+ key=None,
+ slices=[], researchers=[], pis=[]):
record_dict = {}
if xrn:
if type:
record_dict['type'] = xrn.get_type()
if url:
record_dict['url'] = url
+ if description:
+ record_dict['description'] = description
if key:
try:
pubkey = open(key, 'r').read()
if slices:
record_dict['slices'] = slices
if researchers:
- record_dict['researchers'] = researchers
- if description:
- record_dict['description'] = description
+ record_dict['researcher'] = researchers
+ if email:
+ record_dict['email'] = email
+ if pis:
+ record_dict['pi'] = pis
return record_dict
@args('-x', '--xrn', dest='xrn', metavar='<xrn>', help='object hrn/urn (mandatory)')
@args('-t', '--type', dest='type', metavar='<type>', help='object type', default=None)
- @args('-u', '--url', dest='url', metavar='<url>', help='URL', default=None)
+ @args('-e', '--email', dest='email', default="",
+ help="email (mandatory for users)")
+ @args('-u', '--url', dest='url', metavar='<url>', default=None,
+ help="URL, useful for slices")
@args('-d', '--description', dest='description', metavar='<description>',
- help='Description', default=None)
+ help='Description, useful for slices', default=None)
@args('-k', '--key', dest='key', metavar='<key>', help='public key string or file',
default=None)
@args('-s', '--slices', dest='slices', metavar='<slices>', help='slice xrns',
help='Principal Investigators/Project Managers ',
default='', type="str", action='callback', callback=optparse_listvalue_callback)
def register(self, xrn, type=None, url=None, description=None, key=None, slices='',
- pis='', researchers=''):
- """Create a new Registry recory"""
+ pis='', researchers='',email=''):
+ """Create a new Registry record"""
record_dict = self._record_dict(xrn=xrn, type=type, url=url, key=key,
- slices=slices, researchers=researchers)
+ slices=slices, researchers=researchers, email=email, pis=pis)
self.api.manager.Register(self.api, record_dict)
pis='', researchers=''):
"""Update an existing Registry record"""
record_dict = self._record_dict(xrn=xrn, type=type, url=url, description=description,
- key=key, slices=slices, researchers=researchers)
+ key=key, slices=slices, researchers=researchers, pis=pis)
+ for (k,v) in record_dict.items(): print k,'=',v
self.api.manager.Update(self.api, record_dict)
@args('-x', '--xrn', dest='xrn', metavar='<xrn>', help='object hrn/urn (mandatory)')
# execute command
try:
- # print "invoking %s *=%s **=%s"%(command.__name__,cmd_args, cmd_kwds)
+ #print "invoking %s *=%s **=%s"%(command.__name__,cmd_args, cmd_kwds)
command(*cmd_args, **cmd_kwds)
sys.exit(0)
except TypeError:
print "Possible wrong number of arguments supplied"
+ #import traceback
+ #traceback.print_exc()
print command.__doc__
parser.print_help()
#raise
gid = auth_info.get_gid_object()
record.gid=gid.save_to_string(save_parents=True)
- elif isinstance (record, RegSlice):
# locate objects for relationships
- if hasattr (record, 'researcher'):
- # we get the list of researcher hrns as
- researcher_hrns = record.researcher
- # strip that in case we have <researcher> words </researcher>
- researcher_hrns = [ x.strip() for x in researcher_hrns ]
- logger.info ("incoming researchers %s"%researcher_hrns)
- request = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns))
- logger.info ("%d incoming hrns, %d matches found"%(len(researcher_hrns),request.count()))
- researchers = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns)).all()
- record.reg_researchers = researchers
+ pi_hrns = getattr(record,'pi',None)
+ if pi_hrns is not None: record.update_pis (pi_hrns)
+
+ elif isinstance (record, RegSlice):
+ researcher_hrns = getattr(record,'researcher',None)
+ if researcher_hrns is not None: record.update_researchers (researcher_hrns)
elif isinstance (record, RegUser):
# create RegKey objects for incoming keys
def Update(self, api, record_dict):
assert ('type' in record_dict)
- new_record=RegRecord(dict=record_dict)
- type = new_record.type
- hrn = new_record.hrn
+ new_record=make_record(dict=record_dict)
+ (type,hrn) = (new_record.type, new_record.hrn)
# make sure the record exists
record = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))
record.just_updated()
- # validate the type
- if type not in ['authority', 'slice', 'node', 'user']:
- raise UnknownSfaType(type)
-
# Use the pointer from the existing record, not the one that the user
# gave us. This prevents the user from inserting a forged pointer
pointer = record.pointer
- # is the a change in keys ?
+ # is there a change in keys ?
new_key=None
if type=='user':
if getattr(new_key,'keys',None):
if isinstance (new_key,types.ListType):
new_key=new_key[0]
- # update the PLC information that was specified with the record
- if not self.driver.update (record.__dict__, new_record.__dict__, hrn, new_key):
- logger.warning("driver.update failed")
-
# take new_key into account
if new_key:
# update the openssl key and gid
record.gid = gid
dsession.commit()
+ # xxx should do side effects from new_record to record
+ # not too sure how to do that
+ # not too big a deal with planetlab as the driver is authoritative, but...
+
+ # update native relations
+ if isinstance (record, RegSlice):
+ researcher_hrns = getattr(new_record,'researcher',None)
+ if researcher_hrns is not None: record.update_researchers (researcher_hrns)
+
+ elif isinstance (record, RegAuthority):
+ pi_hrns = getattr(new_record,'pi',None)
+ if pi_hrns is not None: record.update_pis (pi_hrns)
+
+ # update the PLC information that was specified with the record
+ if not self.driver.update (record.__dict__, new_record.__dict__, hrn, new_key):
+ logger.warning("driver.update failed")
+
# update membership for researchers, pis, owners, operators
self.update_driver_relations (record, new_record)
logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
self.shell.DeletePersonFromSlice (target_id, subject_id)
elif subject_type == 'authority' and target_type == 'user' and relation_name == 'pi':
- logger.log ("WARNING: XXX todo pldriver.update_relation not implemented for the 'pi' relationship")
+ # due to the plcapi limitations this means essentially adding pi role to all people in the list
+ # it's tricky to remove any pi role here, although it might be desirable
+ persons = self.shell.GetPersons (target_ids)
+ for person in persons:
+ if 'pi' not in person['roles']:
+ self.shell.AddRoleToPerson('pi',person['person_id'])
else:
logger.info('unexpected relation %s to maintain, %s -> %s'%(relation_name,subject_type,target_type))
def __repr__ (self):
return RegRecord.__repr__(self).replace("Record","Authority")
+ def update_pis (self, pi_hrns):
+ # don't ruin the import of that file in a client world
+ from sfa.storage.alchemy import dbsession
+ # strip that in case we have <researcher> words </researcher>
+ pi_hrns = [ x.strip() for x in pi_hrns ]
+ request = dbsession.query (RegUser).filter(RegUser.hrn.in_(pi_hrns))
+ logger.info ("RegAuthority.update_pis: %d incoming pis, %d matches found"%(len(pi_hrns),request.count()))
+ pis = dbsession.query (RegUser).filter(RegUser.hrn.in_(pi_hrns)).all()
+ self.reg_pis = pis
+
####################
class RegSlice (RegRecord):
__tablename__ = 'slices'
def __repr__ (self):
return RegRecord.__repr__(self).replace("Record","Slice")
+ def update_researchers (self, researcher_hrns):
+ # don't ruin the import of that file in a client world
+ from sfa.storage.alchemy import dbsession
+ # strip that in case we have <researcher> words </researcher>
+ researcher_hrns = [ x.strip() for x in researcher_hrns ]
+ request = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns))
+ logger.info ("RegSlice.update_researchers: %d incoming researchers, %d matches found"%(len(researcher_hrns),request.count()))
+ researchers = dbsession.query (RegUser).filter(RegUser.hrn.in_(researcher_hrns)).all()
+ self.reg_researchers = researchers
+
# when dealing with credentials, we need to retrieve the PIs attached to a slice
def get_pis (self):
# don't ruin the import of that file in a client world