*redesign: moved classes for configuration objects to "objects" subpackage.
[shinken.git] / shinken / objects / hostgroup.py
blobba860bda2b8cd477e96d7636ff64e3058d5fdace
1 #!/usr/bin/env python
2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
5 # Gregory Starck, g.starck@gmail.com
7 #This file is part of Shinken.
9 #Shinken is free software: you can redistribute it and/or modify
10 #it under the terms of the GNU Affero General Public License as published by
11 #the Free Software Foundation, either version 3 of the License, or
12 #(at your option) any later version.
14 #Shinken is distributed in the hope that it will be useful,
15 #but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 #GNU Affero General Public License for more details.
19 #You should have received a copy of the GNU Affero General Public License
20 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
23 from .itemgroup import Itemgroup, Itemgroups
24 from shinken.property import UnusedProp, BoolProp, IntegerProp, FloatProp, CharProp, StringProp, ListProp
26 class Hostgroup(Itemgroup):
27 id = 1 #0 is always a little bit special... like in database
28 my_type = 'hostgroup'
30 properties={
31 'id': StringProp(
32 default=0,
33 fill_brok=['full_status']),
34 'hostgroup_name': StringProp(
35 fill_brok=['full_status']),
36 'alias': StringProp(
37 fill_brok=['full_status']),
38 'notes': StringProp(
39 default='',
40 fill_brok=['full_status']),
41 'notes_url': StringProp(
42 default='',
43 fill_brok=['full_status']),
44 'action_url': StringProp(
45 default='',
46 fill_brok=['full_status']),
47 'members': StringProp(
48 default='',
49 fill_brok=['full_status']),
50 #Shinken specific
51 'unknown_members': StringProp(
52 default=[]),
53 'configuration_errors' : StringProp(default = []),
56 macros = {
57 'HOSTGROUPALIAS' : 'alias',
58 'HOSTGROUPMEMBERS' : 'members',
59 'HOSTGROUPNOTES' : 'notes',
60 'HOSTGROUPNOTESURL' : 'notes_url',
61 'HOSTGROUPACTIONURL' : 'action_url'
65 def get_name(self):
66 return self.hostgroup_name
69 def get_hosts(self):
70 return getattr(self, 'members', '')
73 def get_hostgroup_members(self):
74 if self.has('hostgroup_members'):
75 return self.hostgroup_members.split(',')
76 else:
77 return []
80 #We fillfull properties with template ones if need
81 #Because hostgroup we call may not have it's members
82 #we call get_hosts_by_explosion on it
83 def get_hosts_by_explosion(self, hostgroups):
84 #First we tag the hg so it will not be explode
85 #if a son of it already call it
86 self.already_explode = True
88 #Now the recursiv part
89 #rec_tag is set to False avery HG we explode
90 #so if True here, it must be a loop in HG
91 #calls... not GOOD!
92 if self.rec_tag:
93 print "Error : we've got a loop in hostgroup definition", self.get_name()
94 return self.get_hosts()
95 #Ok, not a loop, we tag it and continue
96 self.rec_tag = True
98 hg_mbrs = self.get_hostgroup_members()
99 for hg_mbr in hg_mbrs:
100 hg = hostgroups.find_by_name(hg_mbr.strip())
101 if hg is not None:
102 value = hg.get_hosts_by_explosion(hostgroups)
103 if value is not None:
104 self.add_string_member(value)
106 return self.get_hosts()
110 class Hostgroups(Itemgroups):
111 name_property = "hostgroup_name" # is used for finding hostgroups
112 inner_class = Hostgroup
114 def get_members_by_name(self, hgname):
115 id = self.find_id_by_name(hgname)
116 if id == None:
117 return []
118 return self.itemgroups[id].get_hosts()
121 def linkify(self, hosts=None, realms=None):
122 self.linkify_hg_by_hst(hosts)
123 self.linkify_hg_by_realms(realms)
126 #We just search for each hostgroup the id of the hosts
127 #and replace the name by the id
128 def linkify_hg_by_hst(self, hosts):
129 for hg in self.itemgroups.values():
130 mbrs = hg.get_hosts()
131 #The new member list, in id
132 new_mbrs = []
133 for mbr in mbrs:
134 if mbr == '*':
135 new_mbrs.extend(hosts)
136 else:
137 h = hosts.find_by_name(mbr)
138 if h != None:
139 new_mbrs.append(h)
140 else:
141 hg.unknown_members.append(mbr)
143 #Make members uniq
144 new_mbrs = list(set(new_mbrs))
146 #We find the id, we remplace the names
147 hg.replace_members(new_mbrs)
149 #Now register us in our members
150 for h in hg.members:
151 h.hostgroups.append(hg)
152 #and be sure we are uniq in it
153 h.hostgroups = list(set(h.hostgroups))
156 #More than an explode function, but we need to already
157 #have members so... Will be really linkify just after
158 #And we explode realm in ours members, but do not overide
159 #a host realm value if it's already set
160 def linkify_hg_by_realms(self, realms):
161 #Now we explode the realm value if we've got one
162 #The group realm must not overide a host one (warning?)
163 for hg in self:
164 if not hasattr(hg, 'realm'): continue
166 r = realms.find_by_name(hg.realm.strip())
167 if r != None:
168 hg.realm = r
169 print "Hostgroup", hg.get_name(), "is in the realm", r.get_name()
170 else:
171 err = "The hostgroup %s got an unknown realm '%s'" % (hg.get_name(), hg.realm)
172 hg.configuration_errors.append(err)
173 hg.realm = None
174 continue
176 for h in hg:
177 if h is None: continue
178 if h.realm == None or h.got_default_realm: #default value not hasattr(h, 'realm'):
179 print "Apply a realm", hg.realm.get_name(), "to host", h.get_name(), "from a hostgroup rule (%s)" % hg.get_name()
180 h.realm = hg.realm
181 else:
182 if h.realm != hg.realm:
183 print "Warning : host", h.get_name(), "is not in the same realm than it's hostgroup", hg.get_name()
186 #Add a host string to a hostgroup member
187 #if the host group do not exist, create it
188 def add_member(self, hname, hgname):
189 id = self.find_id_by_name(hgname)
190 #if the id do not exist, create the hg
191 if id == None:
192 hg = Hostgroup({'hostgroup_name' : hgname, 'alias' : hgname, 'members' : hname})
193 self.add(hg)
194 else:
195 self.itemgroups[id].add_string_member(hname)
198 #Use to fill members with hostgroup_members
199 def explode(self):
200 #We do not want a same hg to be explode again and again
201 #so we tag it
202 for tmp_hg in self.itemgroups.values():
203 tmp_hg.already_explode = False
204 for hg in self.itemgroups.values():
205 if hg.has('hostgroup_members') and not hg.already_explode:
206 #get_hosts_by_explosion is a recursive
207 #function, so we must tag hg so we do not loop
208 for tmp_hg in self.itemgroups.values():
209 tmp_hg.rec_tag = False
210 hg.get_hosts_by_explosion(self)
212 #We clean the tags
213 for tmp_hg in self.itemgroups.values():
214 if hasattr(tmp_hg, 'rec_tag'):
215 del tmp_hg.rec_tag
216 del tmp_hg.already_explode