1 from PLC.Method import Method
2 from PLC.Parameter import Parameter, Mixed
3 from PLC.Filter import Filter
4 from PLC.Auth import Auth
5 from PLC.Persons import Person, Persons
6 from PLC.Sites import Site, Sites
7 from PLC.Slices import Slice, Slices
8 from PLC.Keys import Key, Keys
10 class GetSliceKeys(Method):
12 Returns an array of structs containing public key info for users in
13 the specified slices. If slice_filter is specified and is an array
14 of slice identifiers or slice names, or a struct of slice
15 attributes, only slices matching the filter will be returned. If
16 return_fields is specified, only the specified details will be
19 Users may only query slices of which they are members. PIs may
20 query any of the slices at their sites. Admins and nodes may query
21 any slice. If a slice that cannot be queried is specified in
22 slice_filter, details about that slice will not be returned.
25 roles = ['admin', 'pi', 'user', 'node']
29 Mixed([Mixed(Slice.fields['slice_id'],
30 Slice.fields['name'])],
31 Filter(Slice.fields)),
32 Parameter([str], "List of fields to return", nullok = True)
37 'slice_id': Slice.fields['slice_id'],
38 'name': Slice.fields['name'],
39 'person_id': Person.fields['person_id'],
40 'email': Person.fields['email'],
41 'key': Key.fields['key']
44 def call(self, auth, slice_filter = None, return_fields = None):
45 slice_fields = ['slice_id', 'name']
46 person_fields = ['person_id', 'email']
49 # If we are not admin, make sure to return only viewable
51 if isinstance(self.caller, Person) and \
52 'admin' not in self.caller['roles']:
53 # Get slices that we are able to view
54 valid_slice_ids = self.caller['slice_ids']
55 if 'pi' in self.caller['roles'] and self.caller['site_ids']:
56 sites = Sites(self.api, self.caller['site_ids'])
58 valid_slice_ids += site['slice_ids']
60 if not valid_slice_ids:
63 if slice_filter is None:
64 slice_filter = valid_slice_ids
67 slice_return_fields = [field for field in return_fields if field in slice_fields]
68 person_return_fields = [field for field in return_fields if field in person_fields]
69 key_return_fields = [field for field in return_fields if field in key_fields]
71 slice_return_fields = slice_fields
72 person_return_fields = person_fields
73 key_return_fields = key_fields
75 # Must query at least Slice.slice_id, Slice.person_ids,
76 # and Person.person_id and Person.key_ids so we can join data correctly
77 slice_added_fields = set(['slice_id', 'person_ids']).difference(slice_return_fields)
78 slice_return_fields += slice_added_fields
79 person_added_fields = set(['person_id', 'key_ids']).difference(person_return_fields)
80 person_return_fields += person_added_fields
81 key_added_fields = set(['key_id']).difference(key_return_fields)
82 key_return_fields += key_added_fields
85 all_slices = Slices(self.api, slice_filter, slice_return_fields).dict('slice_id')
86 slice_ids = list(all_slices.keys())
87 slices = list(all_slices.values())
89 # Filter out slices that are not viewable
90 if isinstance(self.caller, Person) and \
91 'admin' not in self.caller['roles']:
92 slices = [slice for slice in slices if slice['slice_id'] in valid_slice_ids]
97 person_ids.update(slice['person_ids'])
99 all_persons = Persons(self.api, list(person_ids), person_return_fields).dict('person_id')
100 person_ids = list(all_persons.keys())
101 persons = list(all_persons.values())
105 for person in persons:
106 key_ids.update(person['key_ids'])
108 all_keys = Keys(self.api, list(key_ids), key_return_fields).dict('key_id')
109 key_ids = list(all_keys.keys())
110 keys = list(all_keys.values())
112 # Create slice_keys list
114 slice_fields = list(set(slice_return_fields).difference(slice_added_fields))
115 person_fields = list(set(person_return_fields).difference(person_added_fields))
116 key_fields = list(set(key_return_fields).difference(key_added_fields))
119 slice_key = dict.fromkeys(slice_fields + person_fields + key_fields)
120 if not slice['person_ids']:
122 for person_id in slice['person_ids']:
123 person = all_persons[person_id]
124 if not person['key_ids']:
126 for key_id in person['key_ids']:
127 key = all_keys[key_id]
128 slice_key.update(dict([k_v for k_v in list(slice.items()) if k_v[0] in slice_fields]))
129 slice_key.update(dict([k_v1 for k_v1 in list(person.items()) if k_v1[0] in person_fields]))
130 slice_key.update(dict([k_v2 for k_v2 in list(key.items()) if k_v2[0] in key_fields]))
131 slice_keys.append(slice_key.copy())