File: snmp_device_alert_store.lua

package info (click to toggle)
ntopng 5.2.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 121,832 kB
  • sloc: javascript: 143,431; cpp: 71,175; ansic: 11,108; sh: 4,687; makefile: 911; python: 587; sql: 512; pascal: 234; perl: 118; ruby: 52; exp: 4
file content (163 lines) | stat: -rw-r--r-- 5,124 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
--
-- (C) 2021-22 - ntop.org
--

local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path

-- Import the classes library.
local classes = require "classes"

require "lua_utils"
local alert_store = require "alert_store"
local format_utils = require "format_utils"
local alert_consts = require "alert_consts"
local alert_utils = require "alert_utils"
local alert_entities = require "alert_entities"
local snmp_utils = require "snmp_utils"
local json = require "dkjson"

-- ##############################################

local snmp_device_alert_store = classes.class(alert_store)

-- ##############################################

function snmp_device_alert_store:init(args)
   self.super:init()

   self._table_name = "snmp_alerts"
   self._alert_entity = alert_entities.snmp_device
end

-- ##############################################

function snmp_device_alert_store:_entity_val_to_ip_and_port(entity_val)
   local ip_port = string.split(entity_val, "_ifidx")
   local ip, port = ip_port[1], tonumber(ip_port[2])

   return ip, port
end

-- ##############################################

function snmp_device_alert_store:insert(alert)
   local device_ip
   local device_name
   local port
   local port_name

   if not isEmptyString(alert.json) then
      local snmp_json = json.decode(alert.json)
      if snmp_json then
         device_ip = snmp_json.device
         device_name = snmp_json.device_name
         port = snmp_json.interface
         port_name = snmp_json.interface_name
      end
   end

   if isEmptyString(device_ip) then
      -- Extract them from the entity value
      device_ip, port = self:_entity_val_to_ip_and_port(alert.entity_val)
   end

   local insert_stmt = string.format("INSERT INTO %s "..
      "(alert_id, interface_id, tstamp, tstamp_end, severity, score, ip, name, port, port_name, json) "..
      "VALUES (%u, %d, %u, %u, %u, %u, '%s', '%s', %u, '%s', '%s'); ",
      self._table_name, 
      alert.alert_id,
      self:_convert_ifid(interface.getId()),
      alert.tstamp,
      alert.tstamp_end,
      ntop.mapScoreToSeverity(alert.score),
      alert.score,
      self:_escape(device_ip or alert.entity_val),
      self:_escape(device_name),
      port or 0,
      self:_escape(port_name),
      self:_escape(alert.json))

   -- traceError(TRACE_NORMAL, TRACE_CONSOLE, insert_stmt)

   return interface.alert_store_query(insert_stmt)
end

-- ##############################################

--@brief Add filters according to what is specified inside the REST API
function snmp_device_alert_store:_add_additional_request_filters()
   -- Add filters specific to the snmp family
end

-- ##############################################

local RNAME = {
   IP = { name = "ip", export = true},
   NAME = { name = "name", export = true},
   PORT = { name = "port", export = true, elements = {"value", "label"}},
   ALERT_NAME = { name = "alert_name", export = true},
   DESCRIPTION = { name = "description", export = true},
   MSG = { name = "msg", export = true, elements = {"name", "value", "description"}}
}

function snmp_device_alert_store:get_rnames()
   return RNAME
end

-- ##############################################

--@brief Convert an alert coming from the DB (value) to a record returned by the REST API
function snmp_device_alert_store:format_record(value, no_html)
   if not value["ip"] then
      -- This is an in-memory engaged alert, let's extract the ip and the port from the entity_val
      value["ip"], value["port"] = self:_entity_val_to_ip_and_port(value["entity_val"])
   end

   -- Suppress zero ports
   value["port"] = tonumber(value["port"])
   if value["port"] == 0 then
      value["port"] = ""
   end

   -- If there's no port name stored, use the id
   if isEmptyString(value["port_name"]) then
      value["port_name"] = value["port"]
   end

   local record = self:format_json_record_common(value, alert_entities.snmp_device.entity_id, no_html)

   local alert_info = alert_utils.getAlertInfo(value)
   local alert_name = alert_consts.alertTypeLabel(tonumber(value["alert_id"]), no_html, alert_entities.snmp_device.entity_id)
   local alert_fullname = alert_consts.alertTypeLabel(tonumber(value["alert_id"]), true, alert_entities.snmp_device.entity_id)
   local msg = alert_utils.formatAlertMessage(ifid, value, alert_info)

   record[RNAME.IP.name] = value["ip"]
   record[RNAME.NAME.name] = snmp_utils.get_snmp_device_sysname(value["ip"]) or ""
   record[RNAME.PORT.name] = {
      value = value["port"],
      label = value["port_name"] or value["port"]
   }

   record[RNAME.ALERT_NAME.name] = alert_name

   if string.lower(noHtml(msg)) == string.lower(noHtml(alert_name)) then
      msg = ""
   end

   record[RNAME.DESCRIPTION.name] = msg

   record[RNAME.MSG.name] = {
     name = noHtml(alert_name),
     fullname = alert_fullname,
     value = tonumber(value["alert_id"]),
     description = msg,
     configset_ref = alert_utils.getConfigsetAlertLink(alert_info)
   }

   return record
end

-- ##############################################

return snmp_device_alert_store