class InitScripts(Table):
"""
- Representation of the initscipts table in the database.
+ Representation of the initscripts table in the database.
"""
def __init__(self, api, initscript_filter = None, columns = None):
Auth(),
ConfFile.fields['conf_file_id'],
Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name'])
+ NodeGroup.fields['groupname'])
]
returns = Parameter(int, '1 if successful')
from PLC.NodeGroups import NodeGroup, NodeGroups
from PLC.Auth import Auth
-can_update = lambda (field, value): field in \
- ['name', 'description']
+can_update = lambda (field, value): field in NodeGroup.fields.keys() and field != NodeGroup.primary_field
class AddNodeGroup(Method):
"""
def call(self, auth, nodegroup_fields):
- nodegroup_fields = dict(filter(can_update, nodegroup_fields.items()))
+ nodegroup_fields = dict([f for f in nodegroup_fields.items() if can_update(f)])
nodegroup = NodeGroup(self.api, nodegroup_fields)
nodegroup.sync()
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+from PLC.NodeTags import NodeTag, NodeTags
+from PLC.Nodes import Node, Nodes
+
+from PLC.Nodes import Nodes
+from PLC.Sites import Sites
+
+class AddNodeTag(Method):
+ """
+ Sets the specified tag for the specified node
+ to the specified value.
+
+ In general only tech(s), PI(s) and of course admin(s) are allowed to
+ do the change, but this is defined in the node tag type object.
+
+ Returns the new node_tag_id (> 0) if successful, faults
+ otherwise.
+ """
+
+ roles = ['admin', 'pi', 'tech', 'user']
+
+ accepts = [
+ Auth(),
+ # no other way to refer to a node
+ NodeTag.fields['node_id'],
+ Mixed(NodeTagType.fields['node_tag_type_id'],
+ NodeTagType.fields['name']),
+ NodeTag.fields['value'],
+ ]
+
+ returns = Parameter(int, 'New node_tag_id (> 0) if successful')
+
+ object_type = 'Node'
+
+
+ def call(self, auth, node_id, node_tag_type_id_or_name, value):
+ nodes = Nodes(self.api, [node_id])
+ if not nodes:
+ raise PLCInvalidArgument, "No such node %r"%node_id
+ node = nodes[0]
+
+ node_tag_types = NodeTagTypes(self.api, [node_tag_type_id_or_name])
+ if not node_tag_types:
+ raise PLCInvalidArgument, "No such node tag type %r"%node_tag_type_id_or_name
+ node_tag_type = node_tag_types[0]
+
+ # checks for existence - does not allow several different tags
+ conflicts = NodeTags(self.api,
+ {'node_id':node['node_id'],
+ 'node_tag_type_id':node_tag_type['node_tag_type_id']})
+
+ if len(conflicts) :
+ raise PLCInvalidArgument, "Node %d already has tag %d"%(node['node_id'],
+ node_tag_type['node_tag_type_id'])
+
+ # check permission : it not admin, is the user affiliated with the right site
+ if 'admin' not in self.caller['roles']:
+ # locate node
+ node = Nodes (self.api,[node['node_id']])[0]
+ # locate site
+ site = Sites (self.api, [node['site_id']])[0]
+ # check caller is affiliated with this site
+ if self.caller['person_id'] not in site['person_ids']:
+ raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site']
+
+ required_min_role = node_tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified node tag, requires role %d",required_min_role
+
+ node_tag = NodeTag(self.api)
+ node_tag['node_id'] = node['node_id']
+ node_tag['node_tag_type_id'] = node_tag_type['node_tag_type_id']
+ node_tag['value'] = value
+
+ node_tag.sync()
+ self.object_ids = [node_tag['node_tag_id']]
+
+ return node_tag['node_tag_id']
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+ ['name', 'description', 'category', 'min_role_id']
+
+class AddNodeTagType(Method):
+ """
+ Adds a new type of node tag.
+ Any fields specified are used, otherwise defaults are used.
+
+ Returns the new node_tag_id (> 0) if successful,
+ faults otherwise.
+ """
+
+ roles = ['admin']
+
+ node_tag_type_fields = dict(filter(can_update, NodeTagType.fields.items()))
+
+ accepts = [
+ Auth(),
+ node_tag_type_fields
+ ]
+
+ returns = Parameter(int, 'New node_tag_id (> 0) if successful')
+
+
+ def call(self, auth, node_tag_type_fields):
+ node_tag_type_fields = dict(filter(can_update, node_tag_type_fields.items()))
+ node_tag_type = NodeTagType(self.api, node_tag_type_fields)
+ node_tag_type.sync()
+
+ self.object_ids = [node_tag_type['node_tag_type_id']]
+
+ return node_tag_type['node_tag_type_id']
Node.fields['hostname'],
None),
Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name'])
+ NodeGroup.fields['groupname'])
]
returns = Parameter(int, 'New slice_attribute_id (> 0) if successful')
Auth(),
ConfFile.fields['conf_file_id'],
Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name'])
+ NodeGroup.fields['groupname'])
]
returns = Parameter(int, '1 if successful')
"""
Deletes an existing initscript.
- Returns 1 if successfuli, faults otherwise.
+ Returns 1 if successful, faults otherwise.
"""
roles = ['admin']
accepts = [
Auth(),
- InitScript.fields['initscript_id']
+ Mixed(InitScript.fields['initscript_id'],
+ InitScript.fields['name']),
]
returns = Parameter(int, '1 if successful')
- def call(self, auth, initscript_id):
- initscripts = InitScripts(self.api, [initscript_id])
+ def call(self, auth, initscript_id_or_name):
+ initscripts = InitScripts(self.api, [initscript_id_or_name])
if not initscripts:
raise PLCInvalidArgument, "No such initscript"
accepts = [
Auth(),
Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name'])
+ NodeGroup.fields['groupname'])
]
returns = Parameter(int, '1 if successful')
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.NodeTags import NodeTag, NodeTags
+from PLC.Nodes import Node, Nodes
+
+from PLC.Nodes import Node, Nodes
+from PLC.Sites import Site, Sites
+
+class DeleteNodeTag(Method):
+ """
+ Deletes the specified node tag
+
+ Attributes may require the caller to have a particular role in order
+ to be deleted, depending on the related node tag type.
+ Admins may delete attributes of any slice or sliver.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin', 'pi', 'user']
+
+ accepts = [
+ Auth(),
+ NodeTag.fields['node_tag_id']
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+ object_type = 'Node'
+
+
+ def call(self, auth, node_tag_id):
+ node_tags = NodeTags(self.api, [node_tag_id])
+ if not node_tags:
+ raise PLCInvalidArgument, "No such node tag %r"%node_tag_id
+ node_tag = node_tags[0]
+
+ ### reproducing a check from UpdateSliceAttribute, looks dumb though
+ nodes = Nodes(self.api, [node_tag['node_id']])
+ if not nodes:
+ raise PLCInvalidArgument, "No such node %r"%node_tag['node_id']
+ node = nodes[0]
+
+ assert node_tag['node_tag_id'] in node['tag_ids']
+
+ # check permission : it not admin, is the user affiliated with the right site
+ if 'admin' not in self.caller['roles']:
+ # locate node
+ node = Nodes (self.api,[node['node_id']])[0]
+ # locate site
+ site = Sites (self.api, [node['site_id']])[0]
+ # check caller is affiliated with this site
+ if self.caller['person_id'] not in site['person_ids']:
+ raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site']
+
+ required_min_role = node_tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified node tag, requires role %d",required_min_role
+
+ node_tag.delete()
+ self.object_ids = [node_tag['node_tag_id']]
+
+ return 1
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+from PLC.Auth import Auth
+
+class DeleteNodeTagType(Method):
+ """
+ Deletes the specified node tag type.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin']
+
+ accepts = [
+ Auth(),
+ Mixed(NodeTagType.fields['node_tag_type_id'],
+ NodeTagType.fields['name']),
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+
+ def call(self, auth, node_tag_type_id_or_name):
+ node_tag_types = NodeTagTypes(self.api, [node_tag_type_id_or_name])
+ if not node_tag_types:
+ raise PLCInvalidArgument, "No such node tag type"
+ node_tag_type = node_tag_types[0]
+
+ node_tag_type.delete()
+ self.object_ids = [node_tag_type['node_tag_type_id']]
+
+ return 1
from PLC.Method import Method
from PLC.Parameter import Parameter, Mixed
from PLC.Filter import Filter
-from PLC.Persons import Person, Persons
from PLC.Auth import Auth
from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings
accepts = [
Auth(),
Mixed([Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name'])],
+ NodeGroup.fields['groupname'])],
Filter(NodeGroup.fields)),
Parameter([str], "List of fields to return", nullok = True)
]
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Filter import Filter
+from PLC.Auth import Auth
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+
+class GetNodeTagTypes(Method):
+ """
+ Returns an array of structs containing details about
+ node tag types.
+
+ The usual filtering scheme applies on this method.
+ """
+
+ roles = ['admin', 'pi', 'user', 'tech', 'node']
+
+ accepts = [
+ Auth(),
+ Mixed([Mixed(NodeTagType.fields['node_tag_type_id'],
+ NodeTagType.fields['name'])],
+ Filter(NodeTagType.fields)),
+ Parameter([str], "List of fields to return", nullok = True)
+ ]
+
+ returns = [NodeTagType.fields]
+
+ def call(self, auth, node_tag_type_filter = None, return_fields = None):
+ return NodeTagTypes(self.api, node_tag_type_filter, return_fields)
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Filter import Filter
+from PLC.Auth import Auth
+
+from PLC.NodeTags import NodeTag, NodeTags
+from PLC.Sites import Site, Sites
+from PLC.Nodes import Node, Nodes
+
+class GetNodeTags(Method):
+ """
+ Returns an array of structs containing details about
+ nodes and related tags.
+
+ If node_tag_filter is specified and is an array of
+ node tag identifiers, only node tags matching
+ the filter will be returned. If return_fields is specified, only
+ the specified details will be returned.
+ """
+
+ roles = ['admin', 'pi', 'user', 'node']
+
+ accepts = [
+ Auth(),
+ Mixed([NodeTag.fields['node_tag_id']],
+ Parameter(int,"Node tag id"),
+ Filter(NodeTag.fields)),
+ Parameter([str], "List of fields to return", nullok = True)
+ ]
+
+ returns = [NodeTag.fields]
+
+
+ def call(self, auth, node_tag_filter = None, return_fields = None):
+
+ node_tags = NodeTags(self.api, node_tag_filter, return_fields)
+
+ return node_tags
'node_id': Node.fields['node_id'],
'hostname': Node.fields['hostname'],
'networks': [Interface.fields],
- 'groups': [NodeGroup.fields['name']],
+ 'groups': [NodeGroup.fields['groupname']],
'conf_files': [ConfFile.fields],
'initscripts': [InitScript.fields],
'slivers': [{
accepts = [
Auth(),
Mixed(NodeGroup.fields['nodegroup_id'],
- NodeGroup.fields['name']),
+ NodeGroup.fields['groupname']),
nodegroup_fields
]
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.NodeTags import NodeTag, NodeTags
+from PLC.Nodes import Node, Nodes
+
+from PLC.Nodes import Nodes
+from PLC.Sites import Sites
+
+class UpdateNodeTag(Method):
+ """
+ Updates the value of an existing node tag
+
+ Access rights depend on the node tag type.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin', 'pi', 'tech', 'user']
+
+ accepts = [
+ Auth(),
+ NodeTag.fields['node_tag_id'],
+ NodeTag.fields['value']
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+ object_type = 'Node'
+
+ def call(self, auth, node_tag_id, value):
+ node_tags = NodeTags(self.api, [node_tag_id])
+ if not node_tags:
+ raise PLCInvalidArgument, "No such node tag %r"%node_tag_id
+ node_tag = node_tags[0]
+
+ ### reproducing a check from UpdateSliceAttribute, looks dumb though
+ nodes = Nodes(self.api, [node_tag['node_id']])
+ if not nodes:
+ raise PLCInvalidArgument, "No such node %r"%node_tag['node_id']
+ node = nodes[0]
+
+ assert node_tag['node_tag_id'] in node['tag_ids']
+
+ # check permission : it not admin, is the user affiliated with the right site
+ if 'admin' not in self.caller['roles']:
+ # locate node
+ node = Nodes (self.api,[node['node_id']])[0]
+ # locate site
+ site = Sites (self.api, [node['site_id']])[0]
+ # check caller is affiliated with this site
+ if self.caller['person_id'] not in site['person_ids']:
+ raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site']
+
+ required_min_role = node_tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified node tag, requires role %d",required_min_role
+
+ node_tag['value'] = value
+ node_tag.sync()
+
+ self.object_ids = [node_tag['node_tag_id']]
+ return 1
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+from PLC.Auth import Auth
+
+can_update = lambda (field, value): field in \
+ ['name', 'description', 'category', 'min_role_id']
+
+class UpdateNodeTagType(Method):
+ """
+ Updates the parameters of an existing tag type
+ with the values in node_tag_type_fields.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin']
+
+ node_tag_type_fields = dict(filter(can_update, NodeTagType.fields.items()))
+
+ accepts = [
+ Auth(),
+ Mixed(NodeTagType.fields['node_tag_type_id'],
+ NodeTagType.fields['name']),
+ node_tag_type_fields
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+ def call(self, auth, node_tag_type_id_or_name, node_tag_type_fields):
+ node_tag_type_fields = dict(filter(can_update, node_tag_type_fields.items()))
+
+ node_tag_types = NodeTagTypes(self.api, [node_tag_type_id_or_name])
+ if not node_tag_types:
+ raise PLCInvalidArgument, "No such tag type"
+ node_tag_type = node_tag_types[0]
+
+ node_tag_type.update(node_tag_type_fields)
+ node_tag_type.sync()
+ self.object_ids = [node_tag_type['node_tag_type_id']]
+
+ return 1
AddNetworkType
AddNode
AddNodeGroup
+AddNodeTag
+AddNodeTagType
AddNodeToPCU
AddPCU
AddPCUProtocolType
DeleteNode
DeleteNodeFromPCU
DeleteNodeGroup
+DeleteNodeTag
+DeleteNodeTagType
DeletePCU
DeletePCUProtocolType
DeletePCUType
GetNetworkMethods
GetNetworkTypes
GetNodeGroups
+GetNodeTagTypes
+GetNodeTags
GetNodes
GetPCUProtocolTypes
GetPCUTypes
UpdateMessage
UpdateNode
UpdateNodeGroup
+UpdateNodeTag
+UpdateNodeTagType
UpdatePCU
UpdatePCUProtocolType
UpdatePCUType
table_name = 'nodegroups'
primary_key = 'nodegroup_id'
- join_tables = ['nodegroup_node', 'conf_file_nodegroup']
+ join_tables = ['conf_file_nodegroup']
+ primary_field = 'nodegroup_id'
fields = {
'nodegroup_id': Parameter(int, "Node group identifier"),
- 'name': Parameter(str, "Node group name", max = 50),
- 'tag_name' : Parameter(str, "Tag name that the nodegroup definition is based upon"),
- 'tag_value' : Parameter(str, "value that the nodegroup definition is based upon"),
-# 'node_ids': Parameter([int], "List of nodes in this node group"),
-# 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
+ 'groupname': Parameter(str, "Node group name", max = 50),
+ 'node_tag_type_id': Parameter (int, "Node tag type id"),
+ 'value' : Parameter(str, "value that the nodegroup definition is based upon"),
}
related_fields = {
- 'conf_files': [Parameter(int, "ConfFile identifier")],
+ 'name' : Parameter(str, "Tag name that the nodegroup definition is based upon"),
+ 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
}
def validate_name(self, name):
stale_conf_files = set(self['conf_file_ids']).difference(conf_file_ids)
for new_conf_file in new_conf_files:
- AddConfFileToNodeGroup.__call__(AddConfFileToNodeGroup(self.api), auth, new_conf_file, self['nodegroup_id'])
+ AddConfFileToNodeGroup.__call__(AddConfFileToNodeGroup(self.api),
+ auth, new_conf_file, self['nodegroup_id'])
for stale_conf_file in stale_conf_files:
- DeleteConfFileFromNodeGroup.__call__(DeleteConfFileFromNodeGroup(self.api), auth, stale_conf_file, self['nodegroup_id'])
+ DeleteConfFileFromNodeGroup.__call__(DeleteConfFileFromNodeGroup(self.api),
+ auth, stale_conf_file, self['nodegroup_id'])
class NodeGroups(Table):
# Separate the list into integers and strings
ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter)
strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter)
- nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'name': strs})
+ nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'groupname': strs})
sql += " AND (%s) %s" % nodegroup_filter.sql(api, "OR")
elif isinstance(nodegroup_filter, dict):
nodegroup_filter = Filter(NodeGroup.fields, nodegroup_filter)
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from types import StringTypes
+
+from PLC.Faults import *
+from PLC.Parameter import Parameter
+from PLC.Filter import Filter
+from PLC.Table import Row, Table
+from PLC.Roles import Role, Roles
+
+class NodeTagType (Row):
+
+ """
+ Representation of a row in the node_tag_types table.
+ """
+
+ table_name = 'node_tag_types'
+ primary_key = 'node_tag_type_id'
+ join_tables = ['node_tag']
+ fields = {
+ 'node_tag_type_id': Parameter(int, "Node tag type identifier"),
+ 'name': Parameter(str, "Node tag type name", max = 100),
+ 'description': Parameter(str, "Node tag type description", max = 254),
+ 'category' : Parameter (str, "Node tag category", max=64),
+ 'min_role_id': Parameter(int, "Minimum (least powerful) role that can set or change this attribute"),
+ }
+
+ # for Cache
+ class_key = 'name'
+ foreign_fields = ['category','description','min_role_id']
+ foreign_xrefs = []
+
+ def validate_name(self, name):
+ if not len(name):
+ raise PLCInvalidArgument, "node tag type name must be set"
+
+ conflicts = NodeTagTypes(self.api, [name])
+ for tag_type in conflicts:
+ if 'node_tag_type_id' not in self or \
+ self['node_tag_type_id'] != tag_type['node_tag_type_id']:
+ raise PLCInvalidArgument, "node tag type name already in use"
+
+ return name
+
+ def validate_min_role_id(self, role_id):
+ roles = [row['role_id'] for row in Roles(self.api)]
+ if role_id not in roles:
+ raise PLCInvalidArgument, "Invalid role"
+
+ return role_id
+
+class NodeTagTypes(Table):
+ """
+ Representation of row(s) from the node_tag_types table
+ in the database.
+ """
+
+ def __init__(self, api, node_tag_type_filter = None, columns = None):
+ Table.__init__(self, api, NodeTagType, columns)
+
+ sql = "SELECT %s FROM node_tag_types WHERE True" % \
+ ", ".join(self.columns)
+
+ if node_tag_type_filter is not None:
+ if isinstance(node_tag_type_filter, (list, tuple, set)):
+ # Separate the list into integers and strings
+ ints = filter(lambda x: isinstance(x, (int, long)), node_tag_type_filter)
+ strs = filter(lambda x: isinstance(x, StringTypes), node_tag_type_filter)
+ node_tag_type_filter = Filter(NodeTagType.fields, {'node_tag_type_id': ints, 'name': strs})
+ sql += " AND (%s) %s" % node_tag_type_filter.sql(api, "OR")
+ elif isinstance(node_tag_type_filter, dict):
+ node_tag_type_filter = Filter(NodeTagType.fields, node_tag_type_filter)
+ sql += " AND (%s) %s" % node_tag_type_filter.sql(api, "AND")
+ elif isinstance (node_tag_type_filter, StringTypes):
+ node_tag_type_filter = Filter(NodeTagType.fields, {'name':[node_tag_type_filter]})
+ sql += " AND (%s) %s" % node_tag_type_filter.sql(api, "AND")
+ else:
+ raise PLCInvalidArgument, "Wrong node tag type filter %r"%node_tag_type_filter
+
+ self.selectall(sql)
--- /dev/null
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 9423 $
+#
+from PLC.Faults import *
+from PLC.Parameter import Parameter
+from PLC.Filter import Filter
+from PLC.Table import Row, Table
+from PLC.NodeTagTypes import NodeTagType, NodeTagTypes
+
+class NodeTag(Row):
+ """
+ Representation of a row in the node_tag.
+ To use, instantiate with a dict of values.
+ """
+
+ table_name = 'node_tag'
+ primary_key = 'node_tag_id'
+ fields = {
+ 'node_tag_id': Parameter(int, "Node tag identifier"),
+ 'node_id': Parameter(int, "Node identifier"),
+ 'node_tag_type_id': NodeTagType.fields['node_tag_type_id'],
+ 'name': NodeTagType.fields['name'],
+ 'description': NodeTagType.fields['description'],
+ 'category': NodeTagType.fields['category'],
+ 'min_role_id': NodeTagType.fields['min_role_id'],
+ 'value': Parameter(str, "Node tag value"),
+ ### relations
+
+ }
+
+class NodeTags(Table):
+ """
+ Representation of row(s) from the node_tag table in the
+ database.
+ """
+
+ def __init__(self, api, node_tag_filter = None, columns = None):
+ Table.__init__(self, api, NodeTag, columns)
+
+ sql = "SELECT %s FROM view_node_tags WHERE True" % \
+ ", ".join(self.columns)
+
+ if node_tag_filter is not None:
+ if isinstance(node_tag_filter, (list, tuple, set)):
+ node_tag_filter = Filter(NodeTag.fields, {'node_tag_id': node_tag_filter})
+ elif isinstance(node_tag_filter, dict):
+ node_tag_filter = Filter(NodeTag.fields, node_tag_filter)
+ elif isinstance(node_tag_filter, int):
+ node_tag_filter = Filter(NodeTag.fields, {'node_tag_id': [node_tag_filter]})
+ else:
+ raise PLCInvalidArgument, "Wrong node tag filter %r"%node_tag_filter
+ sql += " AND (%s) %s" % node_tag_filter.sql(api)
+
+
+ self.selectall(sql)
table_name = 'nodes'
primary_key = 'node_id'
# Thierry -- we use delete on interfaces so the related InterfaceSettings get deleted too
- join_tables = ['nodegroup_node', 'conf_file_node', 'pcu_node', 'slice_node', 'slice_attribute', 'node_session', 'peer_node','node_slice_whitelist']
+ join_tables = [ 'slice_node', 'peer_node', 'slice_attribute',
+ 'node_session', 'node_slice_whitelist',
+ 'node_tag', 'conf_file_node', 'pcu_node', ]
fields = {
'node_id': Parameter(int, "Node identifier"),
'hostname': Parameter(str, "Fully qualified hostname", max = 255),
def random_nodegroup():
return {
- 'name': randstr(50),
- 'description': randstr(200),
+ 'groupname': randstr(50),
+# 'description': randstr(200),
}
def random_node(boot_states):
NetworkMethods
NetworkTypes
NodeGroups
+NodeTagTypes
+NodeTags
Nodes
PCUProtocolTypes
PCUTypes
#!/bin/bash
+COMMAND=$(basename $0)
+BASENAME=$(basename $COMMAND .sh)
+DIRNAME=$(dirname $0)
+
. /etc/planetlab/plc_config
PLC_DB_USER
function migration_script () {
- cat <<EOF
-
--- $Id$
---
--- this is the script to migrate from 4.2 to 5.0
---
-
-----------------------------------------
--- rename nodenetwork into interface
-----------------------------------------
-
-ALTER TABLE nodenetworks RENAME TO interfaces;
-ALTER TABLE interfaces RENAME COLUMN nodenetwork_id TO interface_id;
-
-ALTER INDEX nodenetworks_node_id_idx RENAME TO interfaces_node_id_idx;
-
-ALTER TABLE nodenetwork_setting_types RENAME TO interface_setting_types;
-ALTER TABLE interface_setting_types RENAME COLUMN nodenetwork_setting_type_id TO interface_setting_type_id;
-
-ALTER TABLE nodenetwork_setting RENAME TO interface_setting;
-
--- views
-ALTER TABLE nodenetworks_ordered RENAME TO interfaces_ordered;
-ALTER TABLE interfaces_ordered RENAME COLUMN nodenetwork_id TO interface_id;
-
-ALTER TABLE node_nodenetworks RENAME TO node_interfaces;
-ALTER TABLE node_interfaces RENAME COLUMN nodenetwork_ids TO interface_ids;
-
-ALTER TABLE nodenetwork_settings RENAME TO interface_settings;
-ALTER TABLE interface_settings RENAME COLUMN nodenetwork_id TO interface_id;
-ALTER TABLE interface_settings RENAME COLUMN nodenetwork_setting_ids TO setting_ids;
-
-ALTER TABLE view_nodenetwork_settings RENAME TO view_interface_settings;
-ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_setting_id TO interface_setting_id;
-ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_id TO interface_id;
-ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_setting_type_id TO interface_setting_type_id;
-
-ALTER TABLE view_nodenetworks RENAME TO view_interfaces;
-ALTER TABLE view_interfaces RENAME COLUMN nodenetwork_id TO interface_id;
-ALTER TABLE view_interfaces RENAME COLUMN nodenetwork_setting_ids TO setting_ids;
-
-ALTER TABLE view_nodes RENAME COLUMN nodenetwork_ids TO interface_ids;
-
-----------------------------------------
--- node tags
-----------------------------------------
-CREATE TABLE node_tag_types (
-
- node_tag_type_id serial PRIMARY KEY, -- ID
- name text UNIQUE NOT NULL, -- Tag Name
- description text, -- Optional Description
- category text NOT NULL, -- Free text for grouping tags together
- min_role_id integer REFERENCES roles -- set minimal role required
-) WITH OIDS;
-
-CREATE TABLE node_tag (
- node_tag_id serial PRIMARY KEY, -- ID
- node_id integer REFERENCES nodes NOT NULL, -- node id
- node_tag_type_id integer REFERENCES node_tag_types,
- -- tag type id
- value text -- value attached
-) WITH OIDS;
-
----------- related views
-CREATE OR REPLACE VIEW node_tags AS
-SELECT node_id,
-array_accum(node_tag_id) AS tag_ids
-FROM node_tag
-GROUP BY node_id;
-
-CREATE OR REPLACE VIEW view_node_tags AS
-SELECT
-node_tag.node_tag_id,
-node_tag.node_id,
-node_tag_types.node_tag_type_id,
-node_tag_types.name,
-node_tag_types.description,
-node_tag_types.category,
-node_tag_types.min_role_id,
-node_tag.value
-FROM node_tag
-INNER JOIN node_tag_types USING (node_tag_type_id);
-
-DROP VIEW view_nodes;
-CREATE OR REPLACE VIEW view_nodes AS
-SELECT
-nodes.node_id,
-nodes.hostname,
-nodes.site_id,
-nodes.boot_state,
-nodes.deleted,
-nodes.model,
-nodes.boot_nonce,
-nodes.version,
-nodes.ssh_rsa_key,
-nodes.key,
-CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created,
-CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated,
-CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact,
-peer_node.peer_id,
-peer_node.peer_node_id,
-COALESCE((SELECT interface_ids FROM node_interfaces WHERE node_interfaces.node_id = nodes.node_id), '{}') AS interface_ids,
-COALESCE((SELECT nodegroup_ids FROM node_nodegroups WHERE node_nodegroups.node_id = nodes.node_id), '{}') AS nodegroup_ids,
-COALESCE((SELECT slice_ids FROM node_slices WHERE node_slices.node_id = nodes.node_id), '{}') AS slice_ids,
-COALESCE((SELECT slice_ids_whitelist FROM node_slices_whitelist WHERE node_slices_whitelist.node_id = nodes.node_id), '{}') AS slice_ids_whitelist,
-COALESCE((SELECT pcu_ids FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS pcu_ids,
-COALESCE((SELECT ports FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS ports,
-COALESCE((SELECT conf_file_ids FROM node_conf_files WHERE node_conf_files.node_id = nodes.node_id), '{}') AS conf_file_ids,
-COALESCE((SELECT tag_ids FROM node_tags WHERE node_tags.node_id = nodes.node_id), '{}') AS tag_ids,
-node_session.session_id AS session
-FROM nodes
-LEFT JOIN peer_node USING (node_id)
-LEFT JOIN node_session USING (node_id);
-
-----------------------------------------
--- nodegroups
--- xxx - todo
--- a more usable migration script would need to capture more data
-----------------------------------------
-DROP TABLE IF EXISTS nodegroups CASCADE;
-
--- Node groups
-CREATE TABLE nodegroups (
- nodegroup_id serial PRIMARY KEY, -- Group identifier
- name text UNIQUE NOT NULL, -- Group name
- node_tag_type_id integer REFERENCES node_tag_types, -- node is in nodegroup if it has this tag defined
- value text -- with value 'value'
-) WITH OIDS;
-
-CREATE OR REPLACE VIEW nodegroup_node AS
-SELECT nodegroup_id, node_id
-FROM node_tag_types
-JOIN node_tag
-USING (node_tag_type_id)
-JOIN nodegroups
-USING (node_tag_type_id,value);
-
-CREATE OR REPLACE VIEW nodegroup_nodes AS
-SELECT nodegroup_id,
-array_accum(node_id) AS node_ids
-FROM nodegroup_node
-GROUP BY nodegroup_id;
-
--- Node groups that each node is a member of
-CREATE OR REPLACE VIEW node_nodegroups AS
-SELECT node_id,
-array_accum(nodegroup_id) AS nodegroup_ids
-FROM nodegroup_node
-GROUP BY node_id;
-
-----------------------------------------
--- update versioning
-----------------------------------------
-UPDATE plc_db_version SET version=5, subversion=0;
-
-EOF
-
+ sql_script=$DIRNAME/${BASENAME}.sql
+ if [ -f $sql_script ] ; then
+ cat $sql_script
+ else
+ echo Cannot locate ${BASENAME}.sql
+ echo exiting
+ exit 1
+ fi
}
--- /dev/null
+-- $Id$
+--
+-- this is the script to migrate from 4.2 to 5.0
+--
+
+----------------------------------------
+-- rename nodenetwork into interface
+----------------------------------------
+
+ALTER TABLE nodenetworks RENAME TO interfaces;
+ALTER TABLE interfaces RENAME COLUMN nodenetwork_id TO interface_id;
+
+ALTER INDEX nodenetworks_node_id_idx RENAME TO interfaces_node_id_idx;
+
+ALTER TABLE nodenetwork_setting_types RENAME TO interface_setting_types;
+ALTER TABLE interface_setting_types RENAME COLUMN nodenetwork_setting_type_id TO interface_setting_type_id;
+
+ALTER TABLE nodenetwork_setting RENAME TO interface_setting;
+
+-- views
+ALTER TABLE nodenetworks_ordered RENAME TO interfaces_ordered;
+ALTER TABLE interfaces_ordered RENAME COLUMN nodenetwork_id TO interface_id;
+
+ALTER TABLE node_nodenetworks RENAME TO node_interfaces;
+ALTER TABLE node_interfaces RENAME COLUMN nodenetwork_ids TO interface_ids;
+
+ALTER TABLE nodenetwork_settings RENAME TO interface_settings;
+ALTER TABLE interface_settings RENAME COLUMN nodenetwork_id TO interface_id;
+ALTER TABLE interface_settings RENAME COLUMN nodenetwork_setting_ids TO setting_ids;
+
+ALTER TABLE view_nodenetwork_settings RENAME TO view_interface_settings;
+ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_setting_id TO interface_setting_id;
+ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_id TO interface_id;
+ALTER TABLE view_interface_settings RENAME COLUMN nodenetwork_setting_type_id TO interface_setting_type_id;
+
+ALTER TABLE view_nodenetworks RENAME TO view_interfaces;
+ALTER TABLE view_interfaces RENAME COLUMN nodenetwork_id TO interface_id;
+ALTER TABLE view_interfaces RENAME COLUMN nodenetwork_setting_ids TO setting_ids;
+
+ALTER TABLE view_nodes RENAME COLUMN nodenetwork_ids TO interface_ids;
+
+----------------------------------------
+-- node tags
+----------------------------------------
+CREATE TABLE node_tag_types (
+
+ node_tag_type_id serial PRIMARY KEY, -- ID
+ name text UNIQUE NOT NULL, -- Tag Name
+ description text, -- Optional Description
+ category text NOT NULL, -- Free text for grouping tags together
+ min_role_id integer REFERENCES roles -- set minimal role required
+) WITH OIDS;
+
+CREATE TABLE node_tag (
+ node_tag_id serial PRIMARY KEY, -- ID
+ node_id integer REFERENCES nodes NOT NULL, -- node id
+ node_tag_type_id integer REFERENCES node_tag_types,
+ -- tag type id
+ value text -- value attached
+) WITH OIDS;
+
+---------- related views
+CREATE OR REPLACE VIEW node_tags AS
+SELECT node_id,
+array_accum(node_tag_id) AS tag_ids
+FROM node_tag
+GROUP BY node_id;
+
+CREATE OR REPLACE VIEW view_node_tags AS
+SELECT
+node_tag.node_tag_id,
+node_tag.node_id,
+node_tag_types.node_tag_type_id,
+node_tag_types.name,
+node_tag_types.description,
+node_tag_types.category,
+node_tag_types.min_role_id,
+node_tag.value
+FROM node_tag
+INNER JOIN node_tag_types USING (node_tag_type_id);
+
+----------------------------------------
+-- nodegroups
+-- xxx - todo
+-- a more usable migration script would need to capture more data
+----------------------------------------
+DROP TABLE IF EXISTS nodegroups CASCADE;
+
+-- Node groups
+CREATE TABLE nodegroups (
+ nodegroup_id serial PRIMARY KEY, -- Group identifier
+ groupname text UNIQUE NOT NULL, -- Group name
+ node_tag_type_id integer REFERENCES node_tag_types, -- node is in nodegroup if it has this tag defined
+ value text -- with value 'value'
+) WITH OIDS;
+
+CREATE OR REPLACE VIEW nodegroup_node AS
+SELECT nodegroup_id, node_id
+FROM node_tag_types
+JOIN node_tag
+USING (node_tag_type_id)
+JOIN nodegroups
+USING (node_tag_type_id,value);
+
+CREATE OR REPLACE VIEW nodegroup_nodes AS
+SELECT nodegroup_id,
+array_accum(node_id) AS node_ids
+FROM nodegroup_node
+GROUP BY nodegroup_id;
+
+-- Node groups that each node is a member of
+CREATE OR REPLACE VIEW node_nodegroups AS
+SELECT node_id,
+array_accum(nodegroup_id) AS nodegroup_ids
+FROM nodegroup_node
+GROUP BY node_id;
+
+CREATE OR REPLACE VIEW view_nodegroups AS
+SELECT
+nodegroups.*,
+COALESCE((SELECT conf_file_ids FROM nodegroup_conf_files WHERE nodegroup_conf_files.nodegroup_id = nodegroups.nodegroup_id), '{}') AS conf_file_ids
+FROM nodegroups;
+----------------------------------------
+-- the nodes view
+----------------------------------------
+DROP VIEW view_nodes;
+CREATE OR REPLACE VIEW view_nodes AS
+SELECT
+nodes.node_id,
+nodes.hostname,
+nodes.site_id,
+nodes.boot_state,
+nodes.deleted,
+nodes.model,
+nodes.boot_nonce,
+nodes.version,
+nodes.ssh_rsa_key,
+nodes.key,
+CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created,
+CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated,
+CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact,
+peer_node.peer_id,
+peer_node.peer_node_id,
+COALESCE((SELECT interface_ids FROM node_interfaces WHERE node_interfaces.node_id = nodes.node_id), '{}') AS interface_ids,
+COALESCE((SELECT nodegroup_ids FROM node_nodegroups WHERE node_nodegroups.node_id = nodes.node_id), '{}') AS nodegroup_ids,
+COALESCE((SELECT slice_ids FROM node_slices WHERE node_slices.node_id = nodes.node_id), '{}') AS slice_ids,
+COALESCE((SELECT slice_ids_whitelist FROM node_slices_whitelist WHERE node_slices_whitelist.node_id = nodes.node_id), '{}') AS slice_ids_whitelist,
+COALESCE((SELECT pcu_ids FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS pcu_ids,
+COALESCE((SELECT ports FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS ports,
+COALESCE((SELECT conf_file_ids FROM node_conf_files WHERE node_conf_files.node_id = nodes.node_id), '{}') AS conf_file_ids,
+COALESCE((SELECT tag_ids FROM node_tags WHERE node_tags.node_id = nodes.node_id), '{}') AS tag_ids,
+node_session.session_id AS session
+FROM nodes
+LEFT JOIN peer_node USING (node_id)
+LEFT JOIN node_session USING (node_id);
+
+----------------------------------------
+-- update versioning
+----------------------------------------
+UPDATE plc_db_version SET version=5, subversion=0;
+++ /dev/null
-methods.php
-plc_api.php
-- Node groups
CREATE TABLE nodegroups (
nodegroup_id serial PRIMARY KEY, -- Group identifier
- name text UNIQUE NOT NULL, -- Group name
+ groupname text UNIQUE NOT NULL, -- Group name (name & value will refer to the tag)
node_tag_type_id integer REFERENCES node_tag_types, -- node is in nodegroup if it has this tag defined
- value text -- with value 'value'
+ value text NOT NULL -- with value 'value'
) WITH OIDS;
-
+-- xxx - first rough implem
CREATE OR REPLACE VIEW nodegroup_node AS
SELECT nodegroup_id, node_id
FROM node_tag_types
CREATE OR REPLACE VIEW view_nodegroups AS
SELECT
nodegroups.*,
-COALESCE((SELECT node_ids FROM nodegroup_nodes WHERE nodegroup_nodes.nodegroup_id = nodegroups.nodegroup_id), '{}') AS node_ids,
COALESCE((SELECT conf_file_ids FROM nodegroup_conf_files WHERE nodegroup_conf_files.nodegroup_id = nodegroups.nodegroup_id), '{}') AS conf_file_ids
FROM nodegroups;