Merge branch 'master' of ssh://lausser,shinken@shinken.git.sourceforge.net/gitroot...
[shinken.git] / shinken / objects / discoveryrule.py
blob2f0c1f9f3098ef5795233eabc1f1915f7181451f
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
6 # Hartmut Goebel, h.goebel@goebel-consult.de
8 #This file is part of Shinken.
10 #Shinken is free software: you can redistribute it and/or modify
11 #it under the terms of the GNU Affero General Public License as published by
12 #the Free Software Foundation, either version 3 of the License, or
13 #(at your option) any later version.
15 #Shinken is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 #GNU Affero General Public License for more details.
20 #You should have received a copy of the GNU Affero General Public License
21 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
23 import re
25 from shinken.objects import *
26 from shinken.property import IntegerProp, StringProp, ListProp
28 class Discoveryrule(Item):
29 id = 1 #0 is always special in database, so we do not take risk here
30 my_type = 'discoveryrule'
32 properties = {
33 'discoveryrule_name': StringProp (),
34 'creation_type': StringProp (default='service'),
35 # 'check_command': StringProp (),
36 # 'service_description': StringProp (),
37 # 'use': StringProp(),
40 running_properties = {}
42 macros = {}
45 # The init of a discovery will set the property of
46 # Discoveryrule.properties as in setattr, but all others
47 # will be in a list because we need to have all names
48 # and not lost all in __dict__
49 def __init__(self, params={}):
50 cls = self.__class__
52 # We have our own id of My Class type :)
53 # use set attr for going into the slots
54 # instead of __dict__ :)
55 setattr(self, 'id', cls.id)
56 cls.id += 1
58 self.matches = {} # for matching rules
59 self.not_matches = {} # for rules that should NOT match
60 self.writing_properties = {}
62 # Get teh properties of the Class we want
63 if not 'creation_type' in params:
64 params['creation_type'] = 'service'
66 map = {'service' : Service, 'host' : Host}
67 t = params['creation_type']
68 if not t in map:
69 return
70 tcls = map[t]
72 # In my own property :
73 # -> in __dict__
74 # In the properties of the 'creation_type' Class:
75 # -> in self.writing_properties
76 # if not, in matches or not match (if key starts
77 # with a !, it's a not rule)
78 # -> in self.matches or self.not_matches
79 for key in params:
80 # Some key are quite special
81 if key in ['use']:
82 self.writing_properties[key] = params[key]
83 elif key in cls.properties:
84 setattr(self, key, params[key])
85 elif key in tcls.properties:
86 self.writing_properties[key] = params[key]
87 else:
88 if key.startswith('!'):
89 key = key.split('!')[1]
90 self.not_matches[key] = params['!'+key]
91 else:
92 self.matches[key] = params[key]
95 # Output name
96 def get_name(self):
97 try:
98 return self.discoveryrule_name
99 except AttributeError:
100 return "UnnamedDiscoveryRule"
103 # Try to see if the key,value is matching one or
104 # our rule. If value got ',' we must look for each value
105 # If one match, we quit
106 # We can find in matches or not_matches
107 def is_matching(self, key, value, look_in='matches'):
108 if look_in == 'matches':
109 d = self.matches
110 else:
111 d = self.not_matches
112 # If we do not even have the key, we bailout
113 if not key.strip() in d:
114 return False
116 # Get my matching patern
117 m = d[key]
118 if ',' in m:
119 matchings = [mt.strip() for mt in m.split(',')]
120 else:
121 matchings = [m]
123 # Split the alue by , too
124 values = value.split(',')
125 for m in matchings:
126 for v in values:
127 #print "Try to match", m, v
128 if re.search(m, v):
129 return True
130 return False
133 # Look if we match all discovery data or not
134 # a disco data look as a list of (key, values)
135 def is_matching_disco_datas(self, datas):
136 # If we got not data, no way we can match
137 if len(datas) == 0:
138 return False
140 # First we look if it's possible to match
141 # we must match All self.matches things
142 for m in self.matches:
143 #print "Compare to", m
144 match_one = False
145 for (k, v) in datas:
146 # We found at least one of our match key
147 if m == k:
148 if self.is_matching(k, v):
149 #print "Got matching with", m, k, v
150 match_one = True
151 continue
152 if not match_one:
153 # It match none
154 #print "Match none, FAlse"
155 return False
156 #print "It's possible to be OK"
158 # And now look if ANY of not_matches is reach. If so
159 # it's False
160 for m in self.not_matches:
161 #print "Compare to NOT", m
162 match_one = False
163 for (k, v) in datas:
164 #print "K,V", k,v
165 # We found at least one of our match key
166 if m == k:
167 #print "Go loop"
168 if self.is_matching(k, v, look_in='not_matches'):
169 #print "Got matching with", m, k, v
170 match_one = True
171 continue
172 if match_one:
173 #print "I match one, I quit"
174 return False
176 # Ok we match ALL rules in self.matches
177 # and NONE of self.not_matches, we can go :)
178 return True
184 class Discoveryrules(Items):
185 name_property = "discoveryrule_name"
186 inner_class = Discoveryrule