3 from PLC.Method import Method
4 from PLC.Parameter import Parameter, Mixed
5 from PLC.Filter import Filter
6 from PLC.Auth import Auth
7 from PLC.Persons import Person, Persons
8 from PLC.Sites import Site, Sites
9 from PLC.Slices import Slice, Slices
10 from PLC.Keys import Key, Keys
12 class GetSliceKeys(Method):
14 Returns an array of structs containing public key info for users in
15 the specified slices. If slice_filter is specified and is an array
16 of slice identifiers or slice names, or a struct of slice
17 attributes, only slices matching the filter will be returned. If
18 return_fields is specified, only the specified details will be
21 Users may only query slices of which they are members. PIs may
22 query any of the slices at their sites. Admins and nodes may query
23 any slice. If a slice that cannot be queried is specified in
24 slice_filter, details about that slice will not be returned.
27 roles = ['admin', 'pi', 'user', 'node']
31 Mixed([Mixed(Slice.fields['slice_id'],
32 Slice.fields['name'])],
33 Filter(Slice.fields)),
34 Parameter([str], "List of fields to return", nullok = True)
39 'slice_id': Slice.fields['slice_id'],
40 'name': Slice.fields['name'],
41 'person_id': Person.fields['person_id'],
42 'email': Person.fields['email'],
43 'key': Key.fields['key']
46 def call(self, auth, slice_filter = None, return_fields = None):
47 slice_fields = ['slice_id', 'name']
48 person_fields = ['person_id', 'email']
51 # If we are not admin, make sure to return only viewable
53 if isinstance(self.caller, Person) and \
54 'admin' not in self.caller['roles']:
55 # Get slices that we are able to view
56 valid_slice_ids = self.caller['slice_ids']
57 if 'pi' in self.caller['roles'] and self.caller['site_ids']:
58 sites = Sites(self.api, self.caller['site_ids'])
60 valid_slice_ids += site['slice_ids']
62 if not valid_slice_ids:
65 if slice_filter is None:
66 slice_filter = valid_slice_ids
69 slice_return_fields = filter(lambda field: field in slice_fields, return_fields)
70 person_return_fields = filter(lambda field: field in person_fields, return_fields)
71 key_return_fields = filter(lambda field: field in key_fields, return_fields)
73 slice_return_fields = slice_fields
74 person_return_fields = person_fields
75 key_return_fields = key_fields
77 # Must query at least Slice.slice_id, Slice.person_ids,
78 # and Person.person_id and Person.key_ids so we can join data correctly
79 slice_added_fields = set(['slice_id', 'person_ids']).difference(slice_return_fields)
80 slice_return_fields += slice_added_fields
81 person_added_fields = set(['person_id', 'key_ids']).difference(person_return_fields)
82 person_return_fields += person_added_fields
83 key_added_fields = set(['key_id']).difference(key_return_fields)
84 key_return_fields += key_added_fields
87 all_slices = Slices(self.api, slice_filter, slice_return_fields).dict('slice_id')
88 slice_ids = all_slices.keys()
89 slices = all_slices.values()
91 # Filter out slices that are not viewable
92 if isinstance(self.caller, Person) and \
93 'admin' not in self.caller['roles']:
94 slices = filter(lambda slice: slice['slice_id'] in valid_slice_ids, slices)
99 person_ids.update(slice['person_ids'])
101 all_persons = Persons(self.api, list(person_ids), person_return_fields).dict('person_id')
102 person_ids = all_persons.keys()
103 persons = all_persons.values()
107 for person in persons:
108 key_ids.update(person['key_ids'])
110 all_keys = Keys(self.api, list(key_ids), key_return_fields).dict('key_id')
111 key_ids = all_keys.keys()
112 keys = all_keys.values()
114 # Create slice_keys list
116 slice_fields = list(set(slice_return_fields).difference(slice_added_fields))
117 person_fields = list(set(person_return_fields).difference(person_added_fields))
118 key_fields = list(set(key_return_fields).difference(key_added_fields))
121 slice_key = dict.fromkeys(slice_fields + person_fields + key_fields)
122 if not slice['person_ids']:
124 for person_id in slice['person_ids']:
125 person = all_persons[person_id]
126 if not person['key_ids']:
128 for key_id in person['key_ids']:
129 key = all_keys[key_id]
130 slice_key.update(dict(filter(lambda (k, v): k in slice_fields, slice.items())))
131 slice_key.update(dict(filter(lambda (k, v): k in person_fields, person.items())))
132 slice_key.update(dict(filter(lambda (k, v): k in key_fields, key.items())))
133 slice_keys.append(slice_key.copy())