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