oops, undefined variable
[plcapi.git] / PLC / Methods / GetSliceAttributes.py
index 38e887f..b8a0a11 100644 (file)
@@ -1,17 +1,22 @@
 from PLC.Faults import *
 from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
 from PLC.Faults import *
 from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
+from PLC.Filter import Filter
 from PLC.SliceAttributes import SliceAttribute, SliceAttributes
 from PLC.SliceAttributes import SliceAttribute, SliceAttributes
+from PLC.Persons import Person, Persons
+from PLC.Sites import Site, Sites
 from PLC.Slices import Slice, Slices
 from PLC.Slices import Slice, Slices
-from PLC.Nodes import Node, Nodes
-from PLC.Auth import PasswordAuth
+from PLC.Auth import Auth
 
 class GetSliceAttributes(Method):
     """
 
 class GetSliceAttributes(Method):
     """
-    Get an array of structs containing the values of slice and sliver
-    attributes. An attribute is a sliver attribute if the node_id
-    field is set. If slice_attribute_id_list is specified, only the
-    specified attributes will be queried, if set.
+    Returns an array of structs containing details about slice and
+    sliver attributes. An attribute is a sliver attribute if the
+    node_id field is set. If slice_attribute_filter is specified and
+    is an array of slice attribute identifiers, or a struct of slice
+    attribute attributes, only slice attributes matching the filter
+    will be returned. If return_fields is specified, only the
+    specified details will be returned.
 
     Users may only query attributes of slices or slivers of which they
     are members. PIs may only query attributes of slices or slivers at
 
     Users may only query attributes of slices or slivers of which they
     are members. PIs may only query attributes of slices or slivers at
@@ -19,41 +24,65 @@ class GetSliceAttributes(Method):
     attributes of any slice or sliver.
     """
 
     attributes of any slice or sliver.
     """
 
-    roles = ['admin', 'pi', 'user']
+    roles = ['admin', 'pi', 'user', 'node']
 
     accepts = [
 
     accepts = [
-        PasswordAuth(),
-        Mixed(Slice.fields['slice_id'],
-              Slice.fields['name']),
-        [SliceAttribute.fields['slice_attribute_id']],
+        Auth(),
+        Mixed([SliceAttribute.fields['slice_attribute_id']],
+              Filter(SliceAttribute.fields)),
+        Parameter([str], "List of fields to return", nullok = True)
         ]
 
     returns = [SliceAttribute.fields]
         ]
 
     returns = [SliceAttribute.fields]
+    
 
 
-    def call(self, auth, slice_id_or_name, slice_attribute_id_list = None):
-        slices = Slices(self.api, [slice_id_or_name]).values()
-        if not slices:
-            raise PLCInvalidArgument, "No such slice"
-        slice = slices[0]
-
-        if 'admin' not in self.caller['roles']:
-            if self.caller['person_id'] in slice['person_ids']:
-                pass
-            elif 'pi' not in self.caller['roles']:
-                raise PLCPermissionDenied, "Not a member of the specified slice"
-            elif slice['site_id'] not in self.caller['site_ids']:
-                raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
-
-        if slice_attribute_id_list is None:
-            slice_attribute_id_list = slice['slice_attribute_ids']
+    def call(self, auth, slice_attribute_filter = None, return_fields = None):
+       # If we are not admin, make sure to only return our own slice
+       # and sliver attributes.
+        if isinstance(self.caller, Person) and \
+           'admin' not in self.caller['roles']:
+            # Get slices that we are able to view
+            valid_slice_ids = self.caller['slice_ids']
+            if 'pi' in self.caller['roles'] and self.caller['site_ids']:
+                sites = Sites(self.api, self.caller['site_ids'])
+                for site in sites:
+                    valid_slice_ids += site['slice_ids']
+
+            if not valid_slice_ids:
+                return []
+
+            # Get slice attributes that we are able to view
+            valid_slice_attribute_ids = []
+            slices = Slices(self.api, valid_slice_ids)
+            for slice in slices:
+                valid_slice_attribute_ids += slice['slice_attribute_ids']
+
+            if not valid_slice_attribute_ids:
+                return []
+
+            if slice_attribute_filter is None:
+                slice_attribute_filter = valid_slice_attribute_ids
+
+        # Must query at least slice_attribute_id (see below)
+        if return_fields is not None and 'slice_attribute_id' not in return_fields:
+            return_fields.append('slice_attribute_id')
+            added_fields = True
         else:
         else:
-            if set(slice_attribute_id_list).intersection(slice['slice_attribute_ids']) != \
-               set(slice_attribute_id_list):
-                raise PLCInvalidArgument, "Invalid slice attribute ID(s)"
-
-        slice_attributes = SliceAttributes(self.api, slice_attribute_id_list).values()
-       # turn each slice attribute into a real dict
-       slice_attributes = [dict(slice_attribute.items()) \
-                          for slice_attribute in slice_attributes]
-       
+            added_fields = False
+
+        slice_attributes = SliceAttributes(self.api, slice_attribute_filter, return_fields)
+
+        # Filter out slice attributes that are not viewable
+        if isinstance(self.caller, Person) and \
+           'admin' not in self.caller['roles']:
+            slice_attributes = filter(lambda slice_attribute: \
+                                      slice_attribute['slice_attribute_id'] in valid_slice_attribute_ids,
+                                      slice_attributes)
+
+        # Remove slice_attribute_id if not specified
+        if added_fields:
+            for slice_attribute in slice_attributes:
+               if 'slice_attribute_id' in slice_attribute:
+                   del slice_attribute['slice_attribute_id']
+
         return slice_attributes
         return slice_attributes