5 from sfa.util.faults import *
6 from sfa.util.method import Method
7 from sfa.util.parameter import Parameter, Mixed
8 from sfa.trust.auth import Auth
9 from sfa.util.record import GeniRecord
10 from sfa.util.genitable import GeniTable
11 from sfa.trust.certificate import Keypair, convert_public_key
12 from sfa.trust.gid import *
13 from sfa.util.debug import log
14 from sfa.trust.credential import Credential
18 Update an object in the registry. Currently, this only updates the
19 PLC information associated with the record. The Geni fields (name, type,
22 @param cred credential string specifying rights of the caller
23 @param record a record dictionary to be updated
25 @return 1 if successful, faults otherwise
28 interfaces = ['registry']
31 Parameter(str, "Credential string"),
32 Parameter(dict, "Record dictionary to be updated")
35 returns = Parameter(int, "1 if successful")
37 def call(self, cred, record_dict, caller_cred=None):
38 self.api.auth.check(cred, "update")
43 self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, Credential(string=caller_cred).get_gid_caller().get_hrn(), None, self.name))
44 new_record = GeniRecord(dict = record_dict)
45 type = new_record['type']
46 hrn = new_record['hrn']
47 self.api.auth.verify_object_permission(hrn)
49 # make sure the record exists
50 records = table.findObjects({'type': type, 'hrn': hrn})
52 raise RecordNotFound(hrn)
54 record['last_updated'] = time.gmtime()
56 # Update_membership needs the membership lists in the existing record
57 # filled in, so it can see if members were added or removed
58 self.api.fill_record_info(record)
60 # Use the pointer from the existing record, not the one that the user
61 # gave us. This prevents the user from inserting a forged pointer
62 pointer = record['pointer']
64 # update the PLC information that was specified with the record
66 if (type == "authority"):
67 self.api.plshell.UpdateSite(self.api.plauth, pointer, new_record)
70 pl_record=self.api.geni_fields_to_pl_fields(type, hrn, new_record)
71 if 'name' in pl_record:
73 self.api.plshell.UpdateSlice(self.api.plauth, pointer, pl_record)
76 # SMBAKER: UpdatePerson only allows a limited set of fields to be
77 # updated. Ideally we should have a more generic way of doing
78 # this. I copied the field names from UpdatePerson.py...
80 all_fields = new_record
81 for key in all_fields.keys():
82 if key in ['first_name', 'last_name', 'title', 'email',
83 'password', 'phone', 'url', 'bio', 'accepted_aup',
85 update_fields[key] = all_fields[key]
86 self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
88 if 'key' in new_record and new_record['key']:
89 # must check this key against the previous one if it exists
90 persons = self.api.plshell.GetPersons(self.api.plauth, [pointer], ['key_ids'])
92 keys = person['key_ids']
93 keys = self.api.plshell.GetKeys(self.api.plauth, person['key_ids'])
95 if isinstance(new_record['key'], list):
96 new_key = new_record['key'][0]
98 new_key = new_record['key']
100 # Delete all stale keys
102 if new_record['key'] != key['key']:
103 self.api.plshell.DeleteKey(self.api.plauth, key['key_id'])
107 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type': 'ssh', 'key': new_key})
109 # update the openssl key and gid
110 pkey = convert_public_key(new_key)
112 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
113 gid = gid_object.save_to_string(save_parents=True)
115 record = GeniRecord(dict=record)
119 self.api.plshell.UpdateNode(self.api.plauth, pointer, new_record)
122 raise UnknownGeniType(type)
124 # update membership for researchers, pis, owners, operators
125 self.api.update_membership(record, new_record)