-# $Id$
+#
+# Thierry Parmentelat - INRIA
+#
from PLC.Faults import *
from PLC.Method import Method
from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
from PLC.SliceTags import SliceTag, SliceTags
from PLC.Nodes import Node
from PLC.Slices import Slice, Slices
from PLC.InitScripts import InitScript, InitScripts
-from PLC.Auth import Auth
+
+from PLC.AuthorizeHelpers import AuthorizeHelpers
class UpdateSliceTag(Method):
"""
accepts = [
Auth(),
SliceTag.fields['slice_tag_id'],
- Mixed(SliceTag.fields['value'],
+ Mixed(SliceTag.fields['value'],
InitScript.fields['name'])
]
slices = Slices(self.api, [slice_tag['slice_id']])
if not slices:
- raise PLCInvalidArgument, "No such slice"
+ raise PLCInvalidArgument, "No such slice %d"%slice_tag['slice_id']
slice = slices[0]
assert slice_tag['slice_tag_id'] in slice['slice_tag_ids']
- 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 slice_tag['min_role_id'] is not None and \
- min(self.caller['role_ids']) > slice_tag['min_role_id']:
- raise PLCPermissionDenied, "Not allowed to update the specified attribute"
+ # check authorizations
+ node_id_or_hostname=slice_tag['node_id']
+ nodegroup_id_or_name=slice_tag['nodegroup_id']
+ granted=False
+ if 'admin' in self.caller['roles']:
+ granted=True
+ # does caller have right role(s) ? this knows how to deal with self.caller being a node
+ elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
+ granted=False
+ # node callers: check the node is in the slice
+ elif isinstance(self.caller, Node):
+ # nodes can only set their own sliver tags
+ if node_id_or_hostname is None:
+ granted=False
+ elif not AuthorizeHelpers.node_match_id (self.api, self.caller, node_id_or_hostname):
+ granted=False
+ elif not AuthorizeHelpers.node_in_slice (self.api, self.caller, slice):
+ granted=False
+ # caller is a non-admin person
else:
- ### make node's min_role_id == PI min_role_id
- node_role_id = 20
- if slice_tag['min_role_id'] is not None and node_role_id > slice_tag['min_role_id']:
- raise PLCPermissionDenied, "Not allowed to update the specified slice attribute"
-
- if slice_tag['tagname'] in ['initscript']:
+ # only admins can handle slice tags on a nodegroup
+ if nodegroup_id_or_name:
+ raise PLCPermissionDenied, "%s, cannot set slice tag %s on nodegroup - restricted to admins"%\
+ (self.name,tag_type['tagname'])
+ # if a node is specified it is expected to be in the slice
+ if node_id_or_hostname:
+ if not AuthorizeHelpers.node_id_in_slice (self.api, node_id_or_hostname, slice):
+ raise PLCPermissionDenied, "%s, node must be in slice when setting sliver tag"
+ # try all roles to find a match - tech are ignored b/c not in AddSliceTag.roles anyways
+ for role in AuthorizeHelpers.person_tag_type_common_roles(self.api,self.caller,tag_type):
+ # regular users need to be in the slice
+ if role=='user':
+ if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice):
+ granted=True ; break
+ # for convenience, pi's can tweak all the slices in their site
+ elif role=='pi':
+ if AuthorizeHelpers.slice_belongs_to_pi (self.api, slice, self.caller):
+ granted=True ; break
+ if not granted:
+ raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
+
+ if slice_tag['tagname'] in ['initscript']:
initscripts = InitScripts(self.api, {'enabled': True, 'name': value})
if not initscripts:
- raise PLCInvalidArgument, "No such plc initscript"
+ raise PLCInvalidArgument, "No such plc initscript"
slice_tag['value'] = unicode(value)
slice_tag.sync()
- self.event_objects = {'SliceTag': [slice_tag['slice_tag_id']]}
+ self.event_objects = {'SliceTag': [slice_tag['slice_tag_id']]}
return 1