logstash-filter-dns 3.0.1 → 3.0.3

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
  SHA1:
3
- metadata.gz: a904ba308a43248f28d424a0d82da4fde999894b
4
- data.tar.gz: 5583c65cffcfac528907a2ebfb83e412ae387a84
3
+ metadata.gz: 71ea1ae4db2be0cfc2ef5e4c7e109d8ab52ea66e
4
+ data.tar.gz: 9da02b4bd4f919e0a08ba2df3d85a5baf871023e
5
5
  SHA512:
6
- metadata.gz: 7a9d4691b838e061e30cf8257e620d657b0c48bcbab5f53b2b46c1fba2d19e7b985d58131b5355ff190f2a8a70138773d8f6137ddf871b5551983266ad9bf53d
7
- data.tar.gz: b40d2d271a3999fcd9bb3ee5f4cfcf8362108c84f4fd029e41f11e673638ab7007e80c2061cc98d51c97d58cddbd4ea253d26085dd014a5ae25f85c39de37f7a
6
+ metadata.gz: 3c6d9c9f130680c2c08d5c42f28e313c28fa9da74e4bb7b4e54367a11bf8c25b6c2199d487af71911180e61cb8e627cffd59740e941f4949e2f659c8ea5c9061
7
+ data.tar.gz: e4be62edea5cc7d006a7aae79d7c2ef02fbc974e0522dd4a92974acd47444570ce28da677d760a978000bb45c572c7f4edf5b5e8644e74fb1297281609b4a977
data/CHANGELOG.md CHANGED
@@ -1,7 +1,16 @@
1
+ ## 3.0.3
2
+ - Relax constraint on logstash-core-plugin-api to >= 1.60 <= 2.99
3
+
4
+ ## 3.0.2
5
+ - Add support for International Domain Names e.g. müller.com. Fixes https://github.com/logstash-plugins/logstash-filter-dns/issues/22
6
+ - Add support for custom hosts files (helps with testing but could be useful to some folks).
7
+
1
8
  ## 3.0.1
2
9
  - Republish all the gems under jruby.
10
+
3
11
  ## 3.0.0
4
12
  - Update the plugin to the version 2.0 of the plugin api, this change is required for Logstash 5.0 compatibility. See https://github.com/elastic/logstash/issues/5141
13
+
5
14
  ## 2.1.3
6
15
  - Fix spec early termination by removing an explicit return from a block
7
16
 
@@ -17,7 +26,7 @@
17
26
  - Retry a maximum of :max_retries instead of failing immediately
18
27
 
19
28
  ## 2.0.0
20
- - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
29
+ - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
21
30
  instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
22
31
  - Dependency on logstash-core update to 2.0
23
32
 
data/CONTRIBUTORS CHANGED
@@ -16,6 +16,7 @@ Contributors:
16
16
  * Richard Pijnenburg (electrical)
17
17
  * Suyog Rao (suyograo)
18
18
  * hal-awesome
19
+ * Guy Boertje (guyboertje)
19
20
 
20
21
  Note: If you've sent us patches, bug reports, or otherwise contributed to
21
22
  Logstash, and you aren't on the list above and want to be, please let us know
@@ -2,17 +2,20 @@
2
2
  require "logstash/filters/base"
3
3
  require "logstash/namespace"
4
4
  require "lru_redux"
5
+ require "resolv"
6
+ require "timeout"
7
+
8
+ java_import 'java.net.IDN'
5
9
 
6
10
 
7
11
  # The DNS filter performs a lookup (either an A record/CNAME record lookup
8
12
  # or a reverse lookup at the PTR record) on records specified under the
9
- # `reverse` and `resolve` arrays.
13
+ # `reverse` arrays or respectively under the `resolve` arrays.
10
14
  #
11
15
  # The config should look like this:
12
16
  # [source,ruby]
13
17
  # filter {
14
18
  # dns {
15
- # type => 'type'
16
19
  # reverse => [ "source_host", "field_with_address" ]
17
20
  # resolve => [ "field_with_fqdn" ]
18
21
  # action => "replace"
@@ -63,14 +66,15 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
63
66
  # how long to cache failed requests (in seconds)
64
67
  config :failed_cache_ttl, :validate => :number, :default => 5
65
68
 
69
+ # Use custom hosts file(s). For example: `["/var/db/my_custom_hosts"]`
70
+ config :hostsfile, :validate => :array
71
+
66
72
  public
67
73
  def register
68
- require "resolv"
69
- require "timeout"
70
- if @nameserver.nil?
74
+ if @nameserver.nil? && @hostsfile.nil?
71
75
  @resolv = Resolv.new
72
76
  else
73
- @resolv = Resolv.new(resolvers=[::Resolv::Hosts.new, ::Resolv::DNS.new(:nameserver => @nameserver, :search => [], :ndots => 1)])
77
+ @resolv = Resolv.new(build_resolvers)
74
78
  end
75
79
 
76
80
  if @hit_cache_size > 0
@@ -99,6 +103,21 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
99
103
  end
100
104
 
101
105
  private
106
+
107
+ def build_resolvers
108
+ build_user_host_resolvers.concat([::Resolv::Hosts.new]).concat(build_user_dns_resolver)
109
+ end
110
+
111
+ def build_user_host_resolvers
112
+ return [] if @hostsfile.nil? || @hostsfile.empty?
113
+ @hostsfile.map{|fn| ::Resolv::Hosts.new(fn)}
114
+ end
115
+
116
+ def build_user_dns_resolver
117
+ return [] if @nameserver.nil? || @nameserver.empty?
118
+ [::Resolv::DNS.new(:nameserver => @nameserver, :search => [], :ndots => 1)]
119
+ end
120
+
102
121
  def resolve(event)
103
122
  @resolve.each do |field|
104
123
  is_array = false
@@ -245,11 +264,13 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
245
264
 
246
265
  private
247
266
  def getname(address)
248
- @resolv.getname(address).force_encoding(Encoding::UTF_8)
267
+ name = @resolv.getname(address).force_encoding(Encoding::UTF_8)
268
+ IDN.toUnicode(name)
249
269
  end
250
270
 
251
271
  private
252
272
  def getaddress(name)
253
- @resolv.getaddress(name).force_encoding(Encoding::UTF_8)
273
+ idn = IDN.toASCII(name)
274
+ @resolv.getaddress(idn).force_encoding(Encoding::UTF_8)
254
275
  end
255
276
  end # class LogStash::Filters::DNS
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-dns'
4
- s.version = '3.0.1'
4
+ s.version = '3.0.3'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "This filter will resolve any IP addresses from a field of your choosing."
7
7
  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"
@@ -20,9 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
21
21
 
22
22
  # Gem dependencies
23
- s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
23
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
24
  s.add_runtime_dependency 'lru_redux', "~> 1.1.0"
25
25
 
26
26
  s.add_development_dependency 'logstash-devutils'
27
27
  end
28
-
@@ -4,357 +4,392 @@ require "logstash/filters/dns"
4
4
  require "resolv"
5
5
 
6
6
  describe LogStash::Filters::DNS do
7
- before(:each) do
8
- allow_any_instance_of(Resolv).to receive(:getaddress).with("carrera.databits.net").and_return("199.192.228.250")
9
- allow_any_instance_of(Resolv).to receive(:getaddress).with("does.not.exist").and_raise(Resolv::ResolvError)
10
- allow_any_instance_of(Resolv).to receive(:getaddress).with("nonexistanthostname###.net").and_raise(Resolv::ResolvError)
11
- allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
12
- allow_any_instance_of(Resolv).to receive(:getname).with("127.0.0.1").and_return("localhost")
13
- allow_any_instance_of(Resolv).to receive(:getname).with("128.0.0.1").and_raise(Resolv::ResolvError)
14
- allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
15
- end
7
+ describe "with stubbed Resolv" do
8
+ before(:each) do
9
+ allow_any_instance_of(Resolv).to receive(:getaddress).with("carrera.databits.net").and_return("199.192.228.250")
10
+ allow_any_instance_of(Resolv).to receive(:getaddress).with("does.not.exist").and_raise(Resolv::ResolvError)
11
+ allow_any_instance_of(Resolv).to receive(:getaddress).with("nonexistanthostname###.net").and_raise(Resolv::ResolvError)
12
+ allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
13
+ allow_any_instance_of(Resolv).to receive(:getname).with("127.0.0.1").and_return("localhost")
14
+ allow_any_instance_of(Resolv).to receive(:getname).with("128.0.0.1").and_raise(Resolv::ResolvError)
15
+ allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
16
+ end
16
17
 
17
- describe "dns reverse lookup, replace (on a field)" do
18
- config <<-CONFIG
19
- filter {
20
- dns {
21
- reverse => "foo"
22
- action => "replace"
18
+ describe "dns reverse lookup, replace (on a field)" do
19
+ config <<-CONFIG
20
+ filter {
21
+ dns {
22
+ reverse => "foo"
23
+ action => "replace"
24
+ }
23
25
  }
24
- }
25
- CONFIG
26
+ CONFIG
26
27
 
27
- sample("foo" => "199.192.228.250") do
28
- insist { subject.get("foo") } == "carrera.databits.net"
28
+ sample("foo" => "199.192.228.250") do
29
+ insist { subject.get("foo") } == "carrera.databits.net"
30
+ end
29
31
  end
30
- end
31
32
 
32
- describe "dns reverse lookup, append" do
33
- config <<-CONFIG
34
- filter {
35
- dns {
36
- reverse => "foo"
37
- action => "append"
33
+ describe "dns reverse lookup, append" do
34
+ config <<-CONFIG
35
+ filter {
36
+ dns {
37
+ reverse => "foo"
38
+ action => "append"
39
+ }
38
40
  }
39
- }
40
- CONFIG
41
+ CONFIG
41
42
 
42
- sample("foo" => "199.192.228.250") do
43
- insist { subject.get("foo")[0] } == "199.192.228.250"
44
- insist { subject.get("foo")[1] } == "carrera.databits.net"
43
+ sample("foo" => "199.192.228.250") do
44
+ insist { subject.get("foo")[0] } == "199.192.228.250"
45
+ insist { subject.get("foo")[1] } == "carrera.databits.net"
46
+ end
45
47
  end
46
- end
47
48
 
48
- describe "dns reverse lookup, not an IP" do
49
- config <<-CONFIG
50
- filter {
51
- dns {
52
- reverse => "foo"
49
+ describe "dns reverse lookup, not an IP" do
50
+ config <<-CONFIG
51
+ filter {
52
+ dns {
53
+ reverse => "foo"
54
+ }
53
55
  }
54
- }
55
- CONFIG
56
+ CONFIG
56
57
 
57
- sample("foo" => "not.an.ip") do
58
- insist { subject.get("foo") } == "not.an.ip"
58
+ sample("foo" => "not.an.ip") do
59
+ insist { subject.get("foo") } == "not.an.ip"
60
+ end
59
61
  end
60
- end
61
62
 
62
- describe "dns resolve lookup, replace" do
63
- config <<-CONFIG
64
- filter {
65
- dns {
66
- resolve => ["host"]
67
- action => "replace"
68
- add_tag => ["success"]
63
+ describe "dns resolve lookup, replace" do
64
+ config <<-CONFIG
65
+ filter {
66
+ dns {
67
+ resolve => ["host"]
68
+ action => "replace"
69
+ add_tag => ["success"]
70
+ }
69
71
  }
70
- }
71
- CONFIG
72
+ CONFIG
72
73
 
73
- sample("host" => "carrera.databits.net") do
74
- insist { subject.get("host") } == "199.192.228.250"
75
- insist { subject.get("tags") } == ["success"]
74
+ sample("host" => "carrera.databits.net") do
75
+ insist { subject.get("host") } == "199.192.228.250"
76
+ insist { subject.get("tags") } == ["success"]
77
+ end
76
78
  end
77
- end
78
79
 
79
- describe "dns fail resolve lookup, don't add tag" do
80
- config <<-CONFIG
81
- filter {
82
- dns {
83
- resolve => ["host1", "host2"]
84
- action => "replace"
85
- add_tag => ["success"]
80
+ describe "dns fail resolve lookup, don't add tag" do
81
+ config <<-CONFIG
82
+ filter {
83
+ dns {
84
+ resolve => ["host1", "host2"]
85
+ action => "replace"
86
+ add_tag => ["success"]
87
+ }
86
88
  }
87
- }
88
- CONFIG
89
+ CONFIG
89
90
 
90
- sample("host1" => "carrera.databits.net", "host2" => "nonexistanthostname###.net") do
91
- insist { subject.get("tags") }.nil?
92
- insist { subject.get("host1") } == "199.192.228.250"
93
- insist { subject.get("host2") } == "nonexistanthostname###.net"
91
+ sample("host1" => "carrera.databits.net", "host2" => "nonexistanthostname###.net") do
92
+ insist { subject.get("tags") }.nil?
93
+ insist { subject.get("host1") } == "199.192.228.250"
94
+ insist { subject.get("host2") } == "nonexistanthostname###.net"
95
+ end
94
96
  end
95
- end
96
97
 
97
- describe "dns resolves lookups, adds tag" do
98
- config <<-CONFIG
99
- filter {
100
- dns {
101
- resolve => ["host1", "host2"]
102
- action => "replace"
103
- add_tag => ["success"]
98
+ describe "dns resolves lookups, adds tag" do
99
+ config <<-CONFIG
100
+ filter {
101
+ dns {
102
+ resolve => ["host1", "host2"]
103
+ action => "replace"
104
+ add_tag => ["success"]
105
+ }
104
106
  }
105
- }
106
- CONFIG
107
+ CONFIG
107
108
 
108
- sample("host1" => "carrera.databits.net", "host2" => "carrera.databits.net") do
109
- insist { subject.get("tags") } == ["success"]
109
+ sample("host1" => "carrera.databits.net", "host2" => "carrera.databits.net") do
110
+ insist { subject.get("tags") } == ["success"]
111
+ end
110
112
  end
111
- end
112
113
 
113
- describe "dns resolves and reverses, fails last, no tag" do
114
- config <<-CONFIG
115
- filter {
116
- dns {
117
- resolve => ["host1"]
118
- reverse => ["ip1", "ip2"]
119
- action => "replace"
120
- add_tag => ["success"]
114
+ describe "dns resolves and reverses, fails last, no tag" do
115
+ config <<-CONFIG
116
+ filter {
117
+ dns {
118
+ resolve => ["host1"]
119
+ reverse => ["ip1", "ip2"]
120
+ action => "replace"
121
+ add_tag => ["success"]
122
+ }
121
123
  }
122
- }
123
- CONFIG
124
-
125
- sample("host1" => "carrera.databits.net",
126
- "ip1" => "127.0.0.1",
127
- "ip2" => "128.0.0.1") do
128
- insist { subject.get("tags") }.nil?
129
- insist { subject.get("host1") } == "199.192.228.250"
130
- insist { subject.get("ip1") } == "localhost"
131
- insist { subject.get("ip2") } == "128.0.0.1"
124
+ CONFIG
125
+
126
+ sample("host1" => "carrera.databits.net",
127
+ "ip1" => "127.0.0.1",
128
+ "ip2" => "128.0.0.1") do
129
+ insist { subject.get("tags") }.nil?
130
+ insist { subject.get("host1") } == "199.192.228.250"
131
+ insist { subject.get("ip1") } == "localhost"
132
+ insist { subject.get("ip2") } == "128.0.0.1"
133
+ end
132
134
  end
133
- end
134
135
 
135
- describe "dns resolve lookup, replace (on a field)" do
136
- config <<-CONFIG
137
- filter {
138
- dns {
139
- resolve => "foo"
140
- action => "replace"
136
+ describe "dns resolve lookup, replace (on a field)" do
137
+ config <<-CONFIG
138
+ filter {
139
+ dns {
140
+ resolve => "foo"
141
+ action => "replace"
142
+ }
141
143
  }
142
- }
143
- CONFIG
144
+ CONFIG
144
145
 
145
- sample("foo" => "carrera.databits.net") do
146
- insist { subject.get("foo") } == "199.192.228.250"
146
+ sample("foo" => "carrera.databits.net") do
147
+ insist { subject.get("foo") } == "199.192.228.250"
148
+ end
147
149
  end
148
- end
149
150
 
150
- describe "dns resolve lookup, skip multi-value" do
151
- config <<-CONFIG
152
- filter {
153
- dns {
154
- resolve => "foo"
155
- action => "replace"
151
+ describe "dns resolve lookup, skip multi-value" do
152
+ config <<-CONFIG
153
+ filter {
154
+ dns {
155
+ resolve => "foo"
156
+ action => "replace"
157
+ }
156
158
  }
157
- }
158
- CONFIG
159
+ CONFIG
159
160
 
160
- sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
161
- insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
161
+ sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
162
+ insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
163
+ end
162
164
  end
163
- end
164
165
 
165
- describe "dns resolve lookup, append" do
166
- config <<-CONFIG
167
- filter {
168
- dns {
169
- resolve => "foo"
170
- action => "append"
166
+ describe "dns resolve lookup, append" do
167
+ config <<-CONFIG
168
+ filter {
169
+ dns {
170
+ resolve => "foo"
171
+ action => "append"
172
+ }
171
173
  }
172
- }
173
- CONFIG
174
+ CONFIG
174
175
 
175
- sample("foo" => "carrera.databits.net") do
176
- insist { subject.get("foo")[0] } == "carrera.databits.net"
177
- insist { subject.get("foo")[1] } == "199.192.228.250"
176
+ sample("foo" => "carrera.databits.net") do
177
+ insist { subject.get("foo")[0] } == "carrera.databits.net"
178
+ insist { subject.get("foo")[1] } == "199.192.228.250"
179
+ end
178
180
  end
179
- end
180
181
 
181
- describe "dns resolve lookup, append with multi-value does nothing" do
182
- config <<-CONFIG
183
- filter {
184
- dns {
185
- resolve => "foo"
186
- action => "append"
182
+ describe "dns resolve lookup, append with multi-value does nothing" do
183
+ config <<-CONFIG
184
+ filter {
185
+ dns {
186
+ resolve => "foo"
187
+ action => "append"
188
+ }
187
189
  }
188
- }
189
- CONFIG
190
+ CONFIG
190
191
 
191
- sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
192
- insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
192
+ sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
193
+ insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
194
+ end
193
195
  end
194
- end
195
196
 
196
- describe "dns resolve lookup, not a valid hostname" do
197
- config <<-CONFIG
198
- filter {
199
- dns {
200
- resolve=> "foo"
197
+ describe "dns resolve lookup, not a valid hostname" do
198
+ config <<-CONFIG
199
+ filter {
200
+ dns {
201
+ resolve=> "foo"
202
+ }
201
203
  }
202
- }
203
- CONFIG
204
+ CONFIG
204
205
 
205
- sample("foo" => "does.not.exist") do
206
- insist { subject.get("foo") } == "does.not.exist"
206
+ sample("foo" => "does.not.exist") do
207
+ insist { subject.get("foo") } == "does.not.exist"
208
+ end
207
209
  end
208
- end
209
210
 
210
- describe "dns resolve lookup, single custom nameserver" do
211
- config <<-CONFIG
212
- filter {
213
- dns {
214
- resolve => ["host"]
215
- action => "replace"
216
- nameserver => "8.8.8.8"
211
+ describe "dns resolve lookup, single custom nameserver" do
212
+ config <<-CONFIG
213
+ filter {
214
+ dns {
215
+ resolve => ["host"]
216
+ action => "replace"
217
+ nameserver => "8.8.8.8"
218
+ }
217
219
  }
218
- }
219
- CONFIG
220
+ CONFIG
220
221
 
221
- sample("host" => "carrera.databits.net") do
222
- insist { subject.get("host") } == "199.192.228.250"
222
+ sample("host" => "carrera.databits.net") do
223
+ insist { subject.get("host") } == "199.192.228.250"
224
+ end
223
225
  end
224
- end
225
226
 
226
- describe "dns resolve lookup, multiple nameserver fallback" do
227
- config <<-CONFIG
228
- filter {
229
- dns {
230
- resolve => ["host"]
231
- action => "replace"
232
- nameserver => ["127.0.0.99", "8.8.8.8"]
227
+ describe "dns resolve lookup, multiple nameserver fallback" do
228
+ config <<-CONFIG
229
+ filter {
230
+ dns {
231
+ resolve => ["host"]
232
+ action => "replace"
233
+ nameserver => ["127.0.0.99", "8.8.8.8"]
234
+ }
233
235
  }
234
- }
235
- CONFIG
236
+ CONFIG
236
237
 
237
- sample("host" => "carrera.databits.net") do
238
- insist { subject.get("host") } == "199.192.228.250"
238
+ sample("host" => "carrera.databits.net") do
239
+ insist { subject.get("host") } == "199.192.228.250"
240
+ end
239
241
  end
240
- end
241
242
 
242
- describe "dns resolve lookup, multiple nameserver fallback" do
243
- config <<-CONFIG
244
- filter {
245
- dns {
246
- resolve => ["host"]
247
- action => "replace"
248
- nameserver => ["127.0.0.99", "8.8.8.8"]
243
+ describe "dns resolve lookup, multiple nameserver fallback" do
244
+ config <<-CONFIG
245
+ filter {
246
+ dns {
247
+ resolve => ["host"]
248
+ action => "replace"
249
+ nameserver => ["127.0.0.99", "8.8.8.8"]
250
+ }
249
251
  }
250
- }
251
- CONFIG
252
+ CONFIG
252
253
 
253
- sample("host" => "carrera.databits.net") do
254
- insist { subject.get("host") } == "199.192.228.250"
254
+ sample("host" => "carrera.databits.net") do
255
+ insist { subject.get("host") } == "199.192.228.250"
256
+ end
255
257
  end
256
- end
257
258
 
258
- describe "failed cache" do
259
+ describe "failed cache" do
259
260
 
260
- let(:subject) { LogStash::Filters::DNS.new(config) }
261
- let(:event1) { LogStash::Event.new("message" => "unkownhost") }
262
- let(:event2) { LogStash::Event.new("message" => "unkownhost") }
261
+ let(:subject) { LogStash::Filters::DNS.new(config) }
262
+ let(:event1) { LogStash::Event.new("message" => "unkownhost") }
263
+ let(:event2) { LogStash::Event.new("message" => "unkownhost") }
263
264
 
264
- before(:each) do
265
- allow(subject).to receive(:getaddress).and_raise Resolv::ResolvError
266
- subject.register
267
- end
265
+ before(:each) do
266
+ allow(subject).to receive(:getaddress).and_raise Resolv::ResolvError
267
+ subject.register
268
+ end
268
269
 
269
- context "when enabled" do
270
- let(:config) { { "resolve" => ["message"], "failed_cache_size" => 3 } }
270
+ context "when enabled" do
271
+ let(:config) { { "resolve" => ["message"], "failed_cache_size" => 3 } }
271
272
 
272
- it "should cache a failed lookup" do
273
- expect(subject).to receive(:getaddress).once
274
- subject.filter(event1)
275
- subject.filter(event2)
273
+ it "should cache a failed lookup" do
274
+ expect(subject).to receive(:getaddress).once
275
+ subject.filter(event1)
276
+ subject.filter(event2)
277
+ end
276
278
  end
277
- end
278
279
 
279
- context "when disabled" do
280
- let(:config) { { "resolve" => ["message"] } }
280
+ context "when disabled" do
281
+ let(:config) { { "resolve" => ["message"] } }
281
282
 
282
- it "should not cache a failed lookup" do
283
- expect(subject).to receive(:getaddress).twice
284
- subject.filter(event1)
285
- subject.filter(event2)
283
+ it "should not cache a failed lookup" do
284
+ expect(subject).to receive(:getaddress).twice
285
+ subject.filter(event1)
286
+ subject.filter(event2)
287
+ end
286
288
  end
287
289
  end
288
- end
289
290
 
290
- describe "hit cache" do
291
+ describe "hit cache" do
291
292
 
292
- let(:subject) { LogStash::Filters::DNS.new(config) }
293
- let(:event1) { LogStash::Event.new("message" => "unkownhost") }
294
- let(:event2) { LogStash::Event.new("message" => "unkownhost") }
293
+ let(:subject) { LogStash::Filters::DNS.new(config) }
294
+ let(:event1) { LogStash::Event.new("message" => "unkownhost") }
295
+ let(:event2) { LogStash::Event.new("message" => "unkownhost") }
295
296
 
296
- before(:each) do
297
- allow(subject).to receive(:getaddress).and_return("127.0.0.1")
298
- subject.register
299
- end
297
+ before(:each) do
298
+ allow(subject).to receive(:getaddress).and_return("127.0.0.1")
299
+ subject.register
300
+ end
300
301
 
301
- context "when enabled" do
302
- let(:config) { { "resolve" => ["message"], "hit_cache_size" => 3 } }
302
+ context "when enabled" do
303
+ let(:config) { { "resolve" => ["message"], "hit_cache_size" => 3 } }
303
304
 
304
- it "should cache a succesful lookup" do
305
- expect(subject).to receive(:getaddress).once
306
- subject.filter(event1)
307
- subject.filter(event2)
305
+ it "should cache a succesful lookup" do
306
+ expect(subject).to receive(:getaddress).once
307
+ subject.filter(event1)
308
+ subject.filter(event2)
309
+ end
308
310
  end
309
- end
310
311
 
311
- context "when disabled" do
312
- let(:config) { { "resolve" => ["message"] } }
312
+ context "when disabled" do
313
+ let(:config) { { "resolve" => ["message"] } }
313
314
 
314
- it "should not cache a successful lookup" do
315
- expect(subject).to receive(:getaddress).twice
316
- subject.filter(event1)
317
- subject.filter(event2)
315
+ it "should not cache a successful lookup" do
316
+ expect(subject).to receive(:getaddress).twice
317
+ subject.filter(event1)
318
+ subject.filter(event2)
319
+ end
318
320
  end
319
321
  end
320
- end
321
322
 
322
- describe "retries" do
323
+ describe "retries" do
323
324
 
324
- let(:subject) { LogStash::Filters::DNS.new(config) }
325
- let(:event) { LogStash::Event.new("message" => "unkownhost") }
326
- let(:max_retries) { 3 }
327
- let(:config) { { "resolve" => ["message"], "max_retries" => max_retries } }
325
+ let(:subject) { LogStash::Filters::DNS.new(config) }
326
+ let(:event) { LogStash::Event.new("message" => "unkownhost") }
327
+ let(:max_retries) { 3 }
328
+ let(:config) { { "resolve" => ["message"], "max_retries" => max_retries } }
328
329
 
329
- before(:each) { subject.register }
330
+ before(:each) { subject.register }
330
331
 
331
- context "when failing permanently" do
332
- before(:each) do
333
- allow(subject).to receive(:getaddress).and_raise(Timeout::Error)
332
+ context "when failing permanently" do
333
+ before(:each) do
334
+ allow(subject).to receive(:getaddress).and_raise(Timeout::Error)
335
+ end
336
+
337
+ it "should fail a resolve after max_retries" do
338
+ expect(subject).to receive(:getaddress).exactly(max_retries+1).times
339
+ subject.filter(event)
340
+ end
334
341
  end
335
342
 
336
- it "should fail a resolve after max_retries" do
337
- expect(subject).to receive(:getaddress).exactly(max_retries+1).times
338
- subject.filter(event)
343
+ context "when failing temporarily" do
344
+ before(:each) do
345
+ allow(subject).to receive(:getaddress) do
346
+ @try ||= 0
347
+ if @try < 2
348
+ @try = @try + 1
349
+ raise Timeout::Error
350
+ else
351
+ "127.0.0.1"
352
+ end
353
+ end
354
+ end
355
+
356
+ it "should resolve before max_retries" do
357
+ expect(subject).to receive(:getaddress).exactly(3).times
358
+ subject.filter(event)
359
+ end
339
360
  end
340
361
  end
362
+ end
363
+
364
+ describe "with nameserver integration" do
365
+ describe "lookup using fixture hosts file" do
366
+ let(:subject) { LogStash::Filters::DNS.new(config) }
367
+ let(:hostsfile) { File.join(File.dirname(__FILE__), "..", "fixtures", "hosts") }
368
+ # From the custom hosts file
369
+ # 10.10.0.1 xn--d1acpjx3f.xn--p1ai # -> Яндекс.рф
370
+ # 10.10.0.2 xn--mller-kva.com # -> müller.com
341
371
 
342
- context "when failing temporarily" do
343
372
  before(:each) do
344
- allow(subject).to receive(:getaddress) do
345
- @try ||= 0
346
- if @try < 2
347
- @try = @try + 1
348
- raise Timeout::Error
349
- else
350
- "127.0.0.1"
351
- end
373
+ subject.register
374
+ subject.filter(event)
375
+ end
376
+
377
+ context "when domain is an IDN" do
378
+ let(:config) { { "resolve" => ["domain"], "action" => "replace", "hostsfile" => [hostsfile]} }
379
+ let(:event) { LogStash::Event.new("domain" => "Яндекс.рф") }
380
+
381
+ it "should return the IP" do
382
+ expect(event.get("domain")).to eq("10.10.0.1")
352
383
  end
353
384
  end
354
385
 
355
- it "should resolve before max_retries" do
356
- expect(subject).to receive(:getaddress).exactly(3).times
357
- subject.filter(event)
386
+ context "when IP points to an IDN" do
387
+ let(:config) { { "reverse" => ["domain"], "action" => "replace", "hostsfile" => [hostsfile]} }
388
+ let(:event) { LogStash::Event.new("domain" => "10.10.0.2") }
389
+
390
+ it "should return the IDN" do
391
+ expect(event.get("domain")).to eq("müller.com")
392
+ end
358
393
  end
359
394
  end
360
395
  end
@@ -0,0 +1,2 @@
1
+ 10.10.0.1 xn--d1acpjx3f.xn--p1ai # Яндекс.рф
2
+ 10.10.0.2 xn--mller-kva.com # müller.com
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-dns
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-09 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.60'
19
+ - - "<="
17
20
  - !ruby/object:Gem::Version
18
- version: '2.0'
21
+ version: '2.99'
19
22
  name: logstash-core-plugin-api
20
23
  prerelease: false
21
24
  type: :runtime
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
25
31
  - !ruby/object:Gem::Version
26
- version: '2.0'
32
+ version: '2.99'
27
33
  - !ruby/object:Gem::Dependency
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
@@ -67,6 +73,7 @@ files:
67
73
  - lib/logstash/filters/dns.rb
68
74
  - logstash-filter-dns.gemspec
69
75
  - spec/filters/dns_spec.rb
76
+ - spec/fixtures/hosts
70
77
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
71
78
  licenses:
72
79
  - Apache License (2.0)
@@ -89,9 +96,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
96
  version: '0'
90
97
  requirements: []
91
98
  rubyforge_project:
92
- rubygems_version: 2.4.8
99
+ rubygems_version: 2.6.3
93
100
  signing_key:
94
101
  specification_version: 4
95
102
  summary: This filter will resolve any IP addresses from a field of your choosing.
96
103
  test_files:
97
104
  - spec/filters/dns_spec.rb
105
+ - spec/fixtures/hosts