logstash-input-snmp 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTORS +1 -0
- data/lib/logstash/inputs/snmp.rb +36 -1
- data/lib/logstash/inputs/snmp/base_client.rb +47 -3
- data/logstash-input-snmp.gemspec +1 -1
- data/spec/inputs/snmp_spec.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 213be86518d3d8a674d4227ff23cad9fac2be281fe2d79e9cd6a2e3bc1415b62
|
4
|
+
data.tar.gz: 1334457e8ebfcd7c979fa5bd53870af0205df9fe0842dd1f7e7d4598b653961b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5630fc5e10d784ba79700e2f11216b660194e36317e06ba6060f1459f3825719b28514324e212378a69dcc5b257c8efdaba889c6f65093560a2ae7d51f124314
|
7
|
+
data.tar.gz: 0a888058d97613735f4eb4188963a73e907fa354a7799529153d00c51e58d15a6a232bcc7c0d22eaa8065a3798d3bb48d1f1b5535057e08b4b521647590bac91
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 1.1.0
|
2
|
+
- Added support for querying SNMP tables
|
3
|
+
- Changed three error messages in the base_client to include the target address for clarity in the logs.
|
4
|
+
|
1
5
|
## 1.0.1
|
2
6
|
- Added no_codec condition to the documentation and bumped version [#39](https://github.com/logstash-plugins/logstash-input-snmp/pull/39)
|
3
7
|
- Changed docs to improve options layout [#38](https://github.com/logstash-plugins/logstash-input-snmp/pull/38)
|
data/CONTRIBUTORS
CHANGED
@@ -3,6 +3,7 @@ reports, or in general have helped logstash along its way.
|
|
3
3
|
|
4
4
|
Contributors:
|
5
5
|
* Colin Surprenant - colin.surprenant@gmail.com
|
6
|
+
* Dan Major - axrayn@gmail.com
|
6
7
|
|
7
8
|
Note: If you've sent us patches, bug reports, or otherwise contributed to
|
8
9
|
Logstash, and you aren't on the list above and want to be, please let us know
|
data/lib/logstash/inputs/snmp.rb
CHANGED
@@ -20,6 +20,9 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
|
|
20
20
|
# List of OIDs for which we want to retrieve the subtree of information
|
21
21
|
config :walk,:validate => :array # ["1.3.6.1.2.1.1.1.0"]
|
22
22
|
|
23
|
+
# List of tables to walk
|
24
|
+
config :tables, :validate => :array #[ {"name" => "interfaces" "columns" => ["1.3.6.1.2.1.2.2.1.1", "1.3.6.1.2.1.2.2.1.2", "1.3.6.1.2.1.2.2.1.5"]} ]
|
25
|
+
|
23
26
|
# List of hosts to query the configured `get` and `walk` options.
|
24
27
|
#
|
25
28
|
# Each host definition is a hash and must define the `host` key and value.
|
@@ -91,6 +94,7 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
|
|
91
94
|
def register
|
92
95
|
validate_oids!
|
93
96
|
validate_hosts!
|
97
|
+
validate_tables!
|
94
98
|
|
95
99
|
mib = LogStash::SnmpMib.new
|
96
100
|
|
@@ -172,6 +176,16 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
|
|
172
176
|
end
|
173
177
|
end
|
174
178
|
|
179
|
+
if !Array(@tables).empty?
|
180
|
+
@tables.each do |table_entry|
|
181
|
+
begin
|
182
|
+
result = result.merge(definition[:client].table(table_entry, @oid_root_skip))
|
183
|
+
rescue => e
|
184
|
+
logger.error("error invoking table operation on OID: #{table_entry['name']}, ignoring", :exception => e, :backtrace => e.backtrace)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
175
189
|
unless result.empty?
|
176
190
|
metadata = {
|
177
191
|
"host_protocol" => definition[:host_protocol],
|
@@ -217,7 +231,20 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
|
|
217
231
|
$1
|
218
232
|
end
|
219
233
|
|
220
|
-
|
234
|
+
if !@tables.nil?
|
235
|
+
@tables.each do |table_entry|
|
236
|
+
# Verify oids for valid pattern and get rid of any leading dot if present
|
237
|
+
columns = table_entry["columns"]
|
238
|
+
columns.each do |column|
|
239
|
+
unless column =~ OID_REGEX
|
240
|
+
raise(Logstash::ConfigurationError, "The table column oid '#{column}' is an invalid format")
|
241
|
+
end
|
242
|
+
end
|
243
|
+
$1
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
raise(LogStash::ConfigurationError, "at least one get OID, one walk OID, or one table OID is required") if @get.empty? && @walk.empty? && @tables.nil?
|
221
248
|
end
|
222
249
|
|
223
250
|
def validate_v3_user!
|
@@ -242,4 +269,12 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
|
|
242
269
|
raise(LogStash::ConfigurationError, "each host definition must have a \"host\" option") if !host.is_a?(Hash) || host["host"].nil?
|
243
270
|
end
|
244
271
|
end
|
272
|
+
|
273
|
+
def validate_tables!
|
274
|
+
if !@tables.nil?
|
275
|
+
@tables.each do |table_entry|
|
276
|
+
raise(LogStash::ConfigurationError, "each table definition must have a \"name\" option") if !table_entry.is_a?(Hash) || table_entry["name"].nil?
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
245
280
|
end
|
@@ -18,6 +18,7 @@ java_import "org.snmp4j.smi.OctetString"
|
|
18
18
|
java_import "org.snmp4j.smi.VariableBinding"
|
19
19
|
java_import "org.snmp4j.transport.DefaultUdpTransportMapping"
|
20
20
|
java_import "org.snmp4j.transport.DefaultTcpTransportMapping"
|
21
|
+
java_import "org.snmp4j.util.TableUtils"
|
21
22
|
java_import "org.snmp4j.util.TreeUtils"
|
22
23
|
java_import "org.snmp4j.util.DefaultPDUFactory"
|
23
24
|
java_import "org.snmp4j.asn1.BER"
|
@@ -52,11 +53,11 @@ module LogStash
|
|
52
53
|
return nil if response_event.nil?
|
53
54
|
|
54
55
|
e = response_event.getError
|
55
|
-
raise(SnmpClientError, "error sending snmp get request: #{e.inspect}, #{e.getMessage}") if e
|
56
|
+
raise(SnmpClientError, "error sending snmp get request to target #{@target.address}: #{e.inspect}, #{e.getMessage}") if e
|
56
57
|
|
57
58
|
result = {}
|
58
59
|
response_pdu = response_event.getResponse
|
59
|
-
raise(SnmpClientError, "timeout sending snmp get request") if response_pdu.nil?
|
60
|
+
raise(SnmpClientError, "timeout sending snmp get request to target #{@target.address}") if response_pdu.nil?
|
60
61
|
|
61
62
|
size = response_pdu.size
|
62
63
|
(0..size - 1).each do |i|
|
@@ -85,7 +86,7 @@ module LogStash
|
|
85
86
|
|
86
87
|
if event.isError
|
87
88
|
# TODO: see if we can salvage non errored event here
|
88
|
-
raise(SnmpClientError, "error sending snmp walk request: #{event.getErrorMessage}")
|
89
|
+
raise(SnmpClientError, "error sending snmp walk request to target #{@target.address}: #{event.getErrorMessage}")
|
89
90
|
end
|
90
91
|
|
91
92
|
var_bindings = event.getVariableBindings
|
@@ -105,6 +106,49 @@ module LogStash
|
|
105
106
|
result
|
106
107
|
end
|
107
108
|
|
109
|
+
def table(table, strip_root = 0)
|
110
|
+
result = {}
|
111
|
+
rows = []
|
112
|
+
pdufactory = get_pdu_factory
|
113
|
+
table_name = table["name"]
|
114
|
+
tableUtils = TableUtils.new(@snmp, pdufactory)
|
115
|
+
|
116
|
+
colOID = Array.new
|
117
|
+
Array(table["columns"]).each { |oid| colOID << OID.new(oid) }
|
118
|
+
|
119
|
+
events = tableUtils.getTable(@target, colOID.to_java(org.snmp4j.smi.OID), nil, nil)
|
120
|
+
|
121
|
+
return nil if events.nil? || events.size == 0
|
122
|
+
events.each do |event|
|
123
|
+
next if event.nil?
|
124
|
+
|
125
|
+
if event.isError
|
126
|
+
# TODO: see if we can salvage non errored event here
|
127
|
+
raise(SnmpClientError, "error sending snmp table request to target #{@target.address}: #{event.getErrorMessage}")
|
128
|
+
end
|
129
|
+
|
130
|
+
row = {}
|
131
|
+
idx_val = event.getIndex.toString
|
132
|
+
row["index"] = idx_val
|
133
|
+
|
134
|
+
var_bindings = event.getColumns
|
135
|
+
next if var_bindings.nil? || var_bindings.size == 0
|
136
|
+
|
137
|
+
var_bindings.each do |var_binding|
|
138
|
+
next if var_binding.nil?
|
139
|
+
|
140
|
+
oid = var_binding.getOid.toString
|
141
|
+
variable = var_binding.getVariable
|
142
|
+
value = coerce(variable)
|
143
|
+
mapped_oid = @mib.map_oid(oid, strip_root).sub('.'+idx_val, '')
|
144
|
+
row[mapped_oid] = value
|
145
|
+
end
|
146
|
+
rows << row
|
147
|
+
end
|
148
|
+
result[table_name] = rows
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
108
152
|
protected
|
109
153
|
|
110
154
|
NULL_STRING = "null".freeze
|
data/logstash-input-snmp.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-input-snmp'
|
3
|
-
s.version = '1.0
|
3
|
+
s.version = '1.1.0'
|
4
4
|
s.licenses = ['Apache-2.0']
|
5
5
|
s.summary = "SNMP input plugin"
|
6
6
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
data/spec/inputs/snmp_spec.rb
CHANGED
@@ -24,6 +24,8 @@ describe LogStash::Inputs::Snmp do
|
|
24
24
|
{"get" => [".1.3.6.1.2.1.1.1.0"], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
25
25
|
{"get" => ["1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1"], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
26
26
|
{"get" => ["1.3.6.1.2.1.1.1.0", ".1.3.6.1.2.1.1"], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
27
|
+
{"walk" => ["1.3.6.1.2.1.1.1"], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
28
|
+
{"tables" => [{"name" => "ltmPoolStatTable", "columns" => ["1.3.6.1.4.1.3375.2.2.5.2.3.1.1", "1.3.6.1.4.1.3375.2.2.5.2.3.1.6"]}], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
27
29
|
]
|
28
30
|
}
|
29
31
|
|
@@ -33,6 +35,8 @@ describe LogStash::Inputs::Snmp do
|
|
33
35
|
{"get" => ["test"], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
34
36
|
{"get" => [], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
35
37
|
{"get" => "foo", "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
38
|
+
{"walk" => "foo", "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
39
|
+
{"tables" => [{"columns" => ["1.2.3.4", "4.3.2.1"]}], "hosts" => [{"host" => "udp:127.0.0.1/161"}]},
|
36
40
|
]
|
37
41
|
}
|
38
42
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-snmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elasticsearch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|