# xxx - don't expose yet in api interface and slices dont know how to use that yet
define_accessors(current_module, Slice, "Vref", "vref",
"slice/config", "vserver reference image type",
- get_roles=all_roles, set_roles=["admin"], expose_in_api=False)
+ get_roles=all_roles, set_roles=["admin"], expose_in_api=True)
# node architecture
'secondary_key' : 'ip'},
Slice: {'table_class' : Slices,
'joins_class': SliceTags, 'join_class': SliceTag,
- 'secondary_key':'login_base'},
+ 'secondary_key':'name'},
# Ilink : xxx
}
# accepts
get_accepts = [ Auth () ]
primary_key=objclass.primary_key
- try:
- secondary_key = taggable_classes[objclass]['secondary_key']
- get_accepts += [ Mixed (objclass.fields[primary_key], objclass.fields[secondary_key]) ]
- except:
- secondary_key = None
- get_accepts += [ objclass.fields[primary_key] ]
+ secondary_key = taggable_classes[objclass]['secondary_key']
+ get_accepts += [ Mixed (objclass.fields[primary_key], objclass.fields[secondary_key]) ]
# for set, idem set of arguments + one additional arg, the new value
set_accepts = get_accepts + [ Parameter (str,"New tag value") ]
filter={primary_key:id_or_name}
else:
filter={secondary_key:id_or_name}
- objs = table_class(self.api, filter,[primary_key])
+ objs = table_class(self.api, filter,[primary_key,secondary_key])
if not objs:
raise PLCInvalidArgument, "Cannot set tag on %s %r"%(objclass.__name__,id_or_name)
primary_id = objs[0][primary_key]
if joins:
join=joins[0]
join.delete()
+ # log it
+ self.event_objects= { objclass.__name__ : [primary_id] }
+ self.message=objclass.__name__
+ if secondary_key in objs[0]:
+ self.message += " %s "%objs[0][secondary_key]
+ else:
+ self.message += " %d "%objs[0][primary_key]
+ self.message += "updated"
# attach it
setattr (set_class,"call",set_call)
node['site_id'] = site['site_id']
node.sync()
- self.event_objects = {'Site': [site['site_id']],
- 'Node': [node['node_id']]}
- self.message = "Node %s created" % node['node_id']
-
for (tagname,value) in tags.iteritems():
# the tagtype instance is assumed to exist, just check that
if not TagTypes(self.api,{'tagname':tagname}):
else:
UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],value)
+ self.event_objects = {'Site': [site['site_id']],
+ 'Node': [node['node_id']]}
+ self.message = "Node %s created" % node['node_id']
+
return node['node_id']
import re
from PLC.Faults import *
+from PLC.Auth import Auth
from PLC.Method import Method
from PLC.Parameter import Parameter, Mixed
+from PLC.Table import Row
+
from PLC.Slices import Slice, Slices
-from PLC.Auth import Auth
from PLC.Sites import Site, Sites
+from PLC.TagTypes import TagTypes
+from PLC.SliceTags import SliceTags
+from PLC.Methods.AddSliceTag import AddSliceTag
+from PLC.Methods.UpdateSliceTag import UpdateSliceTag
-can_update = lambda (field, value): field in \
- ['name', 'instantiation', 'url', 'description', 'max_nodes']
+can_update = ['name', 'instantiation', 'url', 'description', 'max_nodes']
class AddSlice(Method):
"""
roles = ['admin', 'pi']
- slice_fields = dict(filter(can_update, Slice.fields.items()))
+ accepted_fields = Row.accepted_fields(can_update, [Slice.fields,Slice.tags])
accepts = [
Auth(),
- slice_fields
+ accepted_fields
]
returns = Parameter(int, 'New slice_id (> 0) if successful')
def call(self, auth, slice_fields):
- slice_fields = dict(filter(can_update, slice_fields.items()))
+
+ [native,tags,rejected]=Row.split_fields(slice_fields,[Slice.fields,Slice.tags])
+
+ if rejected:
+ raise PLCInvalidArgument, "Cannot add Slice with column(s) %r"%rejected
+
+ # Authenticated function
+ assert self.caller is not None
# 1. Lowercase.
# 2. Begins with login_base (letters or numbers).
if 'admin' not in self.caller['roles']:
if site['site_id'] not in self.caller['site_ids']:
- raise PLCPermissionDenied, "Slice prefix %s must be the same as the login_base of one of your sites"%login_base
+ raise PLCPermissionDenied, "Slice prefix %s must match one of your sites' login_base"%login_base
if len(site['slice_ids']) >= site['max_slices']:
- raise PLCInvalidArgument, "Site %s has reached (%d) its maximum allowable slice count (%d)"%(site['name'],
- len(site['slice_ids']),
- site['max_slices'])
-
+ raise PLCInvalidArgument, \
+ "Site %s has reached (%d) its maximum allowable slice count (%d)"%(site['name'],
+ len(site['slice_ids']),
+ site['max_slices'])
if not site['enabled']:
- raise PLCInvalidArgument, "Site %s is disabled can cannot create slices" % (site['name'])
+ raise PLCInvalidArgument, "Site %s is disabled and can cannot create slices" % (site['name'])
- slice = Slice(self.api, slice_fields)
+ slice = Slice(self.api, native)
slice['creator_person_id'] = self.caller['person_id']
slice['site_id'] = site['site_id']
slice.sync()
+ for (tagname,value) in tags.iteritems():
+ # the tagtype instance is assumed to exist, just check that
+ if not TagTypes(self.api,{'tagname':tagname}):
+ raise PLCInvalidArgument,"No such TagType %s"%tagname
+ slice_tags=SliceTags(self.api,{'tagname':tagname,'slice_id':slice['slice_id']})
+ if not slice_tags:
+ AddSliceTag(self.api).__call__(auth,slice['slice_id'],tagname,value)
+ else:
+ UpdateSliceTag(self.api).__call__(auth,slice_tags[0]['slice_tag_id'],value)
+
self.event_objects = {'Slice': [slice['slice_id']]}
+ self.message = "Slice %d created" % slice['slice_id']
return slice['slice_id']
UpdateInterfaceTag(self.api).__call__(auth,interface_tags[0]['interface_tag_id'],value)
self.event_objects = {'Interface': [interface['interface_id']]}
- self.message = "Interface %d updated: %s " % \
- (interface['interface_id'], ", ".join(interface_fields.keys()))
+ if 'ip' in interface:
+ self.message = "Interface %s updated"%interface['ip']
+ else:
+ self.message = "Interface %d updated"%interface['interface_id']
+ self.message += "[%s]." % ", ".join(interface_fields.keys())
return 1
# Logging variables
self.event_objects = {'Node': [node['node_id']]}
- self.message = 'Node %d updated: %s.' % \
- (node['node_id'], ", ".join(node_fields.keys()))
+ if 'hostname' in node:
+ self.message = 'Node %s updated'%node['hostname']
+ else:
+ self.message = 'Node %d updated'%node['node_id']
+ self.message += " [%s]." % (", ".join(node_fields.keys()),)
if 'boot_state' in node_fields.keys():
- self.message += ' boot_state updated to %s' % node_fields['boot_state']
+ self.message += ' boot_state updated to %s' % node_fields['boot_state']
return 1
from PLC.Faults import *
from PLC.Method import Method
from PLC.Parameter import Parameter, Mixed
-from PLC.Slices import Slice, Slices
+from PLC.Table import Row
from PLC.Auth import Auth
-from PLC.Sites import Site, Sites
-related_fields = Slice.related_fields.keys()
-can_update = lambda (field, value): field in \
- ['instantiation', 'url', 'description', 'max_nodes', 'expires'] + \
- related_fields
+from PLC.Slices import Slice, Slices
+from PLC.Sites import Site, Sites
+from PLC.TagTypes import TagTypes
+from PLC.SliceTags import SliceTags
+from PLC.Methods.AddSliceTag import AddSliceTag
+from PLC.Methods.UpdateSliceTag import UpdateSliceTag
+can_update = ['instantiation', 'url', 'description', 'max_nodes', 'expires'] + \
+ Slice.related_fields.keys()
class UpdateSlice(Method):
"""
roles = ['admin', 'pi', 'user']
- slice_fields = dict(filter(can_update, Slice.fields.items() + Slice.related_fields.items()))
+ slice_fields = Row.accepted_fields(can_update, [Slice.fields,Slice.related_fields,Slice.tags])
accepts = [
Auth(),
returns = Parameter(int, '1 if successful')
def call(self, auth, slice_id_or_name, slice_fields):
- slice_fields = dict(filter(can_update, slice_fields.items()))
-
+
+ # split provided fields
+ [native,related,tags,rejected] = Row.split_fields(slice_fields,[Slice.fields,Slice.related_fields,Slice.tags])
+
+ if rejected:
+ raise PLCInvalidArgument, "Cannot update Node column(s) %r"%rejected
+
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]
if slice['peer_id'] is not None:
raise PLCInvalidArgument, "Not a local slice"
+ # Authenticated function
+ assert self.caller is not None
+
if 'admin' not in self.caller['roles']:
if self.caller['person_id'] in slice['person_ids']:
pass
raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
# Renewing
+ renewing=False
if 'expires' in slice_fields and slice_fields['expires'] > slice['expires']:
sites = Sites(self.api, [slice['site_id']])
assert sites
site = sites[0]
- if site['max_slices'] < 0:
+ if site['max_slices'] <= 0:
raise PLCInvalidArgument, "Slice creation and renewal have been disabled for the site"
# Maximum expiration date is 8 weeks from now
if 'url' not in slice_fields or slice_fields['url'] is None or \
not slice_fields['url'].strip():
raise PLCInvalidArgument, "Cannot renew a slice with an empty description or URL"
+ renewing=True
if 'max_nodes' in slice_fields and slice_fields['max_nodes'] != slice['max_nodes']:
if 'admin' not in self.caller['roles'] and \
raise PLCInvalidArgument, "Only admins and PIs may update max_nodes"
# Make requested associations
- for field in related_fields:
- if field in slice_fields:
- slice.associate(auth, field, slice_fields[field])
- slice_fields.pop(field)
+ for (k,v) in related.iteritems():
+ slice.associate(auth,k,v)
slice.update(slice_fields)
- slice.sync()
+ slice.sync(commit=True)
+
+ for (tagname,value) in tags.iteritems():
+ # the tagtype instance is assumed to exist, just check that
+ if not TagTypes(self.api,{'tagname':tagname}):
+ raise PLCInvalidArgument,"No such TagType %s"%tagname
+ slice_tags=SliceTags(self.api,{'tagname':tagname,'slice_id':slice['slice_id']})
+ if not slice_tags:
+ AddSliceTag(self.api).__call__(auth,slice['slice_id'],tagname,value)
+ else:
+ UpdateSliceTag(self.api).__call__(auth,slice_tags[0]['slice_tag_id'],value)
self.event_objects = {'Slice': [slice['slice_id']]}
+ if 'name' in slice:
+ self.message='Slice %s updated'%slice['name']
+ else:
+ self.message='Slice %d updated'%slice['slice_id']
+ if renewing:
+ self.message += ' renewed until %s'%time.strftime('%Y-%m-%d:%H:%M',localtime(slice['expires']))
return 1
from PLC.Parameter import Parameter
from PLC.Filter import Filter
from PLC.Table import Row, Table
+# seems to cause import loops
+#from PLC.Slices import Slice, Slices
+from PLC.Nodes import Node, Nodes
+from PLC.NodeGroups import NodeGroup, NodeGroups
from PLC.TagTypes import TagType, TagTypes
class SliceTag(Row):
table_name = 'slice_tag'
primary_key = 'slice_tag_id'
fields = {
- 'slice_tag_id': Parameter(int, "Slice attribute identifier"),
+ 'slice_tag_id': Parameter(int, "Slice tag identifier"),
'slice_id': Parameter(int, "Slice identifier"),
- 'node_id': Parameter(int, "Node identifier, if a sliver attribute"),
- 'nodegroup_id': Parameter(int, "Nodegroup identifier, if a sliver attribute"),
+ 'name': Parameter(str, "Slice name"),
+ 'node_id': Node.fields['node_id'],
+ 'nodegroup_id': NodeGroup.fields['nodegroup_id'],
'tag_type_id': TagType.fields['tag_type_id'],
'tagname': TagType.fields['tagname'],
'description': TagType.fields['description'],
def __init__(self, api, slice_filter = None, columns = None, expires = int(time.time())):
Table.__init__(self, api, Slice, columns)
- sql = "SELECT %s FROM view_slices WHERE is_deleted IS False" % \
- ", ".join(self.columns)
+ # the view that we're selecting upon: start with view_slices
+ view = "view_slices"
+ # as many left joins as requested tags
+ for tagname in self.tag_columns:
+ view= "%s left join %s using (%s)"%(view,Slice.tagvalue_view_name(tagname),
+ Slice.primary_key)
+
+ sql = "SELECT %s FROM %s WHERE is_deleted IS False" % \
+ (", ".join(self.columns.keys()+self.tag_columns.keys()),view)
if expires is not None:
if expires >= 0:
tag_types.description,
tag_types.category,
tag_types.min_role_id,
-slice_tag.value
+slice_tag.value,
+slices.name
FROM slice_tag
-INNER JOIN tag_types USING (tag_type_id);
+INNER JOIN tag_types USING (tag_type_id)
+INNER JOIN slices USING (slice_id);
--------------------------------------------------------------------------------
CREATE OR REPLACE VIEW view_sessions AS