sensu-plugins-dns 1.4.1 → 2.0.0
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 +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
|