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
11 slice_fields = ['slice_id', 'name']
12 person_fields = ['person_id', 'email']
15 class GetSliceKeys(Method):
17 Returns an array of structs containing details about users/public keys
18 in slices. If slice_filter is specified and is an array of slice
19 identifiers or slice names, or a struct of slice attributes, only
20 slices matching the filter will be returned. If return_fields is
21 specified, only the specified details will be returned.
23 Users may only query slices of which they are members. PIs may
24 query any of the slices at their sites. Admins and nodes may query
25 any slice. If a slice that cannot be queried is specified in
26 slice_filter, details about that slice will not be returned.
29 roles = ['admin', 'pi', 'user', 'node']
33 Mixed([Mixed(Slice.fields['slice_id'],
34 Slice.fields['name'])],
35 Filter(Slice.fields)),
36 Parameter([str], "List of fields to return", nullok = True)
41 'slice_id': Slice.fields['slice_id'],
42 'name': Slice.fields['name'],
43 'person_id': Person.fields['person_id'],
44 'email': Person.fields['email'],
45 'key': Key.fields['key']
48 def call(self, auth, slice_filter = None, return_fields = None):
49 slice_fields = ['slice_id', 'name']
50 person_fields = ['person_id', 'email']
53 # If we are not admin, make sure to return only viewable
55 if isinstance(self.caller, Person) and \
56 'admin' not in self.caller['roles']:
57 # Get slices that we are able to view
58 valid_slice_ids = self.caller['slice_ids']
59 if 'pi' in self.caller['roles'] and self.caller['site_ids']:
60 sites = Sites(self.api, self.caller['site_ids'])
62 valid_slice_ids += site['slice_ids']
64 if not valid_slice_ids:
67 if slice_filter is None:
68 slice_filter = valid_slice_ids
71 slice_return_fields = filter(lambda field: field in slice_fields, return_fields)
72 person_return_fields = filter(lambda field: field in person_fields, return_fields)
73 key_return_fields = filter(lambda field: field in key_fields, return_fields)
75 slice_return_fields = slice_fields
76 person_return_fields = person_fields
77 key_return_fields = key_fields
79 # Must query at least Slice.slice_id, Slice.person_ids,
80 # and Person.person_id and Person.key_ids so we can join data correctly
81 slice_added_fields = set(['slice_id', 'person_ids']).difference(slice_return_fields)
82 slice_return_fields += slice_added_fields
83 person_added_fields = set(['person_id', 'key_ids']).difference(person_return_fields)
84 person_return_fields += person_added_fields
85 key_added_fields = set(['key_id']).difference(key_return_fields)
86 key_return_fields += key_added_fields
89 all_slices = Slices(self.api, slice_filter, slice_return_fields).dict('slice_id')
90 slice_ids = all_slices.keys()
91 slices = all_slices.values()
93 # Filter out slices that are not viewable
94 if isinstance(self.caller, Person) and \
95 'admin' not in self.caller['roles']:
96 slices = filter(lambda slice: slice['slice_id'] in valid_slice_ids, slices)
101 person_ids.update(slice['person_ids'])
103 all_persons = Persons(self.api, list(person_ids), person_return_fields).dict('person_id')
104 person_ids = all_persons.keys()
105 persons = all_persons.values()
109 for person in persons:
110 key_ids.update(person['key_ids'])
112 all_keys = Keys(self.api, list(key_ids), key_return_fields).dict('key_id')
113 key_ids = all_keys.keys()
114 keys = all_keys.values()
116 # Create slice_keys list
118 slice_fields = list(set(slice_return_fields).difference(slice_added_fields))
119 person_fields = list(set(person_return_fields).difference(person_added_fields))
120 key_fields = list(set(key_return_fields).difference(key_added_fields))
123 slice_key = dict.fromkeys(slice_fields + person_fields + key_fields)
124 if not slice['person_ids']:
126 for person_id in slice['person_ids']:
127 person = all_persons[person_id]
128 if not person['key_ids']:
130 for key_id in person['key_ids']:
131 key = all_keys[key_id]
132 slice_key.update(dict(filter(lambda (k, v): k in slice_fields, slice.items())))
133 slice_key.update(dict(filter(lambda (k, v): k in person_fields, person.items())))
134 slice_key.update(dict(filter(lambda (k, v): k in key_fields, key.items())))
135 slice_keys.append(slice_key.copy())