logstash-input-snmp 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 747dbf68d6a90a7ab937bf8c64edef786b7d0c4c0ac2f97088401d1e842c2616
4
- data.tar.gz: e53514a31810159796b3e80ee56f7aa6d66eba23ac781744fd9fbf0be83d4d9a
3
+ metadata.gz: 13fdcfbd3e486a466a7fa32e1de3e6bbdccd30779f5eb4fce9ef8645355c8322
4
+ data.tar.gz: b8e80f54fbe399f262e48aff1fd614d578b16d493cded3e15446593ebffd1f93
5
5
  SHA512:
6
- metadata.gz: fa84badc45e056d01ca6a8668e3b5a2ddf89348339f49524b60b77843753cb7eb51fe2fcfe40d2d61dfc95523988f1fa6e11cc430692bbbe38d0014371c62278
7
- data.tar.gz: 9e8e9895750a23892e99b2c198eef3e66f75de885e700dcea020d00356e843a022bd5dae6894a390f9f64faea40ea0f15310dbc7b34ef1fa96947b15d9d1a45b
6
+ metadata.gz: fc44139cfc59066ffa89fc916903e4507972b9650cc056ee0bb897a8028dcf93abf30c07627926ce717a0da275d084ebf45b7e631355d04752ef55e868eef3f7
7
+ data.tar.gz: 1ca064497bd573c6d3de4c00bf0d744fb14339926d61203d6a7e74fcbb6887c64f784e32ecb579db11fc2ff849c329b7479df92a44b24803d653b316ab41cbd6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 1.3.1
2
+ - Refactor: handle no response(s) wout error logging [#105](https://github.com/logstash-plugins/logstash-input-snmp/pull/105)
3
+
1
4
  ## 1.3.0
2
5
  - Feat: ECS compliance + optional target [#99](https://github.com/logstash-plugins/logstash-input-snmp/pull/99)
3
6
  - Internal: update to Gradle 7 [#102](https://github.com/logstash-plugins/logstash-input-snmp/pull/102)
@@ -52,13 +52,13 @@ module LogStash
52
52
  end
53
53
 
54
54
  def walk(oid, strip_root = 0, path_length = 0)
55
- result = {}
56
-
57
55
  pdufactory = get_pdu_factory
58
56
  treeUtils = TreeUtils.new(@snmp, pdufactory)
59
57
  events = treeUtils.getSubtree(@target, OID.new(oid))
60
58
  return nil if events.nil? || events.size == 0
61
59
 
60
+ result = {}
61
+
62
62
  events.each do |event|
63
63
  next if event.nil?
64
64
 
@@ -192,53 +192,73 @@ class LogStash::Inputs::Snmp < LogStash::Inputs::Base
192
192
 
193
193
  def run(queue)
194
194
  # for now a naive single threaded poller which sleeps off the remaining interval between
195
- # each run. each run polls all the defined hosts for the get and walk options.
195
+ # each run. each run polls all the defined hosts for the get, table and walk options.
196
196
  stoppable_interval_runner.every(@interval, "polling hosts") do
197
- @client_definitions.each do |definition|
198
- client = definition[:client]
199
- result = {}
200
- if !definition[:get].empty?
201
- oids = definition[:get]
202
- begin
203
- result = result.merge(client.get(oids, @oid_root_skip, @oid_path_length))
204
- rescue => e
205
- logger.error("error invoking get operation for OIDs: #{oids}, ignoring",
206
- host: definition[:host_address], exception: e, backtrace: e.backtrace)
197
+ poll_clients(queue)
198
+ end
199
+ end
200
+
201
+ def poll_clients(queue)
202
+ @client_definitions.each do |definition|
203
+ client = definition[:client]
204
+ host = definition[:host_address]
205
+ result = {}
206
+
207
+ if !definition[:get].empty?
208
+ oids = definition[:get]
209
+ begin
210
+ data = client.get(oids, @oid_root_skip, @oid_path_length)
211
+ if data
212
+ result.update(data)
213
+ else
214
+ logger.debug? && logger.debug("get operation returned no response", host: host, oids: oids)
207
215
  end
216
+ rescue => e
217
+ logger.error("error invoking get operation, ignoring", host: host, oids: oids, exception: e, backtrace: e.backtrace)
208
218
  end
209
- if !definition[:walk].empty?
210
- definition[:walk].each do |oid|
211
- begin
212
- result = result.merge(client.walk(oid, @oid_root_skip, @oid_path_length))
213
- rescue => e
214
- logger.error("error invoking walk operation on OID: #{oid}, ignoring",
215
- host: definition[:host_address], exception: e, backtrace: e.backtrace)
219
+ end
220
+
221
+ if !definition[:walk].empty?
222
+ definition[:walk].each do |oid|
223
+ begin
224
+ data = client.walk(oid, @oid_root_skip, @oid_path_length)
225
+ if data
226
+ result.update(data)
227
+ else
228
+ logger.debug? && logger.debug("walk operation returned no response", host: host, oid: oid)
216
229
  end
230
+ rescue => e
231
+ logger.error("error invoking walk operation, ignoring", host: host, oid: oid, exception: e, backtrace: e.backtrace)
217
232
  end
218
233
  end
234
+ end
219
235
 
220
- if !Array(@tables).empty?
221
- @tables.each do |table_entry|
222
- begin
223
- result = result.merge(client.table(table_entry, @oid_root_skip, @oid_path_length))
224
- rescue => e
225
- logger.error("error invoking table operation on OID: #{table_entry['name']}, ignoring",
226
- host: definition[:host_address], exception: e, backtrace: e.backtrace)
236
+ if !Array(@tables).empty?
237
+ @tables.each do |table_entry|
238
+ begin
239
+ data = client.table(table_entry, @oid_root_skip, @oid_path_length)
240
+ if data
241
+ result.update(data)
242
+ else
243
+ logger.debug? && logger.debug("table operation returned no response", host: host, table: table_entry)
227
244
  end
245
+ rescue => e
246
+ logger.error("error invoking table operation, ignoring",
247
+ host: host, table_name: table_entry['name'], exception: e, backtrace: e.backtrace)
228
248
  end
229
249
  end
250
+ end
230
251
 
231
- unless result.empty?
232
- event = targeted_event_factory.new_event(result)
233
- event.set(@host_protocol_field, definition[:host_protocol])
234
- event.set(@host_address_field, definition[:host_address])
235
- event.set(@host_port_field, definition[:host_port])
236
- event.set(@host_community_field, definition[:host_community])
237
- decorate(event)
238
- queue << event
239
- else
240
- logger.debug? && logger.debug("no snmp data retrieved", host: definition[:host_address])
241
- end
252
+ unless result.empty?
253
+ event = targeted_event_factory.new_event(result)
254
+ event.set(@host_protocol_field, definition[:host_protocol])
255
+ event.set(@host_address_field, definition[:host_address])
256
+ event.set(@host_port_field, definition[:host_port])
257
+ event.set(@host_community_field, definition[:host_community])
258
+ decorate(event)
259
+ queue << event
260
+ else
261
+ logger.debug? && logger.debug("no snmp data retrieved", host: definition[:host_address])
242
262
  end
243
263
  end
244
264
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-snmp'
3
- s.version = '1.3.0'
3
+ s.version = '1.3.1'
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"
@@ -136,43 +136,46 @@ describe LogStash::Inputs::Snmp, :ecs_compatibility_support do
136
136
 
137
137
  before(:each) do
138
138
  allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
139
- end
140
139
 
141
- before do
142
140
  expect(LogStash::SnmpClient).to receive(:new).and_return(mock_client)
143
- expect(mock_client).to receive(:get).and_return({"foo" => "bar"})
144
141
  # devutils in v6 calls close on the test pipelines while it does not in v7+
145
- expect(mock_client).to receive(:close).at_most(:once)
142
+ allow(mock_client).to receive(:close).at_most(:once)
146
143
  end
147
144
 
148
- it "shoud add @metadata fields and add default host field" do
149
- config = <<-CONFIG
145
+ context 'mocked get' do
146
+
147
+ before do
148
+ expect(mock_client).to receive(:get).and_return({"foo" => "bar"})
149
+ end
150
+
151
+ it "shoud add @metadata fields and add default host field" do
152
+ config = <<-CONFIG
150
153
  input {
151
154
  snmp {
152
155
  get => ["1.3.6.1.2.1.1.1.0"]
153
156
  hosts => [{ host => "udp:127.0.0.1/161" community => "public" }]
154
157
  }
155
158
  }
156
- CONFIG
157
- event = input(config) { |_, queue| queue.pop }
158
-
159
- if ecs_select.active_mode == :disabled
160
- expect(event.get("[@metadata][host_protocol]")).to eq("udp")
161
- expect(event.get("[@metadata][host_address]")).to eq("127.0.0.1")
162
- expect(event.get("[@metadata][host_port]")).to eq("161")
163
- expect(event.get("[@metadata][host_community]")).to eq("public")
164
- expect(event.get("host")).to eql("127.0.0.1")
165
- else
166
- expect(event.get("[@metadata][input][snmp][host][protocol]")).to eq("udp")
167
- expect(event.get("[@metadata][input][snmp][host][address]")).to eq("127.0.0.1")
168
- expect(event.get("[@metadata][input][snmp][host][port]")).to eq('161')
169
- expect(event.get("[@metadata][input][snmp][host][community]")).to eq("public")
170
- expect(event.get("host")).to eql('ip' => "127.0.0.1")
159
+ CONFIG
160
+ event = input(config) { |_, queue| queue.pop }
161
+
162
+ if ecs_select.active_mode == :disabled
163
+ expect(event.get("[@metadata][host_protocol]")).to eq("udp")
164
+ expect(event.get("[@metadata][host_address]")).to eq("127.0.0.1")
165
+ expect(event.get("[@metadata][host_port]")).to eq("161")
166
+ expect(event.get("[@metadata][host_community]")).to eq("public")
167
+ expect(event.get("host")).to eql("127.0.0.1")
168
+ else
169
+ expect(event.get("[@metadata][input][snmp][host][protocol]")).to eq("udp")
170
+ expect(event.get("[@metadata][input][snmp][host][address]")).to eq("127.0.0.1")
171
+ expect(event.get("[@metadata][input][snmp][host][port]")).to eq('161')
172
+ expect(event.get("[@metadata][input][snmp][host][community]")).to eq("public")
173
+ expect(event.get("host")).to eql('ip' => "127.0.0.1")
174
+ end
171
175
  end
172
- end
173
176
 
174
- it "should add custom host field (legacy metadata)" do
175
- config = <<-CONFIG
177
+ it "should add custom host field (legacy metadata)" do
178
+ config = <<-CONFIG
176
179
  input {
177
180
  snmp {
178
181
  get => ["1.3.6.1.2.1.1.1.0"]
@@ -180,14 +183,14 @@ describe LogStash::Inputs::Snmp, :ecs_compatibility_support do
180
183
  add_field => { host => "%{[@metadata][host_protocol]}:%{[@metadata][host_address]}/%{[@metadata][host_port]},%{[@metadata][host_community]}" }
181
184
  }
182
185
  }
183
- CONFIG
184
- event = input(config) { |_, queue| queue.pop }
186
+ CONFIG
187
+ event = input(config) { |_, queue| queue.pop }
185
188
 
186
- expect(event.get("host")).to eq("udp:127.0.0.1/161,public")
187
- end if ecs_select.active_mode == :disabled
189
+ expect(event.get("host")).to eq("udp:127.0.0.1/161,public")
190
+ end if ecs_select.active_mode == :disabled
188
191
 
189
- it "should add custom host field (ECS mode)" do
190
- config = <<-CONFIG
192
+ it "should add custom host field (ECS mode)" do
193
+ config = <<-CONFIG
191
194
  input {
192
195
  snmp {
193
196
  get => ["1.3.6.1.2.1.1.1.0"]
@@ -195,14 +198,14 @@ describe LogStash::Inputs::Snmp, :ecs_compatibility_support do
195
198
  add_field => { "[host][formatted]" => "%{[@metadata][input][snmp][host][protocol]}://%{[@metadata][input][snmp][host][address]}:%{[@metadata][input][snmp][host][port]}" }
196
199
  }
197
200
  }
198
- CONFIG
199
- event = input(config) { |_, queue| queue.pop }
201
+ CONFIG
202
+ event = input(config) { |_, queue| queue.pop }
200
203
 
201
- expect(event.get("host")).to eq('formatted' => "tcp://192.168.1.11:1161")
202
- end if ecs_select.active_mode != :disabled
204
+ expect(event.get("host")).to eq('formatted' => "tcp://192.168.1.11:1161")
205
+ end if ecs_select.active_mode != :disabled
203
206
 
204
- it "should target event data" do
205
- config = <<-CONFIG
207
+ it "should target event data" do
208
+ config = <<-CONFIG
206
209
  input {
207
210
  snmp {
208
211
  get => ["1.3.6.1.2.1.1.1.0"]
@@ -210,12 +213,92 @@ describe LogStash::Inputs::Snmp, :ecs_compatibility_support do
210
213
  target => "snmp_data"
211
214
  }
212
215
  }
213
- CONFIG
214
- event = input(config) { |_, queue| queue.pop }
216
+ CONFIG
217
+ event = input(config) { |_, queue| queue.pop }
218
+
219
+ expect( event.include?('foo') ).to be false
220
+ expect( event.get('[snmp_data]') ).to eql 'foo' => 'bar'
221
+ end
215
222
 
216
- expect( event.include?('foo') ).to be false
217
- expect( event.get('[snmp_data]') ).to eql 'foo' => 'bar'
218
223
  end
224
+
225
+ context 'mocked nil get response' do
226
+
227
+ let(:config) do
228
+ {
229
+ 'get' => ["1.3.6.1.2.1.1.1.0"],
230
+ "hosts" => [{"host" => "udp:127.0.0.1/161", "community" => "public"}]
231
+ }
232
+ end
233
+
234
+ let(:logger) { double("Logger").as_null_object }
235
+
236
+ before do
237
+ expect(mock_client).to receive(:get).once.and_return(nil)
238
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger)
239
+ expect(logger).not_to receive(:error)
240
+ end
241
+
242
+ it 'generates no events when client returns no response' do
243
+ input = described_class.new(config).tap { |input| input.register }
244
+ input.poll_clients queue = Queue.new
245
+
246
+ expect( queue.size ).to eql 0
247
+ end
248
+ end
249
+
250
+ context 'mocked nil table response' do
251
+
252
+ let(:config) do
253
+ {
254
+ 'tables' => [
255
+ { 'name' => "a1Table", 'columns' => ["1.3.6.1.4.1.3375.2.2.5.2.3.1.1"] }
256
+ ],
257
+ "hosts" => [{"host" => "udp:127.0.0.1/161", "community" => "public"}]
258
+ }
259
+ end
260
+
261
+ let(:logger) { double("Logger").as_null_object }
262
+
263
+ before do
264
+ expect(mock_client).to receive(:table).once.and_return(nil)
265
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger)
266
+ expect(logger).not_to receive(:error)
267
+ end
268
+
269
+ it 'generates no events when client returns no response' do
270
+ input = described_class.new(config).tap { |input| input.register }
271
+ input.poll_clients queue = Queue.new
272
+
273
+ expect( queue.size ).to eql 0
274
+ end
275
+ end
276
+
277
+ context 'mocked nil walk response' do
278
+
279
+ let(:config) do
280
+ {
281
+ 'walk' => ["1.3.6.1.2.1.1"],
282
+ "hosts" => [{"host" => "udp:127.0.0.1/161", "community" => "public"}]
283
+ }
284
+ end
285
+
286
+ let(:logger) { double("Logger").as_null_object }
287
+
288
+ before do
289
+ expect(mock_client).to receive(:walk).once.and_return(nil)
290
+ allow_any_instance_of(described_class).to receive(:logger).and_return(logger)
291
+ expect(logger).not_to receive(:error)
292
+ end
293
+
294
+ it 'generates no events when client returns no response' do
295
+ input = described_class.new(config).tap { |input| input.register }
296
+ input.poll_clients queue = Queue.new
297
+
298
+ expect( queue.size ).to eql 0
299
+ end
300
+ end
301
+
219
302
  end
220
303
 
221
304
  context "StoppableIntervalRunner" do
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.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elasticsearch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-19 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement