sensu-plugins-http-boutetnico 1.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.
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # check-https-cert
6
+ #
7
+ # DESCRIPTION:
8
+ # Checks the expiration date of a URL's TLS/SSL Certificate
9
+ # and notifies if it is before the expiry parameter. Throws
10
+ # a critical if the date is at or past the expiry date.
11
+ #
12
+ # OUTPUT:
13
+ # plain text
14
+ #
15
+ # PLATFORMS:
16
+ # Linux
17
+ #
18
+ # DEPENDENCIES:
19
+ # gem: sensu-plugin
20
+ # gem: net-https
21
+ #
22
+ # USAGE:
23
+ # Check that will warn 1 week prior and critical 3 days prior
24
+ # ./check-https-cert.rb -u https://my.site.com -w 7 -c 3
25
+ #
26
+ # Check an insecure certificate that will warn 1 week prior and critical 3 days prior
27
+ # ./check-https-cert.rb -u https://my.site.com -k -w 7 -c 3
28
+ #
29
+ # Check that a certificate has successfully expired
30
+ # ./check-https-cert.rb -u https://my.site.com -k -e
31
+ #
32
+ # NOTES:
33
+ #
34
+ # LICENSE:
35
+ # Copyright 2014 Rhommel Lamas <roml@rhommell.com>
36
+ # Updated 2017 Phil Porada <philporada@gmail.com>
37
+ # - Provide more clear usage documentation and messages
38
+ # - Added check for successfully expired certificate
39
+ # - Added long flags
40
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
41
+ # for details.
42
+ #
43
+
44
+ require 'sensu-plugin/check/cli'
45
+ require 'net/https'
46
+
47
+ #
48
+ # Check HTTP
49
+ #
50
+ class CheckHttpCert < Sensu::Plugin::Check::CLI
51
+ option :url,
52
+ short: '-u URL',
53
+ long: '--url URL',
54
+ proc: proc(&:to_s),
55
+ description: 'The URL to connect to'
56
+
57
+ option :warning,
58
+ short: '-w',
59
+ long: '--warning DAYS',
60
+ proc: proc(&:to_i),
61
+ default: 50,
62
+ description: 'Warn EXPIRE days before cert expires'
63
+
64
+ option :critical,
65
+ short: '-c',
66
+ long: '--critical DAYS',
67
+ proc: proc(&:to_i),
68
+ default: 25,
69
+ description: 'Critical EXPIRE days before cert expires'
70
+
71
+ option :expired,
72
+ short: '-e',
73
+ long: '--expired',
74
+ boolean: true,
75
+ description: 'Expect certificate to be expired',
76
+ default: false
77
+
78
+ option :insecure,
79
+ short: '-k',
80
+ long: '--insecure',
81
+ boolean: true,
82
+ description: 'Enabling insecure connections',
83
+ default: false
84
+
85
+ def run
86
+ uri = URI.parse(config[:url])
87
+ http = Net::HTTP.new(uri.host, uri.port)
88
+ http.use_ssl = true
89
+ http.verify_mode = if config[:insecure]
90
+ OpenSSL::SSL::VERIFY_NONE
91
+ else
92
+ OpenSSL::SSL::VERIFY_PEER
93
+ end
94
+
95
+ http.start do |h|
96
+ @cert = h.peer_cert
97
+ end
98
+ days_until = ((@cert.not_after - Time.now) / (60 * 60 * 24)).to_i
99
+
100
+ if config[:expired]
101
+ if days_until >= 0
102
+ critical "TLS/SSL certificate expires on #{@cert.not_after} - #{days_until} days left."
103
+ else
104
+ ok "TLS/SSL certificate expired #{days_until.abs} days ago."
105
+ end
106
+ end
107
+
108
+ unless config[:expired]
109
+ if days_until <= 0
110
+ critical "TLS/SSL certificate expired #{days_until.abs} days ago."
111
+ elsif days_until < config[:critical].to_i
112
+ critical "TLS/SSL certificate expires on #{@cert.not_after} - #{days_until} days left."
113
+ elsif days_until < config[:warning].to_i
114
+ warning "TLS/SSL certificate expires on #{@cert.not_after} - #{days_until} days left."
115
+ else
116
+ ok "TLS/SSL certificate expires on #{@cert.not_after} - #{days_until} days left."
117
+ end
118
+ end
119
+ rescue StandardError
120
+ critical "Could not connect to #{config[:url]}"
121
+ end
122
+ end
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # check-fleet-units
6
+ #
7
+ # DESCRIPTION:
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ #
18
+ # USAGE:
19
+ #
20
+ # NOTES:
21
+ #
22
+ # LICENSE:
23
+ # Barry Martin <nyxcharon@gmail.com>
24
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
25
+ # for details.
26
+ #
27
+ require 'sensu-plugin/check/cli'
28
+ require 'net/https'
29
+ require 'time'
30
+ require 'aws-sdk'
31
+ require 'json'
32
+ require 'sensu-plugins-http'
33
+
34
+ #
35
+ # Checks the last modified time of a file to verify it has been updated with a
36
+ # specified threshold.
37
+ #
38
+ class CheckLastModified < Sensu::Plugin::Check::CLI
39
+ include Common
40
+ option :aws_access_key_id,
41
+ short: '-a AWS_ACCESS_KEY_ID',
42
+ long: '--aws-access-key-id AWS_ACCESS_KEY_ID',
43
+ description: 'AWS Access Key. Either set ENV["AWS_ACCESS_KEY_ID"] or provide it as an option',
44
+ default: ENV['AWS_ACCESS_KEY_ID']
45
+
46
+ option :aws_secret_access_key,
47
+ short: '-k AWS_SECRET_KEY',
48
+ long: '--aws-secret-access-key AWS_SECRET_ACCESS_KEY',
49
+ description: 'AWS Secret Access Key. Either set ENV["AWS_SECRET_ACCESS_KEY"] or provide it as an option',
50
+ default: ENV['AWS_SECRET_ACCESS_KEY']
51
+
52
+ option :aws_region,
53
+ short: '-r AWS_REGION',
54
+ long: '--aws-region REGION',
55
+ description: 'AWS Region (defaults to us-east-1).',
56
+ default: 'us-east-1'
57
+
58
+ option :s3_config_bucket,
59
+ short: '-s S3_CONFIG_BUCKET',
60
+ long: '--s3-config-bucket S3_CONFIG_BUCKET',
61
+ description: 'S3 config bucket'
62
+
63
+ option :s3_config_key,
64
+ short: '-k S3_CONFIG_KEY',
65
+ long: '--s3-config-key S3_CONFIG_KEY',
66
+ description: 'S3 config key'
67
+
68
+ option :url,
69
+ short: '-u URL',
70
+ long: '--url URL',
71
+ description: 'The URL of the file to be checked'
72
+
73
+ option :user,
74
+ short: '-U USER',
75
+ long: '--username USER',
76
+ description: 'A username to connect as'
77
+
78
+ option :password,
79
+ short: '-a PASS',
80
+ long: '--password PASS',
81
+ description: 'A password to use for the username'
82
+
83
+ option :threshold,
84
+ short: '-t TIME',
85
+ long: '--time TIME',
86
+ description: 'The time in seconds the file should be updated by'
87
+
88
+ option :follow_redirects,
89
+ short: '-R FOLLOW_REDIRECTS',
90
+ long: '--redirect FOLLOW_REDIRECTS',
91
+ proc: proc(&:to_i),
92
+ default: 0,
93
+ description: 'Follow first <N> redirects'
94
+
95
+ option :follow_redirects_with_get,
96
+ short: '-g GET_REDIRECTS',
97
+ long: '--get-redirects GET_REDIRECTS',
98
+ proc: proc(&:to_i),
99
+ default: 0,
100
+ description: 'Follow first <N> redirects with GET requests'
101
+
102
+ option :auth_first_only,
103
+ short: '-A',
104
+ long: '--auth-first-only',
105
+ default: true,
106
+ description: 'Use basic auth on first request only'
107
+
108
+ def follow_uri(uri, total_redirects, get_redirects, auth_count)
109
+ location = URI(uri)
110
+ http = Net::HTTP.new(location.host, location.port)
111
+
112
+ if location.port == 443
113
+ http.use_ssl = true
114
+ end
115
+
116
+ request = if get_redirects > 0
117
+ Net::HTTP::Get.new(location.request_uri)
118
+ else
119
+ Net::HTTP::Head.new(location.request_uri)
120
+ end
121
+
122
+ if auth_count > 0 && config[:user] && config[:password] && total_redirects == config[:follow_redirects]
123
+ http.use_ssl = true
124
+ request.basic_auth(config[:user], config[:password])
125
+ auth_count -= 1
126
+ end
127
+
128
+ response = http.request(request)
129
+
130
+ if total_redirects > 0
131
+ case response
132
+ when Net::HTTPSuccess then response
133
+ when Net::HTTPRedirection then follow_uri(response['location'], total_redirects - 1, get_redirects - 1, auth_count)
134
+ else
135
+ critical 'Http Error'
136
+ end
137
+ else
138
+ case response
139
+ when Net::HTTPSuccess then response
140
+ else
141
+ critical 'Http Error'
142
+ end
143
+ end
144
+ end
145
+
146
+ def run
147
+ merge_s3_config
148
+
149
+ url = config[:url]
150
+ threshold = config[:threshold]
151
+
152
+ # Validate arguments
153
+ unless url
154
+ unknown 'No URL specified'
155
+ end
156
+
157
+ unless threshold
158
+ unknown 'No threshold specified'
159
+ end
160
+
161
+ response = follow_uri(url, config[:follow_redirects], config[:follow_redirects_with_get], config[:auth_first_only] ? 1 : config[:follow_redirects])
162
+
163
+ # Build a request from user options and then request it
164
+ if response.header['last-modified'].nil?
165
+ critical 'Http Error'
166
+ end
167
+
168
+ # Get timestamp of file and local timestamp and compare (Both in UTC)
169
+ file_stamp = Time.parse(response.header['last-modified']).getgm
170
+ local_stamp = Time.now.getgm
171
+
172
+ if (local_stamp - file_stamp).to_i <= threshold.to_i
173
+ ok 'Last modified time OK'
174
+ else
175
+ critical 'Last modified time greater than threshold'
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # metrics-curl
6
+ #
7
+ # DESCRIPTION:
8
+ # Simple wrapper around curl for getting timing stats from the various phases
9
+ # of connecting to an HTTP/HTTPS server.
10
+ #
11
+ # OUTPUT:
12
+ # metric data
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: sensu-plugin
19
+ #
20
+ # USAGE:
21
+ # #YELLOW
22
+ #
23
+ # NOTES:
24
+ # Based on: http://dev.nuclearrooster.com/2009/12/07/quick-download-benchmarks-with-curl/
25
+ # by Nick Stielau.
26
+ #
27
+ # LICENSE:
28
+ # Copyright 2012 Joe Miller
29
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
30
+ # for details.
31
+ #
32
+ require 'socket'
33
+ require 'English'
34
+ require 'sensu-plugin/metric/cli'
35
+
36
+ #
37
+ # Curl Metrics
38
+ #
39
+ class CurlMetrics < Sensu::Plugin::Metric::CLI::Graphite
40
+ option :url,
41
+ short: '-u URL',
42
+ long: '--url URL',
43
+ description: 'valid cUrl url to connect',
44
+ default: 'http://127.0.0.1:80/'
45
+
46
+ option :curl_args,
47
+ short: '-a "CURL ARGS"',
48
+ long: '--curl_args "CURL ARGS"',
49
+ description: 'Additional arguments to pass to curl',
50
+ default: ''
51
+
52
+ option :scheme,
53
+ description: 'Metric naming scheme, text to prepend to metric',
54
+ short: '-s SCHEME',
55
+ long: '--scheme SCHEME',
56
+ required: true,
57
+ default: "#{Socket.gethostname}.curl_timings"
58
+
59
+ def run
60
+ `which curl > /dev/null 2>&1`
61
+ unless $CHILD_STATUS == 0
62
+ critical 'CRITICAL: curl executable not found in PATH on this system.'\
63
+ ' If curl cannot be installed, consider using metrics_libcurl.rb instead.'
64
+ end
65
+
66
+ cmd = "LC_NUMERIC=C curl --silent --output /dev/null #{config[:curl_args]} "
67
+ cmd += '-w "%{time_total},%{time_namelookup},%{time_connect},%{time_pretransfer},%{time_redirect},%{time_starttransfer},%{http_code}" '
68
+ cmd += config[:url]
69
+ output = `#{cmd}`
70
+
71
+ (time_total, time_namelookup, time_connect, time_pretransfer, time_redirect, time_starttransfer, http_code) = output.split(',')
72
+ output "#{config[:scheme]}.time_total", time_total
73
+ output "#{config[:scheme]}.time_namelookup", time_namelookup
74
+ output "#{config[:scheme]}.time_connect", time_connect
75
+ output "#{config[:scheme]}.time_pretransfer", time_pretransfer
76
+ output "#{config[:scheme]}.time_redirect", time_redirect
77
+ output "#{config[:scheme]}.time_starttransfer", time_starttransfer
78
+ output "#{config[:scheme]}.http_code", http_code
79
+
80
+ if $CHILD_STATUS.to_i == 0
81
+ ok
82
+ else
83
+ warning
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,133 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # metrics-http-json-deep
6
+ #
7
+ # DESCRIPTION:
8
+ # Get metrics in json format via http/https
9
+ #
10
+ # OUTPUT:
11
+ # metric data
12
+ #
13
+ # PLATFORMS:
14
+ # Linux
15
+ #
16
+ # DEPENDENCIES:
17
+ # gem: sensu-plugin
18
+ # gem: uri
19
+ # gem: socket
20
+ # gem: oj
21
+ #
22
+ # USAGE:
23
+ #
24
+ # NOTES:
25
+ #
26
+ # LICENSE:
27
+ # Copyright 2016 Hayato Matsuura
28
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
29
+ # for details.
30
+ #
31
+
32
+ require 'sensu-plugin/metric/cli'
33
+ require 'net/https'
34
+ require 'uri'
35
+ require 'socket'
36
+ require 'oj'
37
+
38
+ #
39
+ # JSON Metrics
40
+ #
41
+ class JsonDeepMetrics < Sensu::Plugin::Metric::CLI::Graphite
42
+ option :url,
43
+ short: '-u URL',
44
+ long: '--url URL',
45
+ description: 'Full URL to JSON, example: https://example.com/foo.json This ignores --hostname and --port options'
46
+
47
+ option :hostname,
48
+ short: '-h HOSTNAME',
49
+ long: '--host HOSTNAME',
50
+ description: 'App server hostname',
51
+ default: '127.0.0.1'
52
+
53
+ option :port,
54
+ short: '-P PORT',
55
+ long: '--port PORT',
56
+ description: 'App server port',
57
+ default: '80'
58
+
59
+ option :path,
60
+ short: '-p PATH',
61
+ long: '--path ROOTPATH',
62
+ description: 'Path for json',
63
+ default: 'status'
64
+
65
+ option :root,
66
+ short: '-r ROOTPATH',
67
+ long: '--rootpath ROOTPATH',
68
+ description: 'Root attribute for json',
69
+ default: 'value'
70
+
71
+ option :scheme,
72
+ description: 'Metric naming scheme, text to prepend to metric',
73
+ short: '-s SCHEME',
74
+ long: '--scheme SCHEME',
75
+ default: "#{Socket.gethostname}.json"
76
+
77
+ option :numonly,
78
+ description: 'Output numbers only',
79
+ short: '-n',
80
+ long: '--number'
81
+
82
+ option :decimal_places,
83
+ description: 'Number of decimal places to allow, to be used with --number',
84
+ short: '-f DECIMAL_PLACES',
85
+ long: '--floats DECIMAL_PLACES',
86
+ proc: proc(&:to_i),
87
+ default: 4
88
+
89
+ def deep_value(hash, scheme = '')
90
+ hash.each do |key, value|
91
+ ekey = key.gsub(/\s/, '_')
92
+ if value.is_a?(Hash)
93
+ deep_value(value, "#{scheme}.#{ekey}")
94
+ elsif config[:numonly]
95
+ output "#{scheme}.#{ekey}", value.round(config[:decimal_places]) if value.is_a?(Numeric)
96
+ else
97
+ output "#{scheme}.#{ekey}", value
98
+ end
99
+ end
100
+ end
101
+
102
+ def run
103
+ found = false
104
+ attempts = 0
105
+ until found || attempts >= 10
106
+ attempts += 1
107
+ if config[:url]
108
+ uri = URI.parse(config[:url])
109
+ http = Net::HTTP.new(uri.host, uri.port)
110
+ if uri.scheme == 'https'
111
+ http.use_ssl = true
112
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
113
+ end
114
+ request = Net::HTTP::Get.new(uri.request_uri)
115
+ response = http.request(request)
116
+ if response.code == '200'
117
+ found = true
118
+ elsif !response.header['location'].nil?
119
+ config[:url] = response.header['location']
120
+ end
121
+ else
122
+ response = Net::HTTP.start(config[:hostname], config[:port]) do |connection|
123
+ request = Net::HTTP::Get.new("/#{config[:path]}")
124
+ connection.request(request)
125
+ end
126
+ end
127
+ end
128
+
129
+ metrics = Oj.load(response.body, mode: :compat)
130
+ deep_value(metrics[config[:root]], config[:scheme])
131
+ ok
132
+ end
133
+ end