bed5b6e2bddbbe35245e6a0e6181c09a902ce340
[plcapi.git] / PLC / Methods / GetSliceTags.py
1 # $Id$
2 # $URL$
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Filter import Filter
7 from PLC.SliceTags import SliceTag, SliceTags
8 from PLC.Persons import Person, Persons
9 from PLC.Sites import Site, Sites
10 from PLC.Nodes import Nodes
11 from PLC.Slices import Slice, Slices
12 from PLC.Auth import Auth
13
14 class GetSliceTags(Method):
15     """
16     Returns an array of structs containing details about slice and
17     sliver attributes. An attribute is a sliver attribute if the
18     node_id field is set. If slice_tag_filter is specified and
19     is an array of slice attribute identifiers, or a struct of slice
20     attribute attributes, only slice attributes matching the filter
21     will be returned. If return_fields is specified, only the
22     specified details will be returned.
23
24     Users may only query attributes of slices or slivers of which they
25     are members. PIs may only query attributes of slices or slivers at
26     their sites, or of which they are members. Admins may query
27     attributes of any slice or sliver.
28     """
29
30     roles = ['admin', 'pi', 'user', 'node']
31
32     accepts = [
33         Auth(),
34         Mixed([SliceTag.fields['slice_tag_id']],
35               Filter(SliceTag.fields)),
36         Parameter([str], "List of fields to return", nullok = True)
37         ]
38
39     returns = [SliceTag.fields]
40
41
42     def call(self, auth, slice_tag_filter = None, return_fields = None):
43         # If we are not admin, make sure to only return our own slice
44         # and sliver attributes.
45         if isinstance(self.caller, Person) and \
46            'admin' not in self.caller['roles']:
47             # Get slices that we are able to view
48             valid_slice_ids = self.caller['slice_ids']
49             if 'pi' in self.caller['roles'] and self.caller['site_ids']:
50                 sites = Sites(self.api, self.caller['site_ids'])
51                 for site in sites:
52                     valid_slice_ids += site['slice_ids']
53             # techs can view all slices on the nodes at their site
54             if 'tech' in self.caller['roles'] and self.caller['site_ids']:
55                 nodes = Nodes(self.api, {'site_id': self.caller['site_ids']}, ['site_id', 'slice_ids'])
56                 for node in nodes:
57                     valid_slice_ids.extend(node['slice_ids'])
58
59             if not valid_slice_ids:
60                 return []
61
62             # Get slice attributes that we are able to view
63             valid_slice_tag_ids = []
64             slices = Slices(self.api, valid_slice_ids)
65             for slice in slices:
66                 valid_slice_tag_ids += slice['slice_tag_ids']
67
68             if not valid_slice_tag_ids:
69                 return []
70
71             if slice_tag_filter is None:
72                 slice_tag_filter = valid_slice_tag_ids
73
74         # Must query at least slice_tag_id (see below)
75         if return_fields is not None and 'slice_tag_id' not in return_fields:
76             return_fields.append('slice_tag_id')
77             added_fields = True
78         else:
79             added_fields = False
80
81         slice_tags = SliceTags(self.api, slice_tag_filter, return_fields)
82
83         # Filter out slice attributes that are not viewable
84         if isinstance(self.caller, Person) and \
85            'admin' not in self.caller['roles']:
86             slice_tags = filter(lambda slice_tag: \
87                                       slice_tag['slice_tag_id'] in valid_slice_tag_ids,
88                                       slice_tags)
89
90         # Remove slice_tag_id if not specified
91         if added_fields:
92             for slice_tag in slice_tags:
93                 if 'slice_tag_id' in slice_tag:
94                     del slice_tag['slice_tag_id']
95
96         return slice_tags