- # check if record already exists
- table = SfaTable()
- existing_records = table.find({'type': type, 'hrn': hrn})
- if existing_records:
- raise ExistingRecord(hrn)
-
- record = SfaRecord(dict = record)
- record['authority'] = get_authority(record['hrn'])
- type = record['type']
- hrn = record['hrn']
- auth_info = api.auth.get_auth_info(record['authority'])
- pub_key = None
- # make sure record has a gid
- if 'gid' not in record:
- uuid = create_uuid()
- pkey = Keypair(create=True)
- if 'key' in record and record['key']:
- if isinstance(record['key'], types.ListType):
- pub_key = record['key'][0]
- else:
- pub_key = record['key']
- pkey = convert_public_key(pub_key)
-
- gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
- gid = gid_object.save_to_string(save_parents=True)
- record['gid'] = gid
- record.set_gid(gid)
-
- if type in ["authority"]:
- # update the tree
- if not api.auth.hierarchy.auth_exists(hrn):
- api.auth.hierarchy.create_auth(hrn_to_urn(hrn,'authority'))
-
- # get the GID from the newly created authority
- gid = auth_info.get_gid_object()
- record.set_gid(gid.save_to_string(save_parents=True))
- pl_record = api.sfa_fields_to_pl_fields(type, hrn, record)
- sites = api.plshell.GetSites(api.plauth, [pl_record['login_base']])
- if not sites:
- pointer = api.plshell.AddSite(api.plauth, pl_record)
- else:
- pointer = sites[0]['site_id']
-
- record.set_pointer(pointer)
- record['pointer'] = pointer
-
- elif (type == "slice"):
- acceptable_fields=['url', 'instantiation', 'name', 'description']
- pl_record = api.sfa_fields_to_pl_fields(type, hrn, record)
- for key in pl_record.keys():
- if key not in acceptable_fields:
- pl_record.pop(key)
- slices = api.plshell.GetSlices(api.plauth, [pl_record['name']])
- if not slices:
- pointer = api.plshell.AddSlice(api.plauth, pl_record)
- else:
- pointer = slices[0]['slice_id']
- record.set_pointer(pointer)
- record['pointer'] = pointer
-
- elif (type == "user"):
- persons = api.plshell.GetPersons(api.plauth, [record['email']])
- if not persons:
- pointer = api.plshell.AddPerson(api.plauth, dict(record))
- else:
- pointer = persons[0]['person_id']
-
- if 'enabled' in record and record['enabled']:
- api.plshell.UpdatePerson(api.plauth, pointer, {'enabled': record['enabled']})
- # add this persons to the site only if he is being added for the first
- # time by sfa and doesont already exist in plc
- if not persons or not persons[0]['site_ids']:
- login_base = get_leaf(record['authority'])
- api.plshell.AddPersonToSite(api.plauth, pointer, login_base)
-
- # What roles should this user have?
- api.plshell.AddRoleToPerson(api.plauth, 'user', pointer)
- # Add the user's key
- if pub_key:
- api.plshell.AddPersonKey(api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key})
-
- elif (type == "node"):
- pl_record = api.sfa_fields_to_pl_fields(type, hrn, record)
- login_base = hrn_to_pl_login_base(record['authority'])
- nodes = api.plshell.GetNodes(api.plauth, [pl_record['hostname']])
- if not nodes:
- pointer = api.plshell.AddNode(api.plauth, login_base, pl_record)
- else:
- pointer = nodes[0]['node_id']
-
- record['pointer'] = pointer
- record.set_pointer(pointer)
- record_id = table.insert(record)
- record['record_id'] = record_id
-
- # update membership for researchers, pis, owners, operators
- api.update_membership(None, record)
-
- return record.get_gid_object().save_to_string(save_parents=True)
-
-def update(api, record_dict):
- new_record = SfaRecord(dict = record_dict)
- type = new_record['type']
- hrn = new_record['hrn']
- urn = hrn_to_urn(hrn,type)
- table = SfaTable()
- # make sure the record exists
- records = table.findObjects({'type': type, 'hrn': hrn})
- if not records:
- raise RecordNotFound(hrn)
- record = records[0]
- record['last_updated'] = time.gmtime()
-
- # Update_membership needs the membership lists in the existing record
- # filled in, so it can see if members were added or removed
- api.fill_record_info(record)
-
- # 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']
- # update the PLC information that was specified with the record
-
- if (type == "authority"):
- api.plshell.UpdateSite(api.plauth, pointer, new_record)
-
- elif type == "slice":
- pl_record=api.sfa_fields_to_pl_fields(type, hrn, new_record)
- if 'name' in pl_record:
- pl_record.pop('name')
- api.plshell.UpdateSlice(api.plauth, pointer, pl_record)
+ # subject_record describes the subject of the relationships
+ # ref_record contains the target values for the various relationships we need to manage
+ # (to begin with, this is just the slice x person relationship)
+ def update_driver_relations (self, subject_obj, ref_obj):
+ type=subject_obj.type
+ #for (k,v) in subject_obj.__dict__.items(): print k,'=',v
+ if type=='slice' and hasattr(ref_obj,'researcher'):
+ self.update_driver_relation(subject_obj, ref_obj.researcher, 'user', 'researcher')
+ elif type=='authority' and hasattr(ref_obj,'pi'):
+ self.update_driver_relation(subject_obj,ref_obj.pi, 'user', 'pi')
+
+ # field_key is the name of one field in the record, typically 'researcher' for a 'slice' record
+ # hrns is the list of hrns that should be linked to the subject from now on
+ # target_type would be e.g. 'user' in the 'slice' x 'researcher' example
+ def update_driver_relation (self, record_obj, hrns, target_type, relation_name):
+ # locate the linked objects in our db
+ subject_type=record_obj.type
+ subject_id=record_obj.pointer
+ # get the 'pointer' field of all matching records
+ link_id_tuples = dbsession.query(RegRecord.pointer).filter_by(type=target_type).filter(RegRecord.hrn.in_(hrns)).all()
+ # sqlalchemy returns named tuples for columns
+ link_ids = [ tuple.pointer for tuple in link_id_tuples ]
+ self.driver.update_relation (subject_type, target_type, relation_name, subject_id, link_ids)
+
+ def Register(self, api, record_dict):
+
+ hrn, type = record_dict['hrn'], record_dict['type']
+ urn = hrn_to_urn(hrn,type)
+ # validate the type
+ if type not in ['authority', 'slice', 'node', 'user']:
+ raise UnknownSfaType(type)
+
+ # check if record_dict already exists
+ existing_records = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).all()
+ if existing_records:
+ raise ExistingRecord(hrn)
+
+ assert ('type' in record_dict)
+ # returns the right type of RegRecord according to type in record
+ record = make_record(dict=record_dict)
+ record.just_created()
+ record.authority = get_authority(record.hrn)
+ auth_info = api.auth.get_auth_info(record.authority)
+ pub_key = None
+ # make sure record has a gid
+ if not record.gid:
+ uuid = create_uuid()
+ pkey = Keypair(create=True)
+ if getattr(record,'keys',None):
+ pub_key=record.keys
+ # use only first key in record
+ if isinstance(record.keys, types.ListType):
+ pub_key = record.keys[0]
+ pkey = convert_public_key(pub_key)
+
+ gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
+ gid = gid_object.save_to_string(save_parents=True)
+ record.gid = gid
+
+ if isinstance (record, RegAuthority):
+ # update the tree
+ if not api.auth.hierarchy.auth_exists(hrn):
+ api.auth.hierarchy.create_auth(hrn_to_urn(hrn,'authority'))
+
+ # get the GID from the newly created authority
+ gid = auth_info.get_gid_object()
+ record.gid=gid.save_to_string(save_parents=True)