2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
6 #This file is part of Shinken.
8 #Shinken is free software: you can redistribute it and/or modify
9 #it under the terms of the GNU Affero General Public License as published by
10 #the Free Software Foundation, either version 3 of the License, or
11 #(at your option) any later version.
13 #Shinken is distributed in the hope that it will be useful,
14 #but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 #GNU Affero General Public License for more details.
18 #You should have received a copy of the GNU Affero General Public License
19 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
22 from itemgroup
import Itemgroup
, Itemgroups
23 from shinken
.property import UnusedProp
, BoolProp
, IntegerProp
, FloatProp
, CharProp
, StringProp
, ListProp
25 class Hostgroup(Itemgroup
):
26 id = 1 #0 is always a little bit special... like in database
32 fill_brok
=['full_status']),
33 'hostgroup_name': StringProp(
34 fill_brok
=['full_status']),
36 fill_brok
=['full_status']),
39 fill_brok
=['full_status']),
40 'notes_url': StringProp(
42 fill_brok
=['full_status']),
43 'action_url': StringProp(
45 fill_brok
=['full_status']),
46 'members': StringProp(
48 fill_brok
=['full_status']),
50 'unknown_members': StringProp(
52 'configuration_errors' : StringProp(default
= []),
56 'HOSTGROUPALIAS' : 'alias',
57 'HOSTGROUPMEMBERS' : 'members',
58 'HOSTGROUPNOTES' : 'notes',
59 'HOSTGROUPNOTESURL' : 'notes_url',
60 'HOSTGROUPACTIONURL' : 'action_url'
65 return self
.hostgroup_name
69 return getattr(self
, 'members', '')
72 def get_hostgroup_members(self
):
73 if self
.has('hostgroup_members'):
74 return self
.hostgroup_members
.split(',')
79 #We fillfull properties with template ones if need
80 #Because hostgroup we call may not have it's members
81 #we call get_hosts_by_explosion on it
82 def get_hosts_by_explosion(self
, hostgroups
):
83 #First we tag the hg so it will not be explode
84 #if a son of it already call it
85 self
.already_explode
= True
87 #Now the recursiv part
88 #rec_tag is set to False avery HG we explode
89 #so if True here, it must be a loop in HG
92 print "Error : we've got a loop in hostgroup definition", self
.get_name()
93 return self
.get_hosts()
94 #Ok, not a loop, we tag it and continue
97 hg_mbrs
= self
.get_hostgroup_members()
98 for hg_mbr
in hg_mbrs
:
99 hg
= hostgroups
.find_by_name(hg_mbr
.strip())
101 value
= hg
.get_hosts_by_explosion(hostgroups
)
102 if value
is not None:
103 self
.add_string_member(value
)
105 return self
.get_hosts()
109 class Hostgroups(Itemgroups
):
110 name_property
= "hostgroup_name" # is used for finding hostgroups
111 inner_class
= Hostgroup
113 def get_members_by_name(self
, hgname
):
114 id = self
.find_id_by_name(hgname
)
117 return self
.itemgroups
[id].get_hosts()
120 def linkify(self
, hosts
=None, realms
=None):
121 self
.linkify_hg_by_hst(hosts
)
122 self
.linkify_hg_by_realms(realms
)
125 #We just search for each hostgroup the id of the hosts
126 #and replace the name by the id
127 def linkify_hg_by_hst(self
, hosts
):
128 for hg
in self
.itemgroups
.values():
129 mbrs
= hg
.get_hosts()
130 #The new member list, in id
134 new_mbrs
.extend(hosts
)
136 h
= hosts
.find_by_name(mbr
)
140 hg
.unknown_members
.append(mbr
)
143 new_mbrs
= list(set(new_mbrs
))
145 #We find the id, we remplace the names
146 hg
.replace_members(new_mbrs
)
148 #Now register us in our members
150 h
.hostgroups
.append(hg
)
151 #and be sure we are uniq in it
152 h
.hostgroups
= list(set(h
.hostgroups
))
155 #More than an explode function, but we need to already
156 #have members so... Will be really linkify just after
157 #And we explode realm in ours members, but do not overide
158 #a host realm value if it's already set
159 def linkify_hg_by_realms(self
, realms
):
160 #Now we explode the realm value if we've got one
161 #The group realm must not overide a host one (warning?)
163 if not hasattr(hg
, 'realm'): continue
165 r
= realms
.find_by_name(hg
.realm
.strip())
168 print "Hostgroup", hg
.get_name(), "is in the realm", r
.get_name()
170 err
= "The hostgroup %s got an unknown realm '%s'" % (hg
.get_name(), hg
.realm
)
171 hg
.configuration_errors
.append(err
)
176 if h
is None: continue
177 if h
.realm
== None or h
.got_default_realm
: #default value not hasattr(h, 'realm'):
178 print "Apply a realm", hg
.realm
.get_name(), "to host", h
.get_name(), "from a hostgroup rule (%s)" % hg
.get_name()
181 if h
.realm
!= hg
.realm
:
182 print "Warning : host", h
.get_name(), "is not in the same realm than it's hostgroup", hg
.get_name()
185 #Add a host string to a hostgroup member
186 #if the host group do not exist, create it
187 def add_member(self
, hname
, hgname
):
188 id = self
.find_id_by_name(hgname
)
189 #if the id do not exist, create the hg
191 hg
= Hostgroup({'hostgroup_name' : hgname
, 'alias' : hgname
, 'members' : hname
})
194 self
.itemgroups
[id].add_string_member(hname
)
197 #Use to fill members with hostgroup_members
199 #We do not want a same hg to be explode again and again
201 for tmp_hg
in self
.itemgroups
.values():
202 tmp_hg
.already_explode
= False
203 for hg
in self
.itemgroups
.values():
204 if hg
.has('hostgroup_members') and not hg
.already_explode
:
205 #get_hosts_by_explosion is a recursive
206 #function, so we must tag hg so we do not loop
207 for tmp_hg
in self
.itemgroups
.values():
208 tmp_hg
.rec_tag
= False
209 hg
.get_hosts_by_explosion(self
)
212 for tmp_hg
in self
.itemgroups
.values():
213 if hasattr(tmp_hg
, 'rec_tag'):
215 del tmp_hg
.already_explode