Fix version output when missing.
[plcapi.git] / PLC / NodeGroups.py
1 #
2 # Functions for interacting with the nodegroups table in the database
3 #
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
6 #
7 # $Id$
8 # $URL$
9 #
10
11 from types import StringTypes
12
13 from PLC.Faults import *
14 from PLC.Parameter import Parameter, Mixed
15 from PLC.Filter import Filter
16 from PLC.Debug import profile
17 from PLC.Table import Row, Table
18 from PLC.Nodes import Node, Nodes
19
20 class NodeGroup(Row):
21     """
22     Representation of a row in the nodegroups table. To use, optionally
23     instantiate with a dict of values. Update as you would a
24     dict. Commit to the database with sync().
25     """
26
27     table_name = 'nodegroups'
28     primary_key = 'nodegroup_id'
29     join_tables = ['conf_file_nodegroup']
30     primary_field = 'nodegroup_id'
31     fields = {
32         'nodegroup_id': Parameter(int, "Node group identifier"),
33         'groupname': Parameter(str, "Node group name", max = 50),
34         'tag_type_id': Parameter (int, "Node tag type id"),
35         'value' : Parameter(str, "value that the nodegroup definition is based upon"),
36         'tagname' : Parameter(str, "Tag name that the nodegroup definition is based upon"),
37         'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
38         'node_ids' : Parameter([int], "List of node_ids that belong to this nodegroup"),
39         }
40     related_fields = {
41         }
42
43     def validate_name(self, name):
44         # Make sure name is not blank
45         if not len(name):
46             raise PLCInvalidArgument, "Invalid node group name"
47
48         # Make sure node group does not alredy exist
49         conflicts = NodeGroups(self.api, [name])
50         for nodegroup in conflicts:
51             if 'nodegroup_id' not in self or self['nodegroup_id'] != nodegroup['nodegroup_id']:
52                 raise PLCInvalidArgument, "Node group name already in use"
53
54         return name
55
56     def associate_conf_files(self, auth, field, value):
57         """
58         Add conf_files found in value list (AddConfFileToNodeGroup)
59         Delets conf_files not found in value list (DeleteConfFileFromNodeGroup)
60         """
61
62         assert 'conf_file_ids' in self
63         assert 'nodegroup_id' in self
64         assert isinstance(value, list)
65
66         conf_file_ids = self.separate_types(value)[0]
67
68         if self['conf_file_ids'] != conf_file_ids:
69             from PLC.Methods.AddConfFileToNodeGroup import AddConfFileToNodeGroup
70             from PLC.Methods.DeleteConfFileFromNodeGroup import DeleteConfFileFromNodeGroup
71             new_conf_files = set(conf_file_ids).difference(self['conf_file_ids'])
72             stale_conf_files = set(self['conf_file_ids']).difference(conf_file_ids)
73
74             for new_conf_file in new_conf_files:
75                 AddConfFileToNodeGroup.__call__(AddConfFileToNodeGroup(self.api),
76                                                 auth, new_conf_file, self['nodegroup_id'])
77             for stale_conf_file in stale_conf_files:
78                 DeleteConfFileFromNodeGroup.__call__(DeleteConfFileFromNodeGroup(self.api),
79                                                      auth, stale_conf_file, self['nodegroup_id'])
80
81
82 class NodeGroups(Table):
83     """
84     Representation of row(s) from the nodegroups table in the
85     database.
86     """
87
88     def __init__(self, api, nodegroup_filter = None, columns = None):
89         Table.__init__(self, api, NodeGroup, columns)
90
91         sql = "SELECT %s FROM view_nodegroups WHERE True" % \
92               ", ".join(self.columns)
93
94         if nodegroup_filter is not None:
95             if isinstance(nodegroup_filter, (list, tuple, set)):
96                 # Separate the list into integers and strings
97                 ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter)
98                 strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter)
99                 nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'groupname': strs})
100                 sql += " AND (%s) %s" % nodegroup_filter.sql(api, "OR")
101             elif isinstance(nodegroup_filter, dict):
102                 nodegroup_filter = Filter(NodeGroup.fields, nodegroup_filter)
103                 sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
104             elif isinstance(nodegroup_filter, (int, long)):
105                 nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': nodegroup_filter})
106                 sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
107             elif isinstance(nodegroup_filter, StringTypes):
108                 nodegroup_filter = Filter(NodeGroup.fields, {'groupname': nodegroup_filter})
109                 sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
110             else:
111                 raise PLCInvalidArgument, "Wrong node group filter %r"%nodegroup_filter
112
113         self.selectall(sql)