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