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 Mixed(Parameter(str, "Request hash"),
36 Parameter(None, "Request hash not specified"))
39 returns = Parameter(int, "String representation of gid object")
41 def call(self, cred, record_dict, request_hash=None, origin_hrn=None):
42 # This cred will be an authority cred, not a user, so we cant use it to
43 # authenticate the caller's request_hash. Let just get the caller's gid
44 # from the cred and authenticate using that
45 client_gid = Credential(string=cred).get_gid_caller()
46 client_gid_str = client_gid.save_to_string(save_parents=True)
47 self.api.auth.authenticateGid(client_gid_str, [cred], request_hash)
48 self.api.auth.check(cred, "register")
50 origin_hrn=Credential(string=cred).get_gid_caller().get_hrn()
53 self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, None, self.name))
54 record = GeniRecord(dict = record_dict)
55 record['authority'] = get_authority(record['hrn'])
58 self.api.auth.verify_object_permission(hrn)
59 auth_info = self.api.auth.get_auth_info(record['authority'])
61 # make sure record has a gid
62 if 'gid' not in record:
64 pkey = Keypair(create=True)
65 if 'key' in record and record['key']:
66 if isinstance(record['key'], list):
67 pub_key = record['key'][0]
69 pub_key = record['key']
70 pkey = convert_public_key(pub_key)
72 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
73 gid = gid_object.save_to_string(save_parents=True)
77 # check if record already exists
79 existing_records = table.find({'type': type, 'hrn': hrn})
81 raise ExistingRecord(hrn)
83 if type in ["authority"]:
85 if not self.api.auth.hierarchy.auth_exists(hrn):
86 self.api.auth.hierarchy.create_auth(hrn)
88 # authorities are special since they are managed by the registry
89 # rather than by the caller. We create our own GID for the
90 # authority rather than relying on the caller to supply one.
92 # get the GID from the newly created authority
93 gid = auth_info.get_gid_object()
94 record.set_gid(gid.save_to_string(save_parents=True))
96 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
97 sites = self.api.plshell.GetSites(self.api.plauth, [pl_record['login_base']])
99 pointer = self.api.plshell.AddSite(self.api.plauth, pl_record)
101 pointer = sites[0]['site_id']
103 record.set_pointer(pointer)
104 record['pointer'] = pointer
106 elif (type == "slice"):
107 acceptable_fields=['url', 'instantiation', 'name', 'description']
108 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
109 for key in pl_record.keys():
110 if key not in acceptable_fields:
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)
118 record['pointer'] = pointer
120 elif (type == "user"):
121 persons = self.api.plshell.GetPersons(self.api.plauth, [record['email']])
123 pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record))
125 raise ExistingRecord(record['email'])
127 if 'enabled' in record and record['enabled']:
128 self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']})
129 # add this persons to the site only if he is being added for the first
130 # time by sfa and doesont already exist in plc
131 if not persons or not persons[0]['site_ids']:
132 login_base = get_leaf(record['authority'])
133 self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base)
135 # What roles should this user have?
136 self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer)
137 record.set_pointer(pointer)
138 record['pointer'] = pointer
141 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key})
143 elif (type == "node"):
144 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
145 login_base = hrn_to_pl_login_base(record['authority'])
146 nodes = self.api.plshell.GetNodes(self.api.plauth, [pl_record['hostname']])
148 pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record)
150 pointer = nodes[0]['node_id']
151 record['pointer'] = pointer
152 record.set_pointer(pointer)
155 raise UnknownGeniType(type)
157 record_id = table.insert(record)
158 record['record_id'] = record_id
160 # update membership for researchers, pis, owners, operators
161 self.api.update_membership(None, record)
163 return record.get_gid_object().save_to_string(save_parents=True)