dcb7752bbbf99e0977a5948ce0e2e81624a03039
[sfa.git] / geni / methods / register.py
1 ### $Id$
2 ### $URL$
3
4 from geni.trust.certificate import Keypair, convert_public_key
5 from geni.trust.gid import *
6 from geni.util.faults import *
7 from geni.util.misc import *
8 from geni.util.method import Method
9 from geni.util.parameter import Parameter, Mixed
10 from geni.util.auth import Auth
11 from geni.util.record import GeniRecord
12 from geni.util.debug import log
13
14 class register(Method):
15     """
16     Register an object with the registry. In addition to being stored in the
17     Geni database, the appropriate records will also be created in the
18     PLC databases
19     
20     @param cred credential string
21     @param record_dict dictionary containing record fields
22     
23     @return gid string representation
24     """
25
26     interfaces = ['registry']
27     
28     accepts = [
29         Parameter(str, "Credential string"),
30         Parameter(dict, "Record dictionary containing record fields")
31         ]
32
33     returns = Parameter(int, "String representation of gid object")
34     
35     def call(self, cred, record_dict):
36         self.api.auth.check(cred, "register")
37         record = GeniRecord(dict = record_dict)
38         type = record.get_type()
39         name = record.get_name()
40         self.api.auth.verify_object_permission(name)
41         auth_name = self.api.auth.get_authority(name)
42         auth_info = self.api.auth.get_auth_info(auth_name)
43         table = self.api.auth.get_auth_table(auth_name)
44         
45         # make sure record has a gid
46         if 'gid' not in record:
47             uuid = create_uuid()
48             pkey = Keypair(create=True)
49             if 'keys' in record and record['keys']:
50                 pkey = convert_public_key(record['keys'][0])
51             
52             gid_object = self.api.auth.hierarchy.create_gid(name, uuid, pkey)
53             gid = gid_object.save_to_string(save_parents=True)
54             record['gid'] = gid
55             record.set_gid(gid)
56
57         # check if record already exists
58         existing_records = table.resolve(type, name)
59         if existing_records:
60             raise ExistingRecord(name)
61         
62         if (type == "sa") or (type=="ma"):
63             # update the tree
64             if not self.api.auth.hierarchy.auth_exists(name):
65                 self.api.auth.hierarchy.create_auth(name)
66
67             # authorities are special since they are managed by the registry
68             # rather than by the caller. We create our own GID for the
69             # authority rather than relying on the caller to supply one.
70
71             # get the GID from the newly created authority
72             child_auth_info = self.api.auth.get_auth_info(name)
73             gid = auth_info.get_gid_object()
74             record.set_gid(gid.save_to_string(save_parents=True))
75
76             # if registering a sa, see if a ma already exists
77             # if registering a ma, see if a sa already exists
78             if (type == "sa"):
79                 other_rec = table.resolve("ma", record.get_name())
80             elif (type == "ma"):
81                 other_rec = table.resolve("sa", record.get_name())
82
83             if other_rec:
84                 print >> log, "linking ma and sa to the same plc site"
85                 pointer = other_rec[0].get_pointer()
86             else:
87                 pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
88                 print >> log, "adding site with fields", pl_record
89                 pointer = self.api.plshell.AddSite(self.api.plauth, pl_record)
90
91             record.set_pointer(pointer)
92
93         elif (type == "slice"):
94             pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
95             pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record)
96             record.set_pointer(pointer)
97
98         elif (type == "user"):
99             pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record))
100             if 'enabled' in record and record['enabled']:
101                 self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']})
102             login_base = get_leaf(auth_info.hrn)
103             self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base)
104             # What roles should this user have?
105             self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer) 
106             record.set_pointer(pointer)
107             
108             # Add the user's key
109             if record['keys']:
110                 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : record['keys'][0]})
111
112         elif (type == "node"):
113             pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
114             login_base = hrn_to_pl_login_base(auth_name)
115             pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record)
116             record.set_pointer(pointer)
117
118         else:
119             raise UnknownGeniType(type)
120
121         table.insert(record)
122
123         # update membership for researchers, pis, owners, operators
124         self.api.update_membership(None, record)
125
126         return record.get_gid_object().save_to_string(save_parents=True)