4 from sfa.trust.certificate import Keypair, convert_public_key
5 from sfa.trust.gid import *
7 from sfa.util.faults import *
8 from sfa.util.misc import *
9 from sfa.util.method import Method
10 from sfa.util.parameter import Parameter, Mixed
11 from sfa.util.record import GeniRecord
12 from sfa.util.genitable import GeniTable
13 from sfa.util.debug import log
14 from sfa.trust.auth import Auth
15 from sfa.trust.gid import create_uuid
16 from sfa.trust.credential import Credential
18 class register(Method):
20 Register an object with the registry. In addition to being stored in the
21 Geni database, the appropriate records will also be created in the
24 @param cred credential string
25 @param record_dict dictionary containing record fields
27 @return gid string representation
30 interfaces = ['registry']
33 Parameter(str, "Credential string"),
34 Parameter(dict, "Record dictionary containing record fields"),
35 Parameter(str, "Request hash")
38 returns = Parameter(int, "String representation of gid object")
40 def call(self, cred, record_dict, request_hash, caller_cred=None):
41 # This cred will be an authority cred, not a user, so we cant use it to
42 # authenticate the caller's request_hash. Let just get the caller's gid
43 # from the cred and authenticate using that
44 client_gid = Credential(string=cred).get_gid_caller()
45 client_gid_str = client_gid.save_to_string()
46 self.api.auth.authenticateGid(cred, [cred, record_dict], request_hash)
47 self.api.auth.check(cred, "register")
52 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))
53 record = GeniRecord(dict = record_dict)
54 record['authority'] = get_authority(record['hrn'])
57 self.api.auth.verify_object_permission(hrn)
58 auth_info = self.api.auth.get_auth_info(record['authority'])
60 # make sure record has a gid
61 if 'gid' not in record:
63 pkey = Keypair(create=True)
64 if 'key' in record and record['key']:
65 if isinstance(record['key'], list):
66 pub_key = record['key'][0]
68 pub_key = record['key']
69 pkey = convert_public_key(pub_key)
71 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
72 gid = gid_object.save_to_string(save_parents=True)
76 # check if record already exists
78 existing_records = table.find({'type': type, 'hrn': hrn})
80 raise ExistingRecord(hrn)
82 # We will update the pointer later
83 record['pointer'] = -1
84 record.set_pointer(-1)
85 record_id = table.insert(record)
86 record['record_id'] = record_id
88 if type in ["authority"]:
90 if not self.api.auth.hierarchy.auth_exists(hrn):
91 self.api.auth.hierarchy.create_auth(hrn)
93 # authorities are special since they are managed by the registry
94 # rather than by the caller. We create our own GID for the
95 # authority rather than relying on the caller to supply one.
97 # get the GID from the newly created authority
98 gid = auth_info.get_gid_object()
99 record.set_gid(gid.save_to_string(save_parents=True))
101 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
102 sites = self.api.plshell.GetSites(self.api.plauth, [pl_record['login_base']])
104 pointer = self.api.plshell.AddSite(self.api.plauth, pl_record)
106 pointer = sites[0]['site_id']
108 record.set_pointer(pointer)
110 elif (type == "slice"):
111 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
112 slices = self.api.plshell.GetSlices(self.api.plauth, [pl_record['name']])
114 pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record)
116 pointer = slices[0]['slice_id']
117 record.set_pointer(pointer)
119 elif (type == "user"):
120 persons = self.api.plshell.GetPersons(self.api.plauth, [record['email']])
122 pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record))
124 pointer = persons[0]['person_id']
126 if 'enabled' in record and record['enabled']:
127 self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']})
128 # add this persons to the site only if he is being added for the first
129 # time by sfa and doesont already exist in plc
130 if not persons or not persons[0]['site_ids']:
131 login_base = get_leaf(record['authority'])
132 self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base)
134 # What roles should this user have?
135 self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer)
136 record.set_pointer(pointer)
139 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key})
141 elif (type == "node"):
142 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
143 login_base = hrn_to_pl_login_base(record['authority'])
144 nodes = self.api.plshell.GetNodes(self.api.plauth, [pl_record['hostname']])
146 pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record)
148 pointer = nodes[0]['node_id']
149 record.set_pointer(pointer)
152 raise UnknownGeniType(type)
156 # update membership for researchers, pis, owners, operators
157 self.api.update_membership(None, record)
159 return record.get_gid_object().save_to_string(save_parents=True)