logstash-filter-phpipam 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2d2e780de960d171b81b544234dc8f752577cf5f28636da7b26d19c9db98d8c
4
- data.tar.gz: a9ed65dd68109a2df0f8225e7dfda292ddae1ca32945fa85a115b720e9f6b34e
3
+ metadata.gz: 4874331ae90441dff667b067ac4609b7811a40a2bf65cb7e0ac19ba8950ae306
4
+ data.tar.gz: 88be65d72fb3a240f7e8a82ae72be5b9977f106b7a39451ca320bbce0900d48b
5
5
  SHA512:
6
- metadata.gz: f69665cbe6a42af223f0c692bf32174e68ca057ec27ce3d3faaa10eaee61d6d71dea92c5ff695de47f0903829bd7326418c877f5369ab1ab17610938fed4cc75
7
- data.tar.gz: f82c9a5559499778bc6ce3f523ce9decd90fa46ed65dce2c2188392c29b05e094bd23a4e983d6c39aab3c35f9889c640f32836702cd0e70476851b0fde9204fb
6
+ metadata.gz: fa801fdd8549deb74f13b360ba66b38667f20bed34faab5b936a330f097b4fdc2d5e4ca634104cee7df9735eae7c6cbfcb27a0610cc5a7ef26869e247974aa1d
7
+ data.tar.gz: e41ca0a859cf078749e204a9227f0aef0c77d55ceff9242be42a9ae7a6e3ae9119bb9f33248a26869a5c36260c183b46d209244854ce11ccec6d0bb098fd4181
data/README.md CHANGED
@@ -2,23 +2,40 @@
2
2
  A Logstash filter that looks up an IP-address, and returns results from phpIPAM
3
3
 
4
4
  ## Installation
5
+ ### Prerequisites
6
+ [Redis](https://redis.io/) is required for this plugin to work.
7
+
8
+ You can install it using most your distributions package manager.
9
+
10
+ #### Ubuntu example
11
+ You can install it with apt:
12
+ ```bash
13
+ sudo apt install redis
14
+ ```
15
+
16
+
17
+ ### Plugin
5
18
  This plugin can be installed using the `logstash-plugin` command in $LOGSTASH_HOME:
6
19
  ```bash
7
20
  ${LOGSTASH_HOME:-/usr/share/logstash}/bin/logstash-plugin install logstash-filter-phpipam
8
21
  ```
9
22
 
10
23
  ## Configuration options
11
- | Option | Type | Default | Comment |
12
- | ---------- | ------- | --------------------------------- | ------------------------------------------------------------------------------- |
13
- | host | string | | What host to connect to with protocol and optional port(e.g. https://fqdn:3000) |
14
- | app_id | string | | See below |
15
- | username | string | | Username to use for the connection |
16
- | password | string | | Password to use for the connection |
17
- | auth | boolean | true | Whether to use authentication or not |
18
- | cache | boolean | true | Whether to use a cache file or not |
19
- | cache_path | string | /tmp/logstash-filter-phpipam.json | Where to place the cache file. tmpfs is recommended |
20
- | source | string | | Which field the IP-address is in |
21
- | target | string | phpipam | Where to place the phpIPAM data in |
24
+ | Option | Type | Default | Comment |
25
+ | --------------- | ------- | ------------- | -------------------------------------------------------------------------------- |
26
+ | host | string | | What host to connect to with protocol and optional port (e.g. https://fqdn:3000) |
27
+ | app_id | string | | See below |
28
+ | username | string | | Username to use for the connection |
29
+ | password | string | | Password to use for the connection |
30
+ | auth | boolean | true | Whether to use authentication or not |
31
+ | cache_ip | integer | 0 | ID of the redis database for IP-addresses |
32
+ | cache_subnet | integer | 1 | ID of the redis database for subnets |
33
+ | cache_vlan | integer | 2 | ID of the redis database for vlans |
34
+ | cache_device | integer | 3 | ID of the redis database for devices |
35
+ | cache_location | integer | 4 | ID of the redis database for locations |
36
+ | cache_freshness | integer | 86400 (1 day) | How long, in seconds, a value should be cached before it's expired |
37
+ | source | string | | Which field the IP-address is in |
38
+ | target | string | phpipam | Where to place the phpIPAM data in |
22
39
 
23
40
  `app_id` can be found in phpIPAM: Administration -> API \
24
41
  It's recommended to use SSL when accessing the app_id in phpIPAM.
@@ -33,7 +50,7 @@ To use the latitude and longtitude in Kibana Maps, you either need to:
33
50
  For option 2, if you use the default target of `phpipam`, you can do something like this, after the phpipam filter:
34
51
  ```
35
52
  mutate {
36
- copy => {
53
+ rename => {
37
54
  "[phpipam][location][location]" => "[geo][location]"
38
55
  }
39
56
  }
@@ -7,6 +7,7 @@ require 'json'
7
7
  require 'net/http'
8
8
  require 'openssl'
9
9
  require 'uri'
10
+ require 'redis'
10
11
 
11
12
  # A Logstash filter that looks up an IP-address, and returns results from phpIPAM
12
13
  class LogStash::Filters::Phpipam < LogStash::Filters::Base
@@ -25,11 +26,15 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
25
26
  # Whether to use authentication or not
26
27
  config :auth, validate: :boolean, default: true
27
28
 
28
- # Whether to use caching or not
29
- config :cache, validate: :boolean, default: true
29
+ # Cache fressness
30
+ config :cache_freshness, validate: :number, default: 86_400
30
31
 
31
- # Which file to use as cache storage. Should be placed on a tmpfs volume for maximum performance
32
- config :cache_path, validate: :string, default: '/tmp/logstash-filter-phpipam.json'
32
+ # All the caching stores
33
+ config :cache_ip, validate: :number, default: 0
34
+ config :cache_subnet, validate: :number, default: 1
35
+ config :cache_vlan, validate: :number, default: 2
36
+ config :cache_device, validate: :number, default: 3
37
+ config :cache_location, validate: :number, default: 4
33
38
 
34
39
  # IP-address field to look up
35
40
  config :source, validate: :string, required: true
@@ -44,7 +49,25 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
44
49
  # Get a session token
45
50
  @token = send_rest_request('POST', "api/#{@app_id}/user/")['token'] if @auth
46
51
 
52
+ # Normalize target
47
53
  @target = normalize_target(@target)
54
+
55
+ @cache_freshness = @cache_freshness.to_i
56
+
57
+ @cs_ip = Redis.new(db: @cache_ip, id: 'logstash-filter-phpipam')
58
+ @cs_subnet = Redis.new(db: @cache_subnet, id: 'logstash-filter-phpipam')
59
+ @cs_vlan = Redis.new(db: @cache_vlan, id: 'logstash-filter-phpipam')
60
+ @cs_device = Redis.new(db: @cache_device, id: 'logstash-filter-phpipam')
61
+ @cs_location = Redis.new(db: @cache_location, id: 'logstash-filter-phpipam')
62
+ end
63
+
64
+ def close
65
+ # Persist the database to disk, when the pipeline ends
66
+ @cs_ip.bgsave
67
+ @cs_subnet.bgsave
68
+ @cs_vlan.bgsave
69
+ @cs_device.bgsave
70
+ @cs_location.bgsave
48
71
  end
49
72
 
50
73
  def filter(event)
@@ -54,11 +77,14 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
54
77
 
55
78
  return unless valid_ip?(ip, event)
56
79
 
57
- # Get data from cache or phpIPAM if not in cache
58
- event_data = search_cache(ip) if @cache
59
- event_data = phpipam_data(ip, event) unless event_data.is_a?(Hash)
80
+ # Get the data
81
+ event_data = phpipam_data(ip)
60
82
 
61
- return if !event_data['error'].nil? && event_data['error']
83
+ # Tag and return if no IP was found
84
+ if event_data.nil?
85
+ event.tag('_phpipam_ip_not_found')
86
+ return
87
+ end
62
88
 
63
89
  # Set the data to the target path
64
90
  event.set(@target, event_data)
@@ -93,10 +119,10 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
93
119
  false
94
120
  end
95
121
 
96
- # Sends a GET method REST request.
122
+ # Sends a GET method REST request. Returns nil if no data/an error was found
97
123
  # @param method: which HTTP method to use (POST, GET)
98
124
  # @param url_path: path to connect to
99
- # @return [hash]
125
+ # @return [hash/nil]
100
126
  def send_rest_request(method, url_path)
101
127
  @logger.debug? && @logger.debug('Sending request', host: @host, path: url_path)
102
128
 
@@ -133,9 +159,9 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
133
159
  # Raise an error if not a code 200 is returned
134
160
  raise LogStash::ConfigurationError, "#{rsp['code']}:#{rsp['message']}" if rsp['code'] != 200
135
161
 
136
- # Return error if no data field is present, else return the data
162
+ # Return nil if no data field is present, else return the data
137
163
  rsp = if rsp['data'].nil?
138
- { 'error' => true }
164
+ nil
139
165
  else
140
166
  rsp['data'].is_a?(Array) ? rsp['data'][0] : rsp['data']
141
167
  end
@@ -151,133 +177,159 @@ class LogStash::Filters::Phpipam < LogStash::Filters::Base
151
177
  value.nil? || value.empty?
152
178
  end
153
179
 
154
- # Checks if the value is defined and not nil or error
155
- # @param value: a value to check
156
- # @return [bool]
157
- def okay?(value)
158
- !defined?(value).nil? && !value.nil? && value['error'].nil?
159
- end
160
-
161
- # Queries phpIPAM and formats the data
162
- # @param ip: an IP-address to query
163
- # @return [hash]
164
- def phpipam_data(ip, event)
165
- # Fetch base data needed from phpIPAM
166
- ip_data = send_rest_request('GET', "api/#{@app_id}/addresses/search/#{ip}/")
167
-
168
- # If the IP wasn't found, return and do nuthin'
169
- if !ip_data['error'].nil? && ip_data['error']
170
- event.tag('_phpipam_ip_not_found')
171
- return { 'error' => true }
172
- end
173
-
174
- subnet_data = send_rest_request('GET', "api/#{@app_id}/subnets/#{ip_data['subnetId']}/") unless nil_or_empty?(ip_data['subnetId'])
175
- vlan_data = send_rest_request('GET', "api/#{@app_id}/vlans/#{subnet_data['vlanId']}/") unless nil_or_empty?(subnet_data['vlanId'])
176
-
177
- device_data = send_rest_request('GET', "api/#{@app_id}/tools/devices/#{ip_data['deviceId']}/") unless ip_data['deviceId'] == '0' || nil_or_empty?(ip_data['deviceId'])
178
- location_data = send_rest_request('GET', "api/#{@app_id}/tools/locations/#{ip_data['location']}/") unless ip_data['location'] == '0' || nil_or_empty?(ip_data['location'])
179
-
180
+ # Get phpIPAM data either from cache or phpIPAM.
181
+ # If data was found from phpIPAM, it will cache it for future needs.
182
+ # If the data wasn't found in either cache or phpIPAM, nil is returned.
183
+ # @param ip - IP-address to lookup
184
+ # @return [hash/nil]
185
+ def phpipam_data(ip)
180
186
  # Base hash to format data in
181
187
  base = {
182
- 'ip' => {},
188
+ 'ip' => {},
189
+ 'subnet' => {},
190
+ 'vlan' => {},
191
+ 'device' => {},
192
+ 'location' => {},
183
193
  }
184
194
 
185
- # IP information
186
- base['ip']['id'] = ip_data['id'].to_i
187
- base['ip']['address'] = ip_data['ip']
188
- base['ip']['description'] = ip_data['description'] unless nil_or_empty?(ip_data['description'])
189
- base['ip']['hostname'] = ip_data['hostname'] unless nil_or_empty?(ip_data['hostname'])
190
- base['ip']['mac'] = ip_data['mac'] unless nil_or_empty?(ip_data['mac'])
191
- base['ip']['note'] = ip_data['note'] unless nil_or_empty?(ip_data['note'])
192
- base['ip']['owner'] = ip_data['owner'] unless nil_or_empty?(ip_data['owner'])
193
-
194
- # Subnet information
195
- if okay?(subnet_data)
196
- base['subnet'] = {}
197
- base['subnet']['id'] = ip_data['subnetId'].to_i
198
- base['subnet']['section_id'] = subnet_data['sectionId'].to_i
199
- base['subnet']['bitmask'] = subnet_data['calculation']['Subnet bitmask'].to_i
200
- base['subnet']['wildcard'] = subnet_data['calculation']['Subnet wildcard']
201
- base['subnet']['netmask'] = subnet_data['calculation']['Subnet netmask']
202
- base['subnet']['network'] = subnet_data['calculation']['Network']
195
+ # If 0 is returned, it has been cached as non-existent
196
+ return nil if @cs_ip.get(ip) == '0'
197
+
198
+ ## IP LOOKUP ##
199
+ if @cs_ip.get(ip).nil?
200
+ ip_data = send_rest_request('GET', "api/#{@app_id}/addresses/search/#{ip}/")
201
+
202
+ # Return and cache 0 for this IP, if it wasn't found in phpIPAM
203
+ if ip_data.nil?
204
+ @cs_ip.set(ip, '0', ex: @cache_freshness)
205
+ return nil
206
+ end
207
+
208
+ # IP information
209
+ base['ip']['id'] = ip_data['id'].to_i
210
+ base['ip']['address'] = ip_data['ip']
211
+ base['ip']['description'] = ip_data['description'] unless nil_or_empty?(ip_data['description'])
212
+ base['ip']['hostname'] = ip_data['hostname'] unless nil_or_empty?(ip_data['hostname'])
213
+ base['ip']['mac'] = ip_data['mac'] unless nil_or_empty?(ip_data['mac'])
214
+ base['ip']['note'] = ip_data['note'] unless nil_or_empty?(ip_data['note'])
215
+ base['ip']['owner'] = ip_data['owner'] unless nil_or_empty?(ip_data['owner'])
216
+
217
+ # Get all the ID's
218
+ base['ip']['subnet_id'] = ip_data['subnetId'].to_i
219
+ base['ip']['device_id'] = ip_data['deviceId'].to_i
220
+ base['ip']['location_id'] = ip_data['location'].to_i
221
+
222
+ @cs_ip.set(ip, base['ip'].to_json, ex: @cache_freshness)
223
+ else
224
+ base['ip'] = JSON.parse(@cs_ip.get(ip))
203
225
  end
204
226
 
205
- # VLAN information
206
- if okay?(vlan_data)
207
- base['vlan'] = {}
208
- base['vlan']['id'] = subnet_data['vlanId'].to_i
209
- base['vlan']['domain_id'] = vlan_data['domainId'].to_i
210
- base['vlan']['number'] = vlan_data['number'].to_i unless nil_or_empty?(vlan_data['number'])
211
- base['vlan']['name'] = vlan_data['name'] unless nil_or_empty?(vlan_data['name'])
212
- base['vlan']['description'] = vlan_data['description'] unless nil_or_empty?(vlan_data['description'])
227
+ ## SUBNET LOOKUP ##
228
+ subnet_id = base['ip']['subnet_id']
229
+
230
+ # If 0 is returned, it doesn't exist. Only lookup if a nonzero value is returned
231
+ if subnet_id.positive?
232
+ if @cs_subnet.get(subnet_id).nil?
233
+ subnet_data = send_rest_request('GET', "api/#{@app_id}/subnets/#{subnet_id}/")
234
+
235
+ # Subnet data
236
+ base['subnet']['id'] = subnet_id
237
+ base['subnet']['section_id'] = subnet_data['sectionId'].to_i
238
+ base['subnet']['bitmask'] = subnet_data['calculation']['Subnet bitmask'].to_i
239
+ base['subnet']['wildcard'] = subnet_data['calculation']['Subnet wildcard']
240
+ base['subnet']['netmask'] = subnet_data['calculation']['Subnet netmask']
241
+ base['subnet']['network'] = subnet_data['calculation']['Network']
242
+
243
+ # Get VLAN id and location _id
244
+ base['subnet']['vlan_id'] = subnet_data['vlanId'].to_i
245
+ base['subnet']['location_id'] = subnet_data['location'].to_i
246
+
247
+ @cs_subnet.set(subnet_id, base['subnet'].to_json, ex: @cache_freshness)
248
+ else
249
+ base['subnet'] = JSON.parse(@cs_subnet.get(subnet_id))
250
+ end
213
251
  end
214
252
 
215
- # Device information
216
- if okay?(device_data)
217
- type = send_rest_request('GET', "api/#{@app_id}/tools/device_types/#{device_data['type']}/")
218
-
219
- base['device'] = {}
220
- base['device']['id'] = ip_data['deviceId'].to_i
221
- base['device']['name'] = device_data['hostname'] unless nil_or_empty?(device_data['hostname'])
222
- base['device']['description'] = device_data['description'] unless nil_or_empty?(device_data['description'])
223
- base['device']['type'] = type['tname'] unless nil_or_empty?(type['tname'])
253
+ ## VLAN LOOKUP ##
254
+ vlan_id = base['subnet']['vlan_id']
255
+
256
+ # If 0 is returned, it doesn't exist. Only lookup if a nonzero value is returned
257
+ if vlan_id.positive?
258
+ if @cs_vlan.get(vlan_id).nil?
259
+ vlan_data = send_rest_request('GET', "api/#{@app_id}/vlans/#{vlan_id}/")
260
+
261
+ # VLAN data
262
+ base['vlan']['id'] = vlan_id
263
+ base['vlan']['domain_id'] = vlan_data['domainId'].to_i
264
+ base['vlan']['number'] = vlan_data['number'].to_i unless nil_or_empty?(vlan_data['number'])
265
+ base['vlan']['name'] = vlan_data['name'] unless nil_or_empty?(vlan_data['name'])
266
+ base['vlan']['description'] = vlan_data['description'] unless nil_or_empty?(vlan_data['description'])
267
+
268
+ @cs_vlan.set(vlan_id, base['vlan'].to_json, ex: @cache_freshness)
269
+ else
270
+ base['vlan'] = JSON.parse(@cs_vlan.get(vlan_id))
271
+ end
224
272
  end
225
273
 
226
- # If the IP doesn't have the location directly, try to get it from the device or subnet
227
- unless okay?(location_data)
228
- location_data = if okay?(device_data) && device_data['location'] != '0' && !nil_or_empty?(device_data['location'])
229
- send_rest_request('GET', "api/#{@app_id}/tools/locations/#{device_data['location']}/")
230
- elsif okay?(subnet_data) && subnet_data['location'] != '0' && !nil_or_empty?(subnet_data['location'])
231
- send_rest_request('GET', "api/#{@app_id}/tools/locations/#{subnet_data['location']}/")
232
- end
233
- end
274
+ ## DEVICE LOOKUP ##
275
+ device_id = base['ip']['device_id']
234
276
 
235
- # Location information
236
- if okay?(location_data)
237
- base['location'] = {}
238
- base['location']['id'] = location_data['id'].to_i
239
- base['location']['address'] = location_data['address'] unless nil_or_empty?(location_data['address'])
240
- base['location']['name'] = location_data['name'] unless nil_or_empty?(location_data['name'])
241
- base['location']['description'] = location_data['description'] unless nil_or_empty?(location_data['description'])
242
- base['location']['location'] = { 'lat' => location_data['lat'].to_f, 'lon' => location_data['long'].to_f } unless nil_or_empty?(location_data['lat'])
243
- end
277
+ # If 0 is returned, it doesn't exist. Only lookup if a nonzero value is returned
278
+ if device_id.positive?
279
+ if @cs_device.get(device_id).nil?
280
+ device_data = send_rest_request('GET', "api/#{@app_id}/tools/devices/#{device_id}/")
244
281
 
245
- # Cache it for future needs
246
- cache_data(base) if @cache
282
+ # Device data
283
+ type = send_rest_request('GET', "api/#{@app_id}/tools/device_types/#{device_data['type']}/")
247
284
 
248
- # all your base are belong to us
249
- base
250
- end
285
+ base['device']['id'] = device_id
286
+ base['device']['name'] = device_data['hostname'] unless nil_or_empty?(device_data['hostname'])
287
+ base['device']['description'] = device_data['description'] unless nil_or_empty?(device_data['description'])
288
+ base['device']['type'] = type['tname'] unless nil_or_empty?(type['tname'])
251
289
 
252
- # Caches data (if possible)
253
- # @param data: the data to cache
254
- # @return [void]
255
- def cache_data(data)
256
- data = data.to_json
290
+ # Get device location
291
+ base['device']['location_id'] = device_data['location'].to_i
257
292
 
258
- File.open(@cache_path, 'a') do |file|
259
- file.write(data + "\n")
260
- @logger.debug? && @logger.debug('Cached data', data: data)
261
- rescue StandardError
262
- @logger.debug? && @logger.debug('Cache file is not writable, skipping caching of data', data: data, cache_file: @cache_path)
263
- break
293
+ @cs_device.set(device_id, base['device'].to_json, ex: @cache_freshness)
294
+ else
295
+ base['device'] = JSON.parse(@cs_device.get(device_id))
296
+ end
264
297
  end
265
- end
266
-
267
- # Seaches the cache file for the IP.
268
- # Returns a hash if the IP was found, else false
269
- # @param ip: The IP-address to search for
270
- # @return [hash/bool]
271
- def search_cache(ip)
272
- @logger.debug? && @logger.debug('Searching cache...', ip: ip)
273
298
 
274
- return false unless File.exist?(@cache_path)
275
-
276
- File.foreach(@cache_path) do |line|
277
- line = JSON.parse(line)
278
- return line if line['ip']['address'] == ip
299
+ ## LOCATION LOOKUP ##
300
+ # Get the first positive location_id from the list
301
+ location_id = [base['ip']['location_id'], base['device']['location_id'], base['subnet']['location_id']].select { |num|
302
+ !num.nil? && num.positive?
303
+ }[0] || 0
304
+
305
+ # If 0 is returned, it doesn't exist. Only lookup if a nonzero value is returned
306
+ if location_id.positive?
307
+ if @cs_location.get(location_id).nil?
308
+ location_data = send_rest_request('GET', "api/#{@app_id}/tools/locations/#{location_id}/")
309
+
310
+ # Location data
311
+ base['location']['id'] = location_id
312
+ base['location']['address'] = location_data['address'] unless nil_or_empty?(location_data['address'])
313
+ base['location']['name'] = location_data['name'] unless nil_or_empty?(location_data['name'])
314
+ base['location']['description'] = location_data['description'] unless nil_or_empty?(location_data['description'])
315
+ base['location']['location'] = { 'lat' => location_data['lat'].to_f, 'lon' => location_data['long'].to_f } unless nil_or_empty?(location_data['lat'])
316
+
317
+ @cs_location.set(location_id, base['location'].to_json, ex: @cache_freshness)
318
+ else
319
+ base['location'] = JSON.parse(@cs_location.get(location_id))
320
+ end
279
321
  end
280
322
 
281
- false
323
+ # Clean-up keys that aren't needed in the final Logstash output
324
+ base['ip'].delete('subnet_id')
325
+ base['ip'].delete('device_id')
326
+ base['ip'].delete('location_id')
327
+ base['subnet'].delete('vlan_id')
328
+ base['subnet'].delete('location_id')
329
+ base['device'].delete('location_id')
330
+ base.delete_if { |_, val| val.empty? }
331
+
332
+ # all your base are belong to us
333
+ base
282
334
  end
283
335
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'logstash-filter-phpipam'
5
- s.version = '0.7.5'
5
+ s.version = '0.8.0'
6
6
  s.licenses = ['Apache-2.0']
7
7
  s.summary = 'A Logstash filter that returns results from phpIPAM'
8
8
  s.description = 'A Logstash filter that looks up an IP-address, and returns results from phpIPAM'
@@ -21,5 +21,6 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency 'logstash-core-plugin-api', '~> 2.0'
24
- s.add_development_dependency 'logstash-devutils'
24
+ s.add_runtime_dependency 'redis', '~> 4.1', '>= 4.1.2'
25
+ s.add_development_dependency 'logstash-devutils', '~> 1.3', '>= 1.3.6'
25
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-phpipam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - magnuslarsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-16 00:00:00.000000000 Z
11
+ date: 2019-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-core-plugin-api
@@ -24,20 +24,46 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.1'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 4.1.2
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '4.1'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 4.1.2
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: logstash-devutils
29
49
  requirement: !ruby/object:Gem::Requirement
30
50
  requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
31
54
  - - ">="
32
55
  - !ruby/object:Gem::Version
33
- version: '0'
56
+ version: 1.3.6
34
57
  type: :development
35
58
  prerelease: false
36
59
  version_requirements: !ruby/object:Gem::Requirement
37
60
  requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '1.3'
38
64
  - - ">="
39
65
  - !ruby/object:Gem::Version
40
- version: '0'
66
+ version: 1.3.6
41
67
  description: A Logstash filter that looks up an IP-address, and returns results from
42
68
  phpIPAM
43
69
  email: ''
@@ -76,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
102
  - !ruby/object:Gem::Version
77
103
  version: '0'
78
104
  requirements: []
79
- rubygems_version: 3.0.4
105
+ rubygems_version: 3.0.6
80
106
  signing_key:
81
107
  specification_version: 4
82
108
  summary: A Logstash filter that returns results from phpIPAM