sensu-plugins-dns 1.4.1 → 2.0.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 +11 -4
- data/bin/check-dns-zone.rb +193 -0
- data/bin/check-dns.rb +2 -2
- data/bin/metrics-dns.rb +1 -1
- data/lib/sensu-plugins-dns/version.rb +5 -3
- metadata +39 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9baf92765cfd62035a6b839ac3ad7675ce33efa5495882da84dc22337bf5cb36
|
4
|
+
data.tar.gz: 61babc44dc892281dbcff81dadb790c97bb6b4d9e5a615910603cc21037246f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a332c8c0cd2bf7b0cad5e3ed88cece9e7a0955132ddf34dfdedae7ff3c8f286b9faeaa1d429aa9a5f5f16c253ca14a6247e23a68faa3922dee3eb9b99dd984df
|
7
|
+
data.tar.gz: a65a420f79058d667b07fe78ff3bac32d20507329c18ad1fc23fbcbdd8f5e7d9ce17a5ede27cbfad1adddc884c0976e11c70e53988f0e6ffb18287643514d44f
|
data/CHANGELOG.md
CHANGED
@@ -5,10 +5,16 @@ This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins
|
|
5
5
|
|
6
6
|
## [Unreleased]
|
7
7
|
|
8
|
+
## [2.0.0] - 03-29-2018
|
9
|
+
### Breaking Changes
|
10
|
+
- Dropping ruby `< 2.2` support (@yuri-zubov)
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
-
|
12
|
+
### Security
|
13
|
+
- updated yard dependency to `~> 0.9.11` per: https://nvd.nist.gov/vuln/detail/CVE-2017-17042 (@yuri-zubov sponsored by Actility, https://www.actility.com)
|
14
|
+
- updated rubocop dependency to `~> 0.51.0` per: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8418. (@yuri-zubov sponsored by Actility, https://www.actility.com)
|
15
|
+
|
16
|
+
### Added
|
17
|
+
- Added many checks for DNS zone (@yuri-zubov sponsored by Actility, https://www.actility.com)
|
12
18
|
|
13
19
|
## [1.4.0] - 2018-03-21
|
14
20
|
### Added
|
@@ -85,7 +91,8 @@ This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins
|
|
85
91
|
### Changed
|
86
92
|
- removed cruft from /lib
|
87
93
|
|
88
|
-
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/
|
94
|
+
[Unreleased]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/2.0.0...HEAD
|
95
|
+
[2.0.0]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/1.4.0...2.0.0
|
89
96
|
[1.4.0]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/1.3.0...1.4.0
|
90
97
|
[1.3.0]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/1.2.1...1.3.0
|
91
98
|
[1.2.1]: https://github.com/sensu-plugins/sensu-plugins-dns/compare/1.2.0...1/1.2.1
|
@@ -0,0 +1,193 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-dns
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin checks DNS Zone using dnsruby and whois.
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux, BSD
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
# gem: dnsruby
|
17
|
+
# gem: whois
|
18
|
+
#
|
19
|
+
# USAGE:
|
20
|
+
# example commands
|
21
|
+
#
|
22
|
+
# NOTES:
|
23
|
+
# Does it behave differently on specific platforms, specific use cases, etc
|
24
|
+
#
|
25
|
+
# LICENSE:
|
26
|
+
# Zubov Yuri <yury.zubau@gmail.com> sponsored by Actility, https://www.actility.com
|
27
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
28
|
+
# for details.
|
29
|
+
#
|
30
|
+
|
31
|
+
require 'sensu-plugin/check/cli'
|
32
|
+
require 'dnsruby'
|
33
|
+
require 'whois'
|
34
|
+
require 'whois/parser'
|
35
|
+
require 'ipaddr'
|
36
|
+
require 'resolv'
|
37
|
+
|
38
|
+
#
|
39
|
+
# DNS
|
40
|
+
#
|
41
|
+
class DNSZone < Sensu::Plugin::Check::CLI
|
42
|
+
option :domain,
|
43
|
+
description: 'Domain to resolve (or ip if type PTR)',
|
44
|
+
short: '-d DOMAIN',
|
45
|
+
long: '--domain DOMAIN'
|
46
|
+
|
47
|
+
option :threshold,
|
48
|
+
description: 'Percentage of DNS queries that must succeed',
|
49
|
+
short: '-l PERCENT',
|
50
|
+
long: '--threshold PERCENT',
|
51
|
+
proc: proc(&:to_i),
|
52
|
+
default: 100
|
53
|
+
|
54
|
+
option :timeout,
|
55
|
+
description: 'Set timeout for query',
|
56
|
+
short: '-T TIMEOUT',
|
57
|
+
long: '--timeout TIMEOUT',
|
58
|
+
proc: proc(&:to_i),
|
59
|
+
default: 5
|
60
|
+
|
61
|
+
option :warn_only,
|
62
|
+
description: 'Warn instead of critical on failure',
|
63
|
+
short: '-w',
|
64
|
+
long: '--warn-only',
|
65
|
+
boolean: true
|
66
|
+
|
67
|
+
def resolve_ns
|
68
|
+
Resolv::DNS.new.getresources(config[:domain], Resolv::DNS::Resource::IN::NS).map { |e| e.name.to_s }
|
69
|
+
end
|
70
|
+
|
71
|
+
def check_whois(entries)
|
72
|
+
errors = []
|
73
|
+
success = []
|
74
|
+
record = Whois.whois(config[:domain])
|
75
|
+
parser = record.parser
|
76
|
+
additional_text = "(whois #{parser.nameservers.map(&:name)}) (dig #{entries})"
|
77
|
+
if Set.new(parser.nameservers.map(&:name)) == Set.new(entries)
|
78
|
+
success << "Resolved #{config[:domain]} #{config[:type]} equal with whois #{additional_text}"
|
79
|
+
else
|
80
|
+
errors << "Resolved #{config[:domain]} #{config[:type]} did not include #{config[:result]} #{additional_text}"
|
81
|
+
end
|
82
|
+
[errors, success]
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_results(entries)
|
86
|
+
errors = []
|
87
|
+
success = []
|
88
|
+
|
89
|
+
%w[check_whois check_axfr soa_query].each do |check|
|
90
|
+
result = send(check, entries)
|
91
|
+
errors.push(*result[0])
|
92
|
+
success.push(*result[1])
|
93
|
+
end
|
94
|
+
|
95
|
+
result = check_dns_connection(entries, true)
|
96
|
+
errors.push(*result[0])
|
97
|
+
success.push(*result[1])
|
98
|
+
|
99
|
+
result = check_dns_connection(entries, false)
|
100
|
+
errors.push(*result[0])
|
101
|
+
success.push(*result[1])
|
102
|
+
|
103
|
+
[errors, success]
|
104
|
+
end
|
105
|
+
|
106
|
+
def check_dns_connection(entries, use_tcp = false)
|
107
|
+
errors = []
|
108
|
+
success = []
|
109
|
+
|
110
|
+
entries.each do |ns|
|
111
|
+
Dnsruby::Resolv.getaddresses(ns).each do |ip|
|
112
|
+
begin
|
113
|
+
resolv = Dnsruby::Resolver.new(nameserver: ip.to_s, do_caching: false, use_tcp: use_tcp)
|
114
|
+
resolv.query_timeout = config[:timeout]
|
115
|
+
resolv.query(config[:domain], Dnsruby::Types.ANY)
|
116
|
+
type_of_connection = use_tcp ? 'tcp' : 'udp'
|
117
|
+
success << "Resolved DNS #{ns}(#{ip}) uses #{type_of_connection}"
|
118
|
+
rescue StandardError
|
119
|
+
errors << "Resolved DNS #{ns}(#{ip}) doesn't use #{type_of_connection}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
[errors, success]
|
124
|
+
end
|
125
|
+
|
126
|
+
def check_axfr(entries)
|
127
|
+
errors = []
|
128
|
+
success = []
|
129
|
+
|
130
|
+
entries.each do |ns|
|
131
|
+
Dnsruby::Resolv.new.getaddresses(ns).each do |ip|
|
132
|
+
begin
|
133
|
+
resolv = Dnsruby::Resolver.new(nameserver: ip.to_s, do_caching: false)
|
134
|
+
resolv.query_timeout = config[:timeout]
|
135
|
+
resolv.query(config[:domain], 'AXFR', 'IN')
|
136
|
+
|
137
|
+
errors << "Resolved DNS #{ns}(#{ip}) has AXFR"
|
138
|
+
rescue StandardError
|
139
|
+
success << "Resolved DNS #{ns}(#{ip}) doesn't have AXFR"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
[errors, success]
|
144
|
+
end
|
145
|
+
|
146
|
+
def soa_query(entries)
|
147
|
+
errors = []
|
148
|
+
success = []
|
149
|
+
resp = ::Resolv::DNS.new.getresources(config[:domain], Resolv::DNS::Resource::IN::SOA)
|
150
|
+
primary_serial_number = resp.map(&:serial).first
|
151
|
+
primary_server = resp.map { |r| r.mname.to_s }
|
152
|
+
primary_server_name = resp.map { |r| r.rname.to_s }
|
153
|
+
|
154
|
+
entries.each_with_index do |ns, _index|
|
155
|
+
::Resolv::DNS.new.getaddresses(ns).each do |ip|
|
156
|
+
serial_number = nil
|
157
|
+
server_name = nil
|
158
|
+
server = nil
|
159
|
+
|
160
|
+
::Resolv::DNS.open nameserver: ip.to_s, ndots: 1 do |dns|
|
161
|
+
resp = dns.getresources(config[:domain], Resolv::DNS::Resource::IN::SOA)
|
162
|
+
serial_number = resp.map(&:serial).first
|
163
|
+
server_name = resp.map { |r| r.rname.to_s }
|
164
|
+
server = resp.map { |r| r.mname.to_s }
|
165
|
+
end
|
166
|
+
|
167
|
+
if serial_number == primary_serial_number
|
168
|
+
success << "SOA Query correct for server #{ns}(#{ip})} SOA #{server_name} (#{serial_number}) #{server} - \
|
169
|
+
SOA primary server #{primary_server_name} (#{primary_serial_number}) #{primary_server}"
|
170
|
+
else
|
171
|
+
errors << "SOA Query wrong for server #{ns}(#{ip})} SOA #{server_name} (#{serial_number}) #{server} - \
|
172
|
+
SOA primary server #{primary_server_name} (#{primary_serial_number}) #{primary_server}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
[errors, success]
|
178
|
+
end
|
179
|
+
|
180
|
+
def run
|
181
|
+
unknown 'No domain specified' if config[:domain].nil?
|
182
|
+
|
183
|
+
entries = resolve_ns
|
184
|
+
errors, success = check_results(entries)
|
185
|
+
percent = success.count.to_f / (success.count.to_f + errors.count.to_f) * 100
|
186
|
+
if percent < config[:threshold]
|
187
|
+
output = "#{percent.to_i}% of tests succeeded: #{errors.uniq.join(", \n")}"
|
188
|
+
config[:warn_only] ? warning(output) : critical(output)
|
189
|
+
else
|
190
|
+
ok(success.uniq.join(", \n"))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/bin/check-dns.rb
CHANGED
@@ -133,7 +133,7 @@ class DNS < Sensu::Plugin::Check::CLI
|
|
133
133
|
begin
|
134
134
|
entry = resolv.query(config[:domain], config[:type], config[:class])
|
135
135
|
resolv.query_timeout = config[:timeout]
|
136
|
-
rescue => e
|
136
|
+
rescue StandardError => e
|
137
137
|
entry = e
|
138
138
|
end
|
139
139
|
entries << entry
|
@@ -155,7 +155,7 @@ class DNS < Sensu::Plugin::Check::CLI
|
|
155
155
|
if answer.match(regex)
|
156
156
|
ok "Resolved #{config[:domain]} #{config[:type]} matched #{regex}"
|
157
157
|
end
|
158
|
-
end
|
158
|
+
end
|
159
159
|
critical "Resolved #{config[:domain]} #{config[:type]} did not match #{regex}"
|
160
160
|
end
|
161
161
|
|
data/bin/metrics-dns.rb
CHANGED
@@ -78,7 +78,7 @@ class DNSGraphite < Sensu::Plugin::Metric::CLI::Graphite
|
|
78
78
|
output "#{config[:scheme]}.#{config[:type]}.#{key_name}.response_time", result.to_f.round(8)
|
79
79
|
rescue Dnsruby::NXDomain
|
80
80
|
critical "Could not resolve #{config[:domain]} #{config[:type]} record"
|
81
|
-
rescue => e
|
81
|
+
rescue StandardError => e
|
82
82
|
unknown e
|
83
83
|
end
|
84
84
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-dns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu Plugins and contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sensu-plugin
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: dnsruby
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,61 +59,61 @@ dependencies:
|
|
45
59
|
- !ruby/object:Gem::Version
|
46
60
|
version: 1.59.2
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
62
|
+
name: codeclimate-test-reporter
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
50
64
|
requirements:
|
51
65
|
- - "~>"
|
52
66
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
54
|
-
type: :
|
67
|
+
version: '0.4'
|
68
|
+
type: :development
|
55
69
|
prerelease: false
|
56
70
|
version_requirements: !ruby/object:Gem::Requirement
|
57
71
|
requirements:
|
58
72
|
- - "~>"
|
59
73
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
74
|
+
version: '0.4'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
76
|
+
name: github-markup
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
79
|
- - "~>"
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version: '1.
|
81
|
+
version: '1.3'
|
68
82
|
type: :development
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
86
|
- - "~>"
|
73
87
|
- !ruby/object:Gem::Version
|
74
|
-
version: '1.
|
88
|
+
version: '1.3'
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
90
|
+
name: whois
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
78
92
|
requirements:
|
79
93
|
- - "~>"
|
80
94
|
- !ruby/object:Gem::Version
|
81
|
-
version: '0
|
82
|
-
type: :
|
95
|
+
version: '4.0'
|
96
|
+
type: :runtime
|
83
97
|
prerelease: false
|
84
98
|
version_requirements: !ruby/object:Gem::Requirement
|
85
99
|
requirements:
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
|
-
version: '0
|
102
|
+
version: '4.0'
|
89
103
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
104
|
+
name: whois-parser
|
91
105
|
requirement: !ruby/object:Gem::Requirement
|
92
106
|
requirements:
|
93
107
|
- - "~>"
|
94
108
|
- !ruby/object:Gem::Version
|
95
|
-
version: '1.
|
96
|
-
type: :
|
109
|
+
version: '1.0'
|
110
|
+
type: :runtime
|
97
111
|
prerelease: false
|
98
112
|
version_requirements: !ruby/object:Gem::Requirement
|
99
113
|
requirements:
|
100
114
|
- - "~>"
|
101
115
|
- !ruby/object:Gem::Version
|
102
|
-
version: '1.
|
116
|
+
version: '1.0'
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: kitchen-docker
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,14 +224,14 @@ dependencies:
|
|
210
224
|
requirements:
|
211
225
|
- - "~>"
|
212
226
|
- !ruby/object:Gem::Version
|
213
|
-
version: 0.
|
227
|
+
version: 0.51.0
|
214
228
|
type: :development
|
215
229
|
prerelease: false
|
216
230
|
version_requirements: !ruby/object:Gem::Requirement
|
217
231
|
requirements:
|
218
232
|
- - "~>"
|
219
233
|
- !ruby/object:Gem::Version
|
220
|
-
version: 0.
|
234
|
+
version: 0.51.0
|
221
235
|
- !ruby/object:Gem::Dependency
|
222
236
|
name: test-kitchen
|
223
237
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,19 +252,20 @@ dependencies:
|
|
238
252
|
requirements:
|
239
253
|
- - "~>"
|
240
254
|
- !ruby/object:Gem::Version
|
241
|
-
version:
|
255
|
+
version: 0.9.11
|
242
256
|
type: :development
|
243
257
|
prerelease: false
|
244
258
|
version_requirements: !ruby/object:Gem::Requirement
|
245
259
|
requirements:
|
246
260
|
- - "~>"
|
247
261
|
- !ruby/object:Gem::Version
|
248
|
-
version:
|
262
|
+
version: 0.9.11
|
249
263
|
description: |-
|
250
264
|
This plugin provides native DNS instrumentation
|
251
265
|
for monitoring, including: record resolution
|
252
266
|
email: "<sensu-users@googlegroups.com>"
|
253
267
|
executables:
|
268
|
+
- check-dns-zone.rb
|
254
269
|
- metrics-dns.rb
|
255
270
|
- check-dns.rb
|
256
271
|
extensions: []
|
@@ -259,6 +274,7 @@ files:
|
|
259
274
|
- CHANGELOG.md
|
260
275
|
- LICENSE
|
261
276
|
- README.md
|
277
|
+
- bin/check-dns-zone.rb
|
262
278
|
- bin/check-dns.rb
|
263
279
|
- bin/metrics-dns.rb
|
264
280
|
- lib/sensu-plugins-dns.rb
|
@@ -281,7 +297,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
281
297
|
requirements:
|
282
298
|
- - ">="
|
283
299
|
- !ruby/object:Gem::Version
|
284
|
-
version: 2.
|
300
|
+
version: 2.2.0
|
285
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
286
302
|
requirements:
|
287
303
|
- - ">="
|
@@ -289,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
289
305
|
version: '0'
|
290
306
|
requirements: []
|
291
307
|
rubyforge_project:
|
292
|
-
rubygems_version: 2.7.
|
308
|
+
rubygems_version: 2.7.6
|
293
309
|
signing_key:
|
294
310
|
specification_version: 4
|
295
311
|
summary: Sensu plugins for dns
|