merge changes from trunk in
[plcapi.git] / PLC / Methods / AddSliceTag.py
index 9a36711..b9f51bd 100644 (file)
@@ -1,4 +1,5 @@
 # $Id$
+# $URL$
 from PLC.Faults import *
 from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
@@ -55,18 +56,24 @@ class AddSliceTag(Method):
             raise PLCInvalidArgument, "No such tag type %r"%tag_type_id_or_name
         tag_type = tag_types[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 tag_type['min_role_id'] is not None and \
-               min(self.caller['role_ids']) > tag_type['min_role_id']:
+        if not isinstance(self.caller, Node):
+            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 tag_type['min_role_id'] is not None and \
+                       min(self.caller['role_ids']) > tag_type['min_role_id']:
+                    raise PLCPermissionDenied, "Not allowed to set the specified slice attribute"
+        else:
+            ### make node's min_role_id == PI min_role_id
+            node_role_id = 20
+            if tag_type['min_role_id'] is not None and node_role_id > tag_type['min_role_id']:
                 raise PLCPermissionDenied, "Not allowed to set the specified slice attribute"
-
+            
        # if initscript is specified, validate value
        if tag_type['tagname'] in ['initscript']:
            initscripts = InitScripts(self.api, {'enabled': True, 'name': value})
@@ -79,18 +86,33 @@ class AddSliceTag(Method):
         slice_tag['value'] = unicode(value)
 
         # Sliver attribute if node is specified
-        if node_id_or_hostname is not None:
-            nodes = Nodes(self.api, [node_id_or_hostname])
-            if not nodes:
-                raise PLCInvalidArgument, "No such node"
-            node = nodes[0]
+        if node_id_or_hostname is not None or isinstance(self.caller, Node):
+            node_id = None
+            if isinstance(self.caller, Node):
+                node = self.caller
+                node_id = node['node_id']
+
+            if node_id_or_hostname is not None:
+                nodes = Nodes(self.api, [node_id_or_hostname])
+                if not nodes:
+                    raise PLCInvalidArgument, "No such node"
+                node = nodes[0]
+                if node_id <> None and node_id <> node['node_id']:
+                    raise PLCPermissionDenied, "Not allowed to set another node's sliver attribute"
+                else:                    
+                    node_id = node['node_id']
             
-            if node['node_id'] not in slice['node_ids']:
-                raise PLCInvalidArgument, "Node not in the specified slice"
+            system_slice_tags = SliceTags(self.api, {'tagname': 'system', 'value': '1'}).dict('slice_id')
+            system_slice_ids = system_slice_tags.keys()
+           if slice['slice_id'] not in system_slice_ids and node_id not in slice['node_ids']:
+                raise PLCInvalidArgument, "AddSliceTag: slice %s not on specified node %s nor is it a system slice (%r)"%(slice['name'],node['hostname'],system_slice_ids)
             slice_tag['node_id'] = node['node_id']
 
        # Sliver attribute shared accross nodes if nodegroup is sepcified
        if nodegroup_id_or_name is not None:
+            if isinstance(self.caller, Node):
+                    raise PLCPermissionDenied, "Not allowed to set nodegroup slice attributes"
+                
            nodegroups = NodeGroups(self.api, [nodegroup_id_or_name])
            if not nodegroups:
                raise PLCInvalidArgument, "No such nodegroup %r"%nodegroup_id_or_name
@@ -103,6 +125,12 @@ class AddSliceTag(Method):
                                                             'tagname': tag_type['tagname'], 
                                                             'value': value})
         for slice_tag_check in slice_tags_check:
+            # do not compare between slice tag and sliver tag
+            if 'node_id' not in slice_tag and slice_tag_check['node_id'] is not None:
+                continue
+            # do not compare between sliver tag and slice tag
+            if 'node_id' in slice_tag and slice_tag['node_id'] is not None and slice_tag_check['node_id'] is None:
+                continue
             if 'node_id' in slice_tag and slice_tag['node_id'] == slice_tag_check['node_id']:
                raise PLCInvalidArgument, "Sliver attribute already exists"
            if 'nodegroup_id' in slice_tag and slice_tag['nodegroup_id'] == slice_tag_check['nodegroup_id']: