Add notification plugin support to AddSliceToNodes and DeleteSliceFromNodes
[plcapi.git] / PLC / Methods / AddSliceToNodes.py
index 1b2942c..a7124d8 100644 (file)
@@ -3,15 +3,17 @@ from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
 from PLC.Nodes import Node, Nodes
 from PLC.Slices import Slice, Slices
 from PLC.Parameter import Parameter, Mixed
 from PLC.Nodes import Node, Nodes
 from PLC.Slices import Slice, Slices
+from PLC.Persons import Person, Persons
 from PLC.Auth import Auth
 from PLC.Auth import Auth
+from PLC.Plugins import PluginManager
 
 class AddSliceToNodes(Method):
     """
 
 class AddSliceToNodes(Method):
     """
-    Adds the specified slice to the specified nodes.
-    Nodes can be either local or foreign nodes, as returned by GetNodes
+    Adds the specified slice to the specified nodes. Nodes may be
+    either local or foreign nodes.
 
 
-    If the slice is
-    already associated with a node, no errors are returned. 
+    If the slice is already associated with a node, no errors are
+    returned.
 
     Returns 1 if successful, faults otherwise.
     """
 
     Returns 1 if successful, faults otherwise.
     """
@@ -22,42 +24,52 @@ class AddSliceToNodes(Method):
         Auth(),
         Mixed(Slice.fields['slice_id'],
               Slice.fields['name']),
         Auth(),
         Mixed(Slice.fields['slice_id'],
               Slice.fields['name']),
-       [Mixed(Node.fields['node_id'],
+        [Mixed(Node.fields['node_id'],
                Node.fields['hostname'])]
         ]
 
     returns = Parameter(int, '1 if successful')
 
                Node.fields['hostname'])]
         ]
 
     returns = Parameter(int, '1 if successful')
 
-    event_type = 'AddTo'
-    object_type = 'Node'
-
     def call(self, auth, slice_id_or_name, node_id_or_hostname_list):
         # Get slice information
         slices = Slices(self.api, [slice_id_or_name])
         if not slices:
     def call(self, auth, slice_id_or_name, node_id_or_hostname_list):
         # Get slice information
         slices = Slices(self.api, [slice_id_or_name])
         if not slices:
-            raise PLCInvalidArgument, "No such slice"
-
+            raise PLCInvalidArgument, "No such slice %r"%slice_id_or_name
         slice = slices[0]
 
         slice = slices[0]
 
+        if slice['peer_id'] is not None:
+            raise PLCInvalidArgument, "Not a local slice"
+
         if 'admin' not in self.caller['roles']:
             if self.caller['person_id'] in slice['person_ids']:
                 pass
         if 'admin' not in self.caller['roles']:
             if self.caller['person_id'] in slice['person_ids']:
                 pass
-            # Thierry : I cannot figure out how this works
-            # how is having pi role related to being in a slice ?
             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"
             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"
-       
+
         # Get specified nodes, add them to the slice
         # Get specified nodes, add them to the slice
-         
-        nodes = Nodes(self.api, node_id_or_hostname_list)
-       for node in nodes:
+        nodes = Nodes(self.api, node_id_or_hostname_list, 
+                      ['node_id', 'hostname', 'slice_ids', 'slice_ids_whitelist', 'site_id'])
+
+        for node in nodes:
+            # check the slice whitelist on each node first
+            # allow users at site to add node to slice, ignoring whitelist
+            if node['slice_ids_whitelist'] and \
+               slice['slice_id'] not in node['slice_ids_whitelist'] and \
+               not set(self.caller['site_ids']).intersection([node['site_id']]):
+                raise PLCInvalidArgument, "%s is not allowed on %s (not on the whitelist)" % \
+                  (slice['name'], node['hostname'])
             if slice['slice_id'] not in node['slice_ids']:
                 slice.add_node(node, commit = False)
 
         slice.sync()
 
             if slice['slice_id'] not in node['slice_ids']:
                 slice.add_node(node, commit = False)
 
         slice.sync()
 
-       self.object_ids = [node['node_id'] for node in nodes]
+        nodeids = [node['node_id'] for node in nodes]
+        self.event_objects = {'Node': nodeids,
+                              'Slice': [slice['slice_id']]}
+        self.message = 'Slice %d added to nodes %s' % (slice['slice_id'], nodeids)
+
+        PluginManager(self.api, auth).notify("slice.AddToNodes", self.event_objects)
 
         return 1
 
         return 1