4 from sfa.util.faults import *
5 from sfa.util.method import Method
6 from sfa.util.parameter import Parameter, Mixed
7 from sfa.trust.auth import Auth
8 from sfa.util.record import GeniRecord
9 from sfa.util.genitable import GeniTable
10 from sfa.trust.certificate import Keypair, convert_public_key
11 from sfa.trust.gid import *
12 from sfa.util.debug import log
13 from sfa.trust.credential import Credential
17 Update an object in the registry. Currently, this only updates the
18 PLC information associated with the record. The Geni fields (name, type,
21 @param cred credential string specifying rights of the caller
22 @param record a record dictionary to be updated
24 @return 1 if successful, faults otherwise
27 interfaces = ['registry']
30 Parameter(str, "Credential string"),
31 Parameter(dict, "Record dictionary to be updated")
34 returns = Parameter(int, "1 if successful")
36 def call(self, cred, record_dict, caller_cred=None):
37 self.api.auth.check(cred, "update")
42 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))
43 new_record = GeniRecord(dict = record_dict)
44 type = new_record['type']
45 hrn = new_record['hrn']
46 self.api.auth.verify_object_permission(hrn)
48 # make sure the record exists
49 records = table.findObjects({'type': type, 'hrn': hrn})
51 raise RecordNotFound(hrn)
54 # Update_membership needs the membership lists in the existing record
55 # filled in, so it can see if members were added or removed
56 self.api.fill_record_info(record)
58 # Use the pointer from the existing record, not the one that the user
59 # gave us. This prevents the user from inserting a forged pointer
60 pointer = record['pointer']
62 # update the PLC information that was specified with the record
64 if (type == "authority"):
65 self.api.plshell.UpdateSite(self.api.plauth, pointer, new_record)
68 pl_record=self.api.geni_fields_to_pl_fields(type, hrn, new_record)
69 if 'name' in pl_record:
71 self.api.plshell.UpdateSlice(self.api.plauth, pointer, pl_record)
74 # SMBAKER: UpdatePerson only allows a limited set of fields to be
75 # updated. Ideally we should have a more generic way of doing
76 # this. I copied the field names from UpdatePerson.py...
78 all_fields = new_record
79 for key in all_fields.keys():
80 if key in ['first_name', 'last_name', 'title', 'email',
81 'password', 'phone', 'url', 'bio', 'accepted_aup',
83 update_fields[key] = all_fields[key]
84 self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
86 if 'key' in new_record and new_record['key']:
87 # must check this key against the previous one if it exists
88 persons = self.api.plshell.GetPersons(self.api.plauth, [pointer], ['key_ids'])
90 keys = person['key_ids']
91 keys = self.api.plshell.GetKeys(self.api.plauth, person['key_ids'])
93 if isinstance(new_record['key'], list):
94 new_key = new_record['key'][0]
96 new_key = new_record['key']
98 # Delete all stale keys
100 if new_record['key'] != key['key']:
101 self.api.plshell.DeleteKey(self.api.plauth, key['key_id'])
105 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type': 'ssh', 'key': new_key})
107 # update the openssl key and gid
108 pkey = convert_public_key(new_key)
110 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
111 gid = gid_object.save_to_string(save_parents=True)
113 record = GeniRecord(dict=record)
117 self.api.plshell.UpdateNode(self.api.plauth, pointer, new_record)
120 raise UnknownGeniType(type)
122 # update membership for researchers, pis, owners, operators
123 self.api.update_membership(record, record)