15ebd5c81fd9b46804d389b09af2562d2a325e16
[plcapi.git] / PLC / Methods / GetSlices.py
1 # $Id$
2 # $URL$
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.Nodes import Nodes
9 from PLC.Sites import Site, Sites
10 from PLC.Slices import Slice, Slices
11
12 class GetSlices(Method):
13     """
14     Returns an array of structs containing details about slices. If
15     slice_filter is specified and is an array of slice identifiers or
16     slice names, or a struct of slice attributes, only slices matching
17     the filter will be returned. If return_fields is specified, only the
18     specified details will be returned.
19
20     Users may only query slices of which they are members. PIs may
21     query any of the slices at their sites. Admins and nodes may query
22     any slice. If a slice that cannot be queried is specified in
23     slice_filter, details about that slice will not be returned.
24     """
25
26     roles = ['admin', 'pi', 'user', 'node']
27
28     accepts = [
29         Auth(),
30         Mixed([Mixed(Slice.fields['slice_id'],
31                      Slice.fields['name'])],
32               Parameter(str,"name"),
33               Parameter(int,"slice_id"),
34               Filter(Slice.fields)),
35         Parameter([str], "List of fields to return", nullok = True)
36         ]
37
38     returns = [Slice.fields]
39
40     def call(self, auth, slice_filter = None, return_fields = None):
41         # If we are not admin, make sure to return only viewable
42         # slices.
43         if isinstance(self.caller, Person) and \
44            'admin' not in self.caller['roles']:
45             # Get slices that we are able to view
46             valid_slice_ids = self.caller['slice_ids']
47             # pis can view all slices at their site
48             if 'pi' in self.caller['roles'] and self.caller['site_ids']:
49                 sites = Sites(self.api, self.caller['site_ids'])
50                 for site in sites:
51                     valid_slice_ids += site['slice_ids']
52             # techs can view all slices on the nodes at their site
53             if 'tech' in self.caller['roles'] and self.caller['site_ids']:
54                 nodes = Nodes(self.api, {'site_id': self.caller['site_ids']}, ['site_id', 'slice_ids'])
55                 for node in nodes:
56                     valid_slice_ids.extend(node['slice_ids'])
57
58             if not valid_slice_ids:
59                 return []
60
61             if slice_filter is None:
62                 slice_filter = valid_slice_ids
63
64         # Must query at least slice_id (see below)
65         if return_fields is not None and 'slice_id' not in return_fields:
66             return_fields.append('slice_id')
67             added_fields = True
68         else:
69             added_fields = False
70
71         slices = Slices(self.api, slice_filter, return_fields)
72
73         # Filter out slices that are not viewable
74         if isinstance(self.caller, Person) and \
75            'admin' not in self.caller['roles']:
76             slices = filter(lambda slice: slice['slice_id'] in valid_slice_ids, slices)
77
78         # Remove slice_id if not specified
79         if added_fields:
80             for slice in slices:
81                 if 'slice_id' in slice:
82                     del slice['slice_id']
83
84         return slices