clearer names for actions, and infer actions better
[monitor.git] / commands / nodegroups.py
1 #!/usr/bin/python
2
3 # This script is used to manipulate the operational state of nodes in
4 # different node groups.  These are basically set operations on nodes via the
5 # PLC api.
6
7 # Take the ng name as an argument....
8 # optionally, 
9 #  * restart them all.
10 #  * Set some or all in the set to rins.
11 #  * get a list of nodes in the Alpha nodegroup.
12
13 # Given a nodelist, it could tag each one with a nodegroup name.
14 #  * 
15
16 from monitor import database
17 from monitor.database.info.model import FindbadNodeRecord
18 from monitor import util
19 from monitor.wrapper import plc
20 from monitor import parser as parsermodule
21
22 api = plc.getAuthAPI()
23
24 from monitor.common import *
25 from sets import Set
26
27 def main():
28
29         parser = parsermodule.getParser(['nodesets'])
30         parser.set_defaults( list=True,
31                                                 add=False,
32                         nocolor=False,
33                                                 notng=False,
34                                                 delete=False,)
35
36         parser.add_option("", "--not", dest="notng", action="store_true", 
37                                                 help="All nodes NOT in nodegroup.")
38         parser.add_option("", "--nocolor", dest="nocolor", action="store_true", 
39                                                 help="Enable color")
40         parser.add_option("", "--list", dest="list", action="store_true", 
41                                                 help="List all nodes in the given nodegroup")
42         parser.add_option("", "--add", dest="add", action="store_true", 
43                                                 help="Add nodes to the given nodegroup")
44         parser.add_option("", "--delete", dest="delete", action="store_true", 
45                                                 help="Delete nodes from the given nodegroup")
46
47         parser = parsermodule.getParser(['defaults'], parser)
48         config = parsermodule.parse_args(parser)
49
50         # COLLECT nodegroups, nodes and node lists
51         if config.node or config.nodelist:
52                 if config.node: 
53                         hostlist = [ config.node ] 
54                 else: 
55                         hostlist = util.file.getListFromFile(config.nodelist)
56
57                 # NOTE: preserve order given in file.  Otherwise, return values are not in order
58                 # given to GetNodes
59                 nodelist = []
60                 for h in hostlist:
61                         nodelist.append( plccache.GetNodeByName(h) )
62
63                 group_str = "Given"
64
65         elif config.site:
66                 site = plccache.GetSitesByName([config.site])
67                 if len (site) > 0:
68                         site = site[0]
69                         nodelist = plccache.GetNodesByIds(site['node_ids'])
70                 else:
71                         nodelist = []
72
73                 group_str = config.site
74
75         elif config.nodeselect:
76                 hostlist = query.node_select(config.nodeselect)
77                 nodelist = [ plccache.GetNodeByName(h) for h in hostlist ]
78
79                 group_str = "selection"
80                 
81         else:
82                 ng = api.GetNodeGroups({'name' : config.nodegroup})
83                 nodelist = plccache.GetNodesByIds(ng[0]['node_ids'])
84
85                 group_str = config.nodegroup
86
87         if config.notng:
88                 # Get nodegroup nodes
89                 ng_nodes = nodelist
90
91                 # Get all nodes
92                 all_nodes = plccache.l_nodes
93                 
94                 # remove ngnodes from all node list
95                 ng_list = [ x['hostname'] for x in ng_nodes ]
96                 all_list = [ x['hostname'] for x in all_nodes ]
97                 not_ng_nodes = Set(all_list) - Set(ng_list)
98
99                 # keep each node that *is* in the not_ng_nodes set
100                 nodelist = filter(lambda x : x['hostname'] in not_ng_nodes, all_nodes)
101
102         hostnames = [ n['hostname'] for n in nodelist ]
103
104         # commands:
105
106         if config.add and config.nodegroup:
107                 for node in hostnames:
108                         print "Adding %s to %s nodegroup" % (node, config.nodegroup)
109                         api.AddNodeToNodeGroup(node, config.nodegroup)
110
111         elif config.delete:
112                 for node in hostnames:
113                         print "Deleting %s from %s nodegroup" % (node, config.nodegroup)
114                         api.DeleteNodeFromNodeGroup(node, config.nodegroup)
115
116         elif config.list:
117                 print " ---- Nodes in the %s Node Group ----" % group_str
118                 print "   Hostname                                   plc  obs     pcu     key         kernel                        last_contact, last change, comon uptime"
119                 i = 1
120                 for node in nodelist:
121                         print "%-2d" % i, 
122                         fbrec = FindbadNodeRecord.get_latest_by(hostname=node['hostname'])
123                         fbdata = fbrec.to_dict()
124                         print nodegroup_display(node, fbdata, config)
125                         i += 1
126
127         else:
128                 print "no other options supported."
129
130 if __name__ == "__main__":
131         try:
132                 main()
133         except IOError:
134                 pass