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):
42 user_cred = Credential(string=cred)
45 gid_origin_caller = user_cred.get_gid_origin_caller()
46 origin_hrn = gid_origin_caller.get_hrn()
47 self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))
49 # This cred will be an authority cred, not a user, so we cant use it to
50 # authenticate the caller's request_hash. Let just get the caller's gid
51 # from the cred and authenticate using that
52 client_gid = Credential(string=cred).get_gid_caller()
53 client_gid_str = client_gid.save_to_string(save_parents=True)
54 self.api.auth.authenticateGid(client_gid_str, [cred], request_hash)
55 self.api.auth.check(cred, "register")
57 record = GeniRecord(dict = record_dict)
58 record['authority'] = get_authority(record['hrn'])
61 self.api.auth.verify_object_permission(hrn)
62 auth_info = self.api.auth.get_auth_info(record['authority'])
64 # make sure record has a gid
65 if 'gid' not in record:
67 pkey = Keypair(create=True)
68 if 'key' in record and record['key']:
69 if isinstance(record['key'], list):
70 pub_key = record['key'][0]
72 pub_key = record['key']
73 pkey = convert_public_key(pub_key)
75 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
76 gid = gid_object.save_to_string(save_parents=True)
80 # check if record already exists
82 existing_records = table.find({'type': type, 'hrn': hrn})
84 raise ExistingRecord(hrn)
86 if type in ["authority"]:
88 if not self.api.auth.hierarchy.auth_exists(hrn):
89 self.api.auth.hierarchy.create_auth(hrn)
91 # authorities are special since they are managed by the registry
92 # rather than by the caller. We create our own GID for the
93 # authority rather than relying on the caller to supply one.
95 # get the GID from the newly created authority
96 gid = auth_info.get_gid_object()
97 record.set_gid(gid.save_to_string(save_parents=True))
99 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
100 sites = self.api.plshell.GetSites(self.api.plauth, [pl_record['login_base']])
102 pointer = self.api.plshell.AddSite(self.api.plauth, pl_record)
104 pointer = sites[0]['site_id']
106 record.set_pointer(pointer)
107 record['pointer'] = pointer
109 elif (type == "slice"):
110 acceptable_fields=['url', 'instantiation', 'name', 'description']
111 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
112 for key in pl_record.keys():
113 if key not in acceptable_fields:
115 slices = self.api.plshell.GetSlices(self.api.plauth, [pl_record['name']])
117 pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record)
119 pointer = slices[0]['slice_id']
120 record.set_pointer(pointer)
121 record['pointer'] = pointer
123 elif (type == "user"):
124 persons = self.api.plshell.GetPersons(self.api.plauth, [record['email']])
126 pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record))
128 raise ExistingRecord(record['email'])
130 if 'enabled' in record and record['enabled']:
131 self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']})
132 # add this persons to the site only if he is being added for the first
133 # time by sfa and doesont already exist in plc
134 if not persons or not persons[0]['site_ids']:
135 login_base = get_leaf(record['authority'])
136 self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base)
138 # What roles should this user have?
139 self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer)
140 record.set_pointer(pointer)
141 record['pointer'] = pointer
144 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key})
146 elif (type == "node"):
147 pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record)
148 login_base = hrn_to_pl_login_base(record['authority'])
149 nodes = self.api.plshell.GetNodes(self.api.plauth, [pl_record['hostname']])
151 pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record)
153 pointer = nodes[0]['node_id']
154 record['pointer'] = pointer
155 record.set_pointer(pointer)
158 raise UnknownGeniType(type)
160 record_id = table.insert(record)
161 record['record_id'] = record_id
163 # update membership for researchers, pis, owners, operators
164 self.api.update_membership(None, record)
166 return record.get_gid_object().save_to_string(save_parents=True)