Project

General

Profile

prewikka.diff

Yoann VANDOORSELAERE, 06/09/2009 12:40 PM

Download (22.7 KB)

View differences:

prewikka/IDMEFDatabase.py
36 36
class IDMEFTime(object):
37 37
    def __init__(self, res):
38 38
        self._res = res
39
        
39

  
40 40
    def __del__(self):
41 41
        idmef_time_destroy(self._res)
42 42

  
......
45 45

  
46 46
    def __int__(self):
47 47
        return idmef_time_get_sec(self._res)
48
                
48

  
49 49
    def __float__(self):
50 50
        return float(idmef_time_get_sec(self._res)) + float(idmef_time_get_usec(self._res)) / 10 ** 6
51
        
51

  
52 52
    def toYMDHMS(self):
53 53
        return time_to_ymdhms(time.localtime(idmef_time_get_sec(self._res)))
54
        
54

  
55 55
    def __getattribute__(self, name):
56 56
        if name is "sec":
57 57
            return idmef_time_get_sec(self._res)
......
98 98
    except KeyError:
99 99
        return None
100 100

  
101
    
102
        
101

  
102

  
103 103
class Message:
104 104
    def __init__(self, res, htmlsafe):
105 105
        self._res = res
106 106
        self._value_list = None
107 107
        self._htmlsafe = htmlsafe
108
        
108

  
109 109
    def __del__(self):
110 110
        idmef_message_destroy(self._res)
111 111

  
......
115 115
    def __iter__(self):
116 116
        if not self._value_list:
117 117
            raise TypeError, "iteration over a non-sequence"
118
        
118

  
119 119
        self._list_iterator = 0
120 120
        return self
121 121

  
......
124 124
            return idmef_value_get_count(self._value_list)
125 125

  
126 126
        return 1
127
    
127

  
128 128
    def next(self):
129 129
        next = idmef_value_get_nth(self._value_list, self._list_iterate)
130 130
        if not next:
......
132 132

  
133 133
        value = self._convert_value(next, self._root + "(%d)" % self._list_iterate)
134 134
        self._list_iterate += 1
135
        
135

  
136 136
        return value
137 137

  
138 138
    def _convert_value(self, idmef_value, key):
......
143 143
            value._value_list = idmef_value
144 144
            if self._value_list:
145 145
                idmef_value_ref(idmef_value)
146
                
146

  
147 147
        elif idmef_value_get_type(idmef_value) != IDMEF_VALUE_TYPE_CLASS:
148 148
            value = convert_idmef_value(idmef_value)
149 149
            if not self._value_list:
150 150
                idmef_value_destroy(idmef_value)
151
            
151

  
152 152
        else:
153 153
            if not self._value_list:
154 154
                idmef_value_destroy(idmef_value)
155
                
155

  
156 156
            value = Message(idmef_message_ref(self._res), self._htmlsafe)
157 157
            value._root = key
158 158

  
159 159
        return value
160
    
160

  
161 161
    def _get_raw_value(self, key):
162 162
        path = idmef_path_new_fast(key)
163 163
        idmef_value = idmef_path_get(path, self._res)
164
        
164

  
165 165
        if idmef_value:
166 166
            ret = self._convert_value(idmef_value, key)
167 167
        else:
168
            if idmef_path_is_list(path, -1):
168
            if idmef_path_is_ambiguous(path):
169 169
                ret = []
170 170
            else:
171 171
                ret = None
172
            
172

  
173 173
        idmef_path_destroy(path)
174 174
        return ret
175 175

  
......
181 181
            return escape_value(self._get_raw_value(key))
182 182
        else:
183 183
            return self._get_raw_value(key)
184
             
184

  
185 185
    def match(self, criteria):
186 186
        if type(criteria) is list:
187 187
            criteria = " && ".join(criteria)
......
192 192

  
193 193
        return ret
194 194

  
195
    def get(self, key, default=None, htmlsafe=None):     
195
    def get(self, key, default=None, htmlsafe=None):
196 196
        if htmlsafe != None:
197 197
            htmlsafe_bkp = self._htmlsafe
198 198
            self._htmlsafe = htmlsafe
199
            
200
        val = self[key] 
199

  
200
        val = self[key]
201 201
        if val == None:
202 202
                val = default
203
        
203

  
204 204
        if htmlsafe != None:
205 205
            self._htmlsafe = htmlsafe_bkp
206
        
206

  
207 207
        return val
208 208

  
209 209
    def getAdditionalData(self, searched, many_values=False):
......
213 213
            meaning = self["%s.additional_data(%d).meaning" % (self._root, i)]
214 214
            if meaning is None:
215 215
                break
216
            
216

  
217 217
            if meaning == searched:
218 218
                value = self["%s.additional_data(%d).data" % (self._root, i)]
219
                
219

  
220 220
                if not many_values:
221 221
                    return value
222
                
222

  
223 223
                values.append(value)
224 224

  
225 225
            i += 1
......
252 252
        self._rows = [ ]
253 253
        self._has_cache = False
254 254
        self._res, self._len = results
255
        
255

  
256 256
    def __iter__(self):
257 257
        if self._has_cache:
258 258
            return iter(self._rows)
259 259
        else:
260 260
            return self
261
        
261

  
262 262
    def __len__(self):
263 263
        return self._len
264
       
264

  
265 265
    def __del__(self):
266 266
        if self._res:
267 267
            self._db_delete(self._res)
268
        
268

  
269 269
    def __getitem__(self, key):
270 270
        if isinstance(key, types.SliceType):
271 271
            start, stop, step = key.start, key.stop, key.step
272 272
            index = start + stop
273 273
        else:
274 274
            index = key
275
        
275

  
276 276
        if not self._has_cache:
277 277
            for r in self:
278 278
                if len(self._rows) >= index:
279 279
                    break
280
                
280

  
281 281
        return self._rows[key]
282
        
283
    def next(self):        
282

  
283
    def next(self):
284 284
        if self._res == None:
285 285
            raise StopIteration
286 286

  
......
292 292
            raise StopIteration
293 293

  
294 294
        row = self._db_convert_row(values)
295
       
295

  
296 296
        self._rows.append(row)
297 297
        return row
298
            
298

  
299 299

  
300 300
class DbResultValues(DbResult):
301 301
    def __init__(self, selection, results):
302 302
        self._selection = selection
303 303
        DbResult.__init__(self, results)
304
                
304

  
305 305
    def _db_get_next(self):
306 306
        return preludedb_result_values_get_next(self._res)
307
        
307

  
308 308
    def _db_delete(self, result):
309 309
        if self._selection:
310 310
            preludedb_path_selection_destroy(self._selection)
311
            
311

  
312 312
        if result:
313 313
            preludedb_result_values_destroy(result)
314
            
314

  
315 315
    def _db_convert_row(self, values):
316 316
        row = []
317 317
        for value in values:
......
319 319
               row.append(None)
320 320
           else:
321 321
               row.append(convert_idmef_value(value))
322
               idmef_value_destroy(value)      
323
               
322
               idmef_value_destroy(value)
323

  
324 324
        return row
325
        
325

  
326 326
class DbResultIdents(DbResult):
327 327
    def _db_get_next(self):
328 328
        return preludedb_result_idents_get_next(self._res)
329
        
329

  
330 330
    def _db_delete(self, result):
331 331
        if result:
332 332
            preludedb_result_idents_destroy(result)
333
                    
333

  
334 334
    def _db_convert_row(self, value):
335 335
        return value
336 336

  
337 337
class IDMEFDatabase:
338 338
    _db_destroy = preludedb_destroy
339 339
    _db = None
340
    
340

  
341 341
    def __init__(self, config):
342 342
        settings = preludedb_sql_settings_new()
343 343
        for param in "file", "host", "port", "name", "user", "pass":
......
360 360
                raise "libpreludedb %s or higher is required (%s found)." % (wanted_version, cur)
361 361
            else:
362 362
                raise "libpreludedb %s or higher is required." % wanted_version
363
        
363

  
364 364
        self._db = preludedb_new(sql, None)
365 365

  
366 366
    def __del__(self):
367 367
        if self._db:
368 368
            self._db_destroy(self._db)
369
            
369

  
370 370
    def _getMessageIdents(self, get_message_idents, criteria, limit, offset, order_by):
371 371
        if type(criteria) is list:
372 372
            if len(criteria) == 0:
373 373
                criteria = None
374 374
            else:
375 375
                criteria = " && ".join(criteria)
376
                
376

  
377 377
        if criteria:
378 378
            criteria = idmef_criteria_new_from_string(criteria)
379 379

  
380 380
        idents = [ ]
381
    
381

  
382 382
        if order_by == "time_asc":
383 383
            order_by = PRELUDEDB_RESULT_IDENTS_ORDER_BY_CREATE_TIME_ASC
384 384
        else:
385 385
            order_by = PRELUDEDB_RESULT_IDENTS_ORDER_BY_CREATE_TIME_DESC
386
            
387
        try:    
386

  
387
        try:
388 388
            result = get_message_idents(self._db, criteria, limit, offset, order_by)
389 389
        except:
390 390
            self._freeDbParams(criteria=criteria)
391 391
            raise
392
                    
392

  
393 393
        if criteria:
394 394
            idmef_criteria_destroy(criteria)
395
        
395

  
396 396
        if not result:
397
            return [ ]            
398
        
397
            return [ ]
398

  
399 399
        return DbResultIdents(result)
400
        
400

  
401 401
    def getAlertIdents(self, criteria=None, limit=-1, offset=-1, order_by="time_desc"):
402 402
        return self._getMessageIdents(preludedb_get_alert_idents2, criteria, limit, offset, order_by)
403 403

  
......
406 406

  
407 407
    def _getLastMessageIdent(self, type, get_message_idents, analyzerid):
408 408
        criteria = None
409
        if analyzerid != None:
410
            criteria = "%s.analyzer(-1).analyzerid == '%s'" % (type, str(analyzerid))
409
        if analyzerid is not False:
410
            if analyzerid is None:
411
                criteria = "! %s.analyzer(-1).analyzerid" % (type)
412
            else:
413
                criteria = "%s.analyzer(-1).analyzerid == '%s'" % (type, str(analyzerid))
411 414

  
412 415
        idents = get_message_idents(criteria, limit=1)
413 416

  
414 417
        return idents[0]
415 418

  
416
    def getLastAlertIdent(self, analyzer=None):
419
    def getLastAlertIdent(self, analyzer=False):
417 420
        return self._getLastMessageIdent("alert", self.getAlertIdents, analyzer)
418 421

  
419
    def getLastHeartbeatIdent(self, analyzer=None):
422
    def getLastHeartbeatIdent(self, analyzer=False):
420 423
        return self._getLastMessageIdent("heartbeat", self.getHeartbeatIdents, analyzer)
421 424

  
422 425
    def getAlert(self, ident, htmlsafe=False):
......
442 445
    def _freeDbParams(self, selection=None, criteria=None):
443 446
        if selection:
444 447
            preludedb_path_selection_destroy(selection)
445
        
448

  
446 449
        if criteria:
447 450
            idmef_criteria_destroy(criteria)
448
            
451

  
449 452
    def getValues(self, selection, criteria=None, distinct=0, limit=-1, offset=-1):
450 453
        if type(criteria) is list:
451 454
            if len(criteria) == 0:
452 455
                criteria = None
453 456
            else:
454 457
                criteria = " && ".join([ "(" + c + ")" for c in criteria ])
455
                            
458

  
456 459
        if criteria:
457 460
            criteria = idmef_criteria_new_from_string(criteria)
458
            
461

  
459 462
        my_selection = preludedb_path_selection_new()
460 463
        for selected in selection:
461 464
            my_selected = preludedb_selected_path_new_string(selected)
......
466 469
        except:
467 470
            self._freeDbParams(my_selection, criteria)
468 471
            raise
469
            
472

  
470 473
        if criteria:
471
            idmef_criteria_destroy(criteria)       
472
        
474
            idmef_criteria_destroy(criteria)
475

  
473 476
        if not result:
474 477
            preludedb_path_selection_destroy(my_selection)
475 478
            return [ ]
476
            
479

  
477 480
        return DbResultValues(my_selection, result)
478
        
481

  
479 482
    def _countMessages(self, root, criteria):
480 483
        return self.getValues(["count(%s.create_time)" % root], criteria)[0][0]
481
        
484

  
482 485
    def countAlerts(self, criteria=None):
483 486
        return self._countMessages("alert", criteria)
484 487

  
......
511 514
                index += 1
512 515
            analyzer_paths.append(path)
513 516

  
514
        return analyzer_paths            
517
        return analyzer_paths
515 518

  
516 519
    def getAnalyzer(self, analyzerid):
517 520
        ident = self.getLastHeartbeatIdent(analyzerid)
518 521
        heartbeat = self.getHeartbeat(ident)
519 522

  
520
        index = 0
521
        while True:
522
            if not heartbeat["heartbeat.analyzer(%d).name" % (index + 1)]:
523
                break
524
            index += 1
525

  
526
        analyzer = { }
527
        analyzer["analyzerid"] = analyzerid
528
        analyzer["name"] = heartbeat.get("heartbeat.analyzer(%d).name" % index)
529
        analyzer["model"] = heartbeat.get("heartbeat.analyzer(%d).model" % index) 
530
        analyzer["version"] = heartbeat.get("heartbeat.analyzer(%d).version" % index)
531
        analyzer["class"] = heartbeat.get("heartbeat.analyzer(%d).class" % index)
532
        analyzer["ostype"] = heartbeat.get("heartbeat.analyzer(%d).ostype" % index)
533
        analyzer["osversion"] = heartbeat.get("heartbeat.analyzer(%d).osversion" % index)
534
        analyzer["node_name"] = heartbeat.get("heartbeat.analyzer(%d).node.name" % index)
535
        analyzer["node_location"] = heartbeat.get("heartbeat.analyzer(%d).node.location" % index)
536
                
537
        i = 0
538
        analyzer["node_addresses"] = [ ]
539
        while True:
540
            address = heartbeat.get("heartbeat.analyzer(%d).node.address(%d).address" % (index, i))
541
            if not address:
523
        path = []
524
        prev = None
525

  
526
        for analyzer in heartbeat["analyzer"]:
527
            if analyzer["analyzerid"]:
528
                path.append(analyzer["analyzerid"])
529

  
530
            if not analyzer["name"]:
542 531
                break
543
            analyzer["node_addresses"].append(address)
544
            i += 1
545
        
546
        analyzer["last_heartbeat_time"] = heartbeat.get("heartbeat.create_time")
547
        analyzer["last_heartbeat_interval"] = heartbeat["heartbeat.heartbeat_interval"]
548
        analyzer["last_heartbeat_status"] = heartbeat.getAdditionalData("Analyzer status")
549
        
550
        return analyzer
532

  
533
            prev = analyzer
534

  
535
        analyzer = prev
536
        analyzerd = { "analyzerid": analyzerid, "path": path, "node_addresses": [] }
537

  
538
        for column in "name", "model", "version", "class", "ostype", "osversion", "node.name", "node.location":
539
            analyzerd[column] = analyzer[column]
540

  
541
        for addr in analyzer["node.address.address"]:
542
            analyzerd["node_addresses"].append(addr)
543

  
544
        analyzerd["last_heartbeat_time"] = heartbeat.get("heartbeat.create_time")
545
        analyzerd["last_heartbeat_interval"] = heartbeat.get("heartbeat.heartbeat_interval")
546
        analyzerd["last_heartbeat_status"] = heartbeat.getAdditionalData("Analyzer status")
547

  
548
        return analyzerd
prewikka/views/sensor.py
55 55

  
56 56
    if time.time() - int(heartbeat_time) > int(heartbeat_interval) + error_margin:
57 57
        return "missing", _("Missing")
58
    
58

  
59 59
    return "online", _("Online")
60 60

  
61 61

  
62 62
def analyzer_cmp(x, y):
63 63
    xmiss = x["status"] == "missing"
64 64
    ymiss = y["status"] == "missing"
65
    
65

  
66 66
    if xmiss and ymiss:
67 67
        return cmp(x["name"], y["name"])
68
        
68

  
69 69
    elif xmiss or ymiss:
70 70
        return ymiss - xmiss
71
        
71

  
72 72
    else:
73 73
        return cmp(x["name"], y["name"])
74
        
74

  
75 75
def node_cmp(x, y):
76 76
    xmiss = x["missing"]
77 77
    ymiss = y["missing"]
78
    
78

  
79 79
    if xmiss or ymiss:
80
        return ymiss - xmiss        
80
        return ymiss - xmiss
81 81
    else:
82 82
        return cmp(x["node_name"], y["node_name"])
83 83

  
......
98 98
    def init(self, env):
99 99
        self._heartbeat_count = int(env.config.general.getOptionValue("heartbeat_count", 30))
100 100
        self._heartbeat_error_margin = int(env.config.general.getOptionValue("heartbeat_error_margin", 3))
101
    
102
        
101

  
103 102
    def render(self):
104 103
        analyzers = { }
105 104

  
......
110 109

  
111 110
        locations = { }
112 111
        nodes = { }
113
        
114
        for analyzer_path in self.env.idmef_db.getAnalyzerPaths():
115
            analyzerid = analyzer_path[-1]          
112

  
113
        for analyzerid in self.env.idmef_db.getAnalyzerids():
116 114
            analyzer = self.env.idmef_db.getAnalyzer(analyzerid)
117
            
115

  
118 116
            parameters = { "analyzerid": analyzer["analyzerid"] }
119 117
            analyzer["alert_listing"] = utils.create_link("sensor_alert_listing", parameters)
120 118
            analyzer["heartbeat_listing"] = utils.create_link("sensor_heartbeat_listing", parameters)
121 119
            analyzer["heartbeat_analyze"] = utils.create_link("heartbeat_analyze", parameters)
122 120

  
123
            if analyzer["node_name"]:
121
            if analyzer["node.name"]:
124 122
                analyzer["node_name_link"] = utils.create_link(self.view_name,
125 123
                                                               { "filter_path": "heartbeat.analyzer(-1).node.name",
126
                                                                 "filter_value": analyzer["node_name"] })
127
                 
128
            if analyzer["node_location"]:
124
                                                                 "filter_value": analyzer["node.name"] })
125

  
126
            if analyzer["node.location"]:
129 127
                analyzer["node_location_link"] = utils.create_link(self.view_name,
130 128
                                                                   { "filter_path": "heartbeat.analyzer(-1).node.location",
131
                                                                     "filter_value": analyzer["node_location"] })
132
                
129
                                                                     "filter_value": analyzer["node.location"] })
130

  
133 131
            node_key = ""
134 132
            for i in range(len(analyzer["node_addresses"])):
135 133
                addr = analyzer["node_addresses"][i]
136 134
                node_key += addr
137
                
135

  
138 136
                analyzer["node_addresses"][i] = {}
139 137
                analyzer["node_addresses"][i]["value"] = addr
140 138
                analyzer["node_addresses"][i]["inline_filter"] = utils.create_link(self.view_name,
......
147 145
                                                                           utils.create_link("Command",
148 146
                                                                                             { "origin": self.view_name,
149 147
                                                                                               "command": command, "host": addr })))
150
            
148

  
151 149
            analyzer["status"], analyzer["status_meaning"] = \
152 150
                                get_analyzer_status_from_latest_heartbeat(analyzer["last_heartbeat_status"],
153 151
                                                                          analyzer["last_heartbeat_time"],
......
156 154

  
157 155
            analyzer["last_heartbeat_time"] = utils.time_to_ymdhms(time.localtime(int(analyzer["last_heartbeat_time"]))) + \
158 156
                                              " %+.2d:%.2d" % utils.get_gmt_offset()
159
       
160
            node_location = analyzer["node_location"] or _("Node location n/a")
161
            node_name = analyzer.get("node_name") or _("Node name n/a")
157

  
158
            node_location = analyzer["node.location"] or _("Node location n/a")
159
            node_name = analyzer.get("node.name") or _("Node name n/a")
162 160
            osversion = analyzer["osversion"] or _("OS version n/a")
163 161
            ostype = analyzer["ostype"] or _("OS type n/a")
164 162
            addresses = analyzer["node_addresses"]
165
            
163

  
166 164
            node_key = node_name + osversion + ostype
167
            
165

  
168 166
            if not locations.has_key(node_location):
169 167
                locations[node_location] = { "total": 1, "missing": 0, "unknown": 0, "offline": 0, "online": 0, "nodes": { } }
170 168
            else:
......
174 172
                locations[node_location]["nodes"][node_key] = { "total": 1, "missing": 0, "unknown": 0, "offline": 0, "online": 0,
175 173
                                                                "analyzers": [ ],
176 174
                                                                "node_name": node_name, "node_location": node_location,
177
                                                                "ostype": ostype, "osversion": osversion, 
175
                                                                "ostype": ostype, "osversion": osversion,
178 176
                                                                "node_addresses": addresses, "node_key": node_key }
179 177
            else:
180 178
                locations[node_location]["nodes"][node_key]["total"] += 1
181
                  
179

  
182 180
            status = analyzer["status"]
183 181
            locations[node_location][status] += 1
184 182
            locations[node_location]["nodes"][node_key][status] += 1
......
187 185
                locations[node_location]["nodes"][node_key]["analyzers"].insert(0, analyzer)
188 186
            else:
189 187
                locations[node_location]["nodes"][node_key]["analyzers"].append(analyzer)
190
                
188

  
191 189
        self.dataset["locations"] = locations
192
        
190

  
193 191

  
194 192
class SensorMessagesDelete(SensorListing):
195 193
    view_name = "sensor_messages_delete"
......
205 203
            if self.parameters.has_key("heartbeats"):
206 204
                criteria = "heartbeat.analyzer(-1).analyzerid == %d" % long(analyzerid)
207 205
                self.env.idmef_db.deleteHeartbeat(self.env.idmef_db.getHeartbeatIdents(criteria))
208
            
206

  
209 207
        SensorListing.render(self)
210 208

  
211 209

  
......
219 217
    def init(self, env):
220 218
        self._heartbeat_count = int(env.config.general.getOptionValue("heartbeat_count", 30))
221 219
        self._heartbeat_error_margin = int(env.config.general.getOptionValue("heartbeat_error_margin", 3))
222
    
220

  
223 221
    def render(self):
224 222
        analyzerid = self.parameters["analyzerid"]
225
        
223

  
226 224
        analyzer = self.env.idmef_db.getAnalyzer(analyzerid)
227 225
        analyzer["last_heartbeat_time"] = str(analyzer["last_heartbeat_time"])
228 226
        analyzer["events"] = [ ]
229 227
        analyzer["status"] = "abnormal_offline"
230 228
        analyzer["status_meaning"] = "abnormal offline"
231
        
229

  
232 230
        start = time.time()
233 231
        idents = self.env.idmef_db.getHeartbeatIdents(criteria="heartbeat.analyzer(-1).analyzerid == %d" % analyzerid,
234 232
                                                      limit=self._heartbeat_count)
......
254 252
                    analyzer["events"].append({ "value": "sensor is down since %s" % older_time, "type": "down"})
255 253
            if newer:
256 254
                event = None
257
                
255

  
258 256
                if newer_status == "starting":
259 257
                    if older_status == "exiting":
260 258
                        event = { "value": "normal sensor start at %s" % str(newer_time),
......
267 265
                    if abs(int(newer_time) - int(older_time) - int(older_interval)) > self._heartbeat_error_margin:
268 266
                        event = { "value": "abnormal heartbeat interval between %s and %s" % (str(older_time), str(newer_time)),
269 267
                                  "type": "abnormal_heartbeat_interval" }
270
                                  
268

  
271 269

  
272 270
                if newer_status == "exiting":
273 271
                    event = { "value": "normal sensor stop at %s" % str(newer_time),