# known classes : { class -> secondary_key }
taggable_classes = { Node : {'table_class' : Nodes,
'joins_class' : NodeTags, 'join_class' : NodeTag,
- 'value_key': 'tagvalue', 'secondary_key': 'hostname'},
+ 'secondary_key': 'hostname'},
Interface : {'table_class' : Interfaces,
'joins_class': InterfaceTags, 'join_class': InterfaceTag,
- 'value_key' : 'value' },
+ },
Slice: {'table_class' : Slices,
'joins_class': SliceTags, 'join_class': SliceTag,
- 'value_key' : 'value', 'secondary_key':'login_base'},
+ 'secondary_key':'login_base'},
# Ilink : xxx
}
tech_roles = [ 'admin', 'pi', 'tech' ]
# generates 2 method classes:
-# Get<classname><methodsuffix> (auth, id_or_name) -> tagvalue or None
-# Set<classname><methodsuffix> (auth, id_or_name, tagvalue) -> None
-# tagvalue is always a string, no cast nor typecheck for now
+# Get<classname><methodsuffix> (auth, id_or_name) -> value or None
+# Set<classname><methodsuffix> (auth, id_or_name, value) -> None
+# value is always a string, no cast nor typecheck for now
#
# note: tag_min_role_id gets attached to the tagtype instance,
# while get_roles and set_roles get attached to the created methods
table_class = taggable_classes[objclass]['table_class']
joins_class = taggable_classes[objclass]['joins_class']
join_class = taggable_classes[objclass]['join_class']
- value_key = taggable_classes[objclass]['value_key']
# body of the get method
def get_call (self, auth, id_or_name):
filter[primary_key]=id_or_name
else:
filter[secondary_key]=id_or_name
- joins = joins_class (self.api,filter,[value_key])
+ joins = joins_class (self.api,filter,['value'])
if not joins:
# xxx - we return None even if id_or_name is not valid
return None
else:
- return joins[0][value_key]
+ return joins[0]['value']
# attach it
setattr (get_class,"call",get_call)
# body of the set method
- def set_call (self, auth, id_or_name, tagvalue):
+ def set_call (self, auth, id_or_name, value):
# locate the object
if isinstance (id_or_name, int):
filter={primary_key:id_or_name}
filter[secondary_key]=id_or_name
joins = joins_class (self.api,filter)
# setting to something non void
- if tagvalue is not None:
+ if value is not None:
if not joins:
join = join_class (self.api)
join['tag_type_id']=tag_type_id
join[primary_key]=primary_id
- join[value_key]=tagvalue
+ join['value']=value
join.sync()
else:
- joins[0][value_key]=tagvalue
+ joins[0]['value']=value
joins[0].sync()
# providing an empty value means clean up
else:
example : filter = { '-OFFSET' : 100, '-LIMIT':25}
A realistic example would read
- GetNodes ( { 'hostname' : '*.edu' , '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } )
- and that would return nodes matching '*.edu' in alphabetical order from 31th to 55th
+ GetNodes ( { 'node_type' : 'regular' , 'hostname' : '*.edu' , '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } )
+ and that would return regular (usual) nodes matching '*.edu' in alphabetical order from 31th to 55th
"""
def __init__(self, fields = {}, filter = {}, doc = "Attribute filter"):
'Node': [node['node_id']]}
self.message = "Node %s created" % node['node_id']
- for (tagname,tagvalue) in tags.iteritems():
+ 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
node_tags=NodeTags(self.api,{'tagname':tagname,'node_id':node['node_id']})
if not node_tags:
- AddNodeTag(self.api).__call__(auth,node['node_id'],tagname,tagvalue)
+ AddNodeTag(self.api).__call__(auth,node['node_id'],tagname,value)
else:
- UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],tagvalue)
+ UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],value)
return node['node_id']
NodeGroup.fields['groupname'],
Mixed(TagType.fields['tag_type_id'],
TagType.fields['tagname']),
- NodeTag.fields['tagvalue'],
+ NodeTag.fields['value'],
]
returns = Parameter(int, 'New nodegroup_id (> 0) if successful')
- def call(self, auth, groupname, tag_type_id_or_tagname, tagvalue):
+ def call(self, auth, groupname, tag_type_id_or_tagname, value):
# locate tag type
tag_types = TagTypes (self.api,[tag_type_id_or_tagname])
if not(tag_types):
nodegroup_fields = { 'groupname' : groupname,
'tag_type_id' : tag_type['tag_type_id'],
- 'tagvalue' : tagvalue }
+ 'value' : value }
nodegroup = NodeGroup(self.api, nodegroup_fields)
nodegroup.sync()
from PLC.Parameter import Parameter, Mixed
from PLC.Auth import Auth
+from PLC.Sites import Sites
+from PLC.Nodes import Node, Nodes
from PLC.TagTypes import TagType, TagTypes
from PLC.NodeTags import NodeTag, NodeTags
-from PLC.Nodes import Node, Nodes
-from PLC.Sites import Sites
class AddNodeTag(Method):
"""
Node.fields['hostname']),
Mixed(TagType.fields['tag_type_id'],
TagType.fields['tagname']),
- NodeTag.fields['tagvalue'],
+ NodeTag.fields['value'],
]
returns = Parameter(int, 'New node_tag_id (> 0) if successful')
node_tag = NodeTag(self.api)
node_tag['node_id'] = node['node_id']
node_tag['tag_type_id'] = tag_type['tag_type_id']
- node_tag['tagvalue'] = value
+ node_tag['value'] = value
node_tag.sync()
self.object_ids = [node_tag['node_tag_id']]
from PLC.Nodes import Node, Nodes
from PLC.Interfaces import Interface, Interfaces
from PLC.InterfaceTags import InterfaceTag, InterfaceTags
-from PLC.NodeTags import NodeTags
# could not define this in the class..
boot_medium_actions = [ 'node-preview',
return (pldistro,arch)
node_id=node['node_id']
- # cannot use accessors in the API itself
- # the 'arch' tag type is assumed to exist, see db-config
- arch_tags = NodeTags (self.api, {'tagname':'arch','node_id':node_id},['tagvalue'])
- if arch_tags:
- arch=arch_tags[0]['tagvalue']
- # ditto
- pldistro_tags = NodeTags (self.api, {'tagname':'pldistro','node_id':node_id},['tagvalue'])
- if pldistro_tags:
- pldistro=pldistro_tags[0]['tagvalue']
+
+ tag=Nodes([node_id],['arch'])[0]['arch']
+ if tag: arch=tag
+ tag=Nodes([node_id],['arch'])[0]['pldistro']
+ if tag: pldistro=tag
return (pldistro,arch)
if 'boot_state' in node_fields.keys():
self.message += ' boot_state updated to %s' % node_fields['boot_state']
- for (tagname,tagvalue) in tags.iteritems():
+ 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
node_tags=NodeTags(self.api,{'tagname':tagname,'node_id':node['node_id']})
if not node_tags:
- AddNodeTag(self.api).__call__(auth,node['node_id'],tagname,tagvalue)
+ AddNodeTag(self.api).__call__(auth,node['node_id'],tagname,value)
else:
- UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],tagvalue)
+ UpdateNodeTag(self.api).__call__(auth,node_tags[0]['node_tag_id'],value)
return 1
from PLC.NodeGroups import NodeGroup, NodeGroups
from PLC.Auth import Auth
-can_update = lambda (field, value): field in ['groupname','tagvalue']
+can_update = lambda (field, value): field in ['groupname','value']
class UpdateNodeGroup(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
+from PLC.Nodes import Node, Nodes
+from PLC.NodeTags import NodeTag, NodeTags
class UpdateNodeTag(Method):
"""
accepts = [
Auth(),
NodeTag.fields['node_tag_id'],
- NodeTag.fields['tagvalue']
+ NodeTag.fields['value']
]
returns = Parameter(int, '1 if successful')
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['tagvalue'] = value
+ node_tag['value'] = value
node_tag.sync()
self.object_ids = [node_tag['node_tag_id']]
'nodegroup_id': Parameter(int, "Node group identifier"),
'groupname': Parameter(str, "Node group name", max = 50),
'tag_type_id': Parameter (int, "Node tag type id"),
- 'tagvalue' : Parameter(str, "value that the nodegroup definition is based upon"),
+ 'value' : Parameter(str, "value that the nodegroup definition is based upon"),
'tagname' : 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"),
'node_ids' : Parameter([int], "List of node_ids that belong to this nodegroup"),
'node_id': Node.fields['node_id'],
'hostname' : Node.fields['hostname'],
'tag_type_id': TagType.fields['tag_type_id'],
- 'tagvalue': Parameter(str, "Node tag value"),
+ 'value': Parameter(str, "Node tag value"),
'tagname': TagType.fields['tagname'],
'description': TagType.fields['description'],
'category': TagType.fields['category'],
view_tags_name = "view_node_tags"
# tags declared here should also be defined as Accessors to ensure that the TagType is created
+ # type info not used yet
tags = {
- # regular
- 'arch': Parameter(str, "node/config", ro=True),
- 'deployment': Parameter(str, "node/operation"),
- # dummynet
+ # regular nodes
+ 'arch': str,
+ 'pldistro' : str,
+ 'deployment': str,
+ # dummynet nodes
}
def validate_hostname(self, hostname):
"""
returns a SQL sentence that creates a view named after the primary_key and tagname,
with 2 columns
- (*) column 1: name=self.primary_key
- (*) column 2: name=tagname value=tagvalue
+ (*) column 1: primary_key
+ (*) column 2: actual tag value, renamed into tagname
"""
if not cls.view_tags_name: return ""
view_tags_name=cls.view_tags_name
tagvalue_view_name=cls.tagvalue_view_name(tagname)
return 'CREATE OR REPLACE VIEW %(tagvalue_view_name)s ' \
- 'as SELECT %(table_name)s.%(primary_key)s,%(view_tags_name)s.tagvalue as "%(tagname)s" ' \
+ 'as SELECT %(table_name)s.%(primary_key)s,%(view_tags_name)s.value as "%(tagname)s" ' \
'from %(table_name)s right join %(view_tags_name)s using (%(primary_key)s) ' \
'WHERE tagname = \'%(tagname)s\';'%locals()
node_tag_id serial PRIMARY KEY, -- ID
node_id integer REFERENCES nodes NOT NULL, -- node id
tag_type_id integer REFERENCES tag_types, -- tag type id
- tagvalue text -- value attached
+ value text -- value attached
) WITH OIDS;
---------- nodegroups table - start
-- nodegroup_id is preserved for conf_files and other references
-- former nodegroups table was (nodegroup_id,name,description)
--- new table is now (nodegroup_id, groupname, tag_type_id, tagvalue)
+-- new table is now (nodegroup_id, groupname, tag_type_id, value)
-- rename column
ALTER TABLE nodegroups RENAME name TO groupname;
ALTER TABLE nodegroups DROP COLUMN description;
---------- set the right tags so as to recover former nodegroups
-INSERT INTO node_tag (node_id, tag_type_id, tagvalue)
- SELECT node_id, tag_type_id, tagvalue FROM
+INSERT INTO node_tag (node_id, tag_type_id, value)
+ SELECT node_id, tag_type_id, value FROM
nodegroup_node LEFT JOIN nodegroups USING (nodegroup_id)
INNER JOIN mgn_site_nodegroup USING (groupname)
LEFT JOIN tag_types using (tagname);
---------- nodegroups table - conclusion
ALTER TABLE nodegroups ADD COLUMN tag_type_id INTEGER;
-ALTER TABLE nodegroups ADD COLUMN tagvalue TEXT;
+ALTER TABLE nodegroups ADD COLUMN value TEXT;
CREATE OR REPLACE VIEW mgn_nodegroups AS
- SELECT groupname, tag_types.tag_type_id, mgn_site_nodegroup.tagvalue
+ SELECT groupname, tag_types.tag_type_id, mgn_site_nodegroup.value
FROM nodegroups INNER JOIN mgn_site_nodegroup USING (groupname)
INNER JOIN tag_types USING (tagname);
UPDATE nodegroups SET tag_type_id = (SELECT tag_type_id FROM mgn_nodegroups WHERE nodegroups.groupname=mgn_nodegroups.groupname);
-UPDATE nodegroups SET tagvalue = (SELECT tagvalue FROM mgn_nodegroups WHERE nodegroups.groupname=mgn_nodegroups.groupname);
+UPDATE nodegroups SET value = (SELECT value FROM mgn_nodegroups WHERE nodegroups.groupname=mgn_nodegroups.groupname);
-- install corresponding constraints
ALTER TABLE nodegroups ADD CONSTRAINT nodegroups_tag_type_id_fkey
# strip off comments
comment=re.compile("\s*#.*")
id="[\w\.-]+|\'[^\']+\'"
- id3="\s*(?P<groupname>%s)\s+(?P<tagname>%s)\s+(?P<tagvalue>%s\s*)"%(id,id,id)
+ id3="\s*(?P<groupname>%s)\s+(?P<tagname>%s)\s+(?P<value>%s\s*)"%(id,id,id)
line=re.compile(id3)
def parse (self):
outfile = sys.stdout
lineno=0
print >> outfile, """
-CREATE TABLE mgn_site_nodegroup (groupname text, tagname text, tagvalue text);
+CREATE TABLE mgn_site_nodegroup (groupname text, tagname text, value text);
"""
for line in file(self.input).readlines():
lineno += 1
if id.find("'")==0:
return id
return "'%s'"%id
- [groupname,tagname,tagvalue]=[normalize(x) for x in match.groups()]
+ [groupname,tagname,value]=[normalize(x) for x in match.groups()]
print >> outfile, \
-"INSERT INTO mgn_site_nodegroup (groupname,tagname,tagvalue) VALUES (%s,%s,%s);"%\
-(groupname,tagname,tagvalue)
+"INSERT INTO mgn_site_nodegroup (groupname,tagname,value) VALUES (%s,%s,%s);"%\
+(groupname,tagname,value)
if outfile != sys.stdout:
outfile.close()
# this file allows you to plan the migration of your nodegroups
#
-# groupname tagname tagvalue
+# groupname tagname value
#
# single quotes can be used
# although tagnames can have spaces, it is not recommended
node_tag_id serial PRIMARY KEY, -- ID
node_id integer REFERENCES nodes NOT NULL, -- node id
tag_type_id integer REFERENCES tag_types, -- tag type id
- tagvalue text -- value attached
+ value text -- value attached
) WITH OIDS;
--------------------------------------------------------------------------------
groupname text UNIQUE NOT NULL, -- Group name
tag_type_id integer REFERENCES tag_types, -- node is in nodegroup if it has this tag defined
-- can be null, make management faster & easier
- tagvalue text -- with this value attached
+ value text -- with this value attached
) WITH OIDS;
-- xxx - first rough implem. similar to former semantics but might be slow
JOIN node_tag
USING (tag_type_id)
JOIN nodegroups
-USING (tag_type_id,tagvalue);
+USING (tag_type_id,value);
CREATE OR REPLACE VIEW nodegroup_nodes AS
SELECT nodegroup_id,
tag_types.description,
tag_types.category,
tag_types.min_role_id,
-node_tag.tagvalue
+node_tag.value
FROM node_tag
INNER JOIN tag_types USING (tag_type_id)
INNER JOIN nodes USING (node_id);