sensu-plugins-consul-magec 2.2.1

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,118 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # check-consul-servers
6
+ #
7
+ # DESCRIPTION:
8
+ # This plugin checks if consul is up and reachable. It then checks
9
+ # the number of peers matches the excepted value
10
+ #
11
+ # OUTPUT:
12
+ # plain text
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: sensu-plugin
19
+ # gem: diplomat
20
+ #
21
+ # USAGE:
22
+ # #YELLOW
23
+ #
24
+ # NOTES:
25
+ #
26
+ # LICENSE:
27
+ # Copyright 2015 Sonian, Inc. and contributors. <support@sensuapp.org>
28
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
29
+ # for details.
30
+ #
31
+
32
+ require 'sensu-plugin/check/cli'
33
+ require 'rest-client'
34
+ require 'json'
35
+
36
+ #
37
+ # Consul Status
38
+ #
39
+ class ConsulStatus < Sensu::Plugin::Check::CLI
40
+ option :server,
41
+ description: 'consul server',
42
+ short: '-s SERVER',
43
+ long: '--server SERVER',
44
+ default: '127.0.0.1'
45
+
46
+ option :port,
47
+ description: 'consul http port',
48
+ short: '-p PORT',
49
+ long: '--port PORT',
50
+ default: '8500'
51
+
52
+ option :min,
53
+ description: 'minimum number of peers',
54
+ short: '-g GREATER THAN',
55
+ long: '--greater GREATER THAN',
56
+ proc: proc(&:to_i),
57
+ default: 3
58
+
59
+ option :expected,
60
+ description: 'expected number of peers',
61
+ short: '-e EXPECT',
62
+ long: '--expect EXPECT',
63
+ proc: proc(&:to_i),
64
+ default: 5
65
+
66
+ option :scheme,
67
+ description: 'consul listener scheme',
68
+ short: '-S SCHEME',
69
+ long: '--scheme SCHEME',
70
+ default: 'http'
71
+
72
+ option :insecure,
73
+ description: 'if set, disables SSL verification',
74
+ short: '-k',
75
+ long: '--insecure',
76
+ boolean: true,
77
+ default: false
78
+
79
+ option :capath,
80
+ description: 'absolute path to an alternate CA file',
81
+ short: '-c CAPATH',
82
+ long: '--capath CAPATH'
83
+
84
+ option :timeout,
85
+ description: 'connection will time out after this many seconds',
86
+ short: '-t TIMEOUT_IN_SECONDS',
87
+ long: '--timeout TIMEOUT_IN_SECONDS',
88
+ proc: proc(&:to_i),
89
+ default: 5
90
+
91
+ option :token,
92
+ description: 'ACL token',
93
+ long: '--token ACL_TOKEN'
94
+
95
+ def run
96
+ url = "#{config[:scheme]}://#{config[:server]}:#{config[:port]}/v1/status/peers"
97
+ options = { timeout: config[:timeout],
98
+ verify_ssl: (OpenSSL::SSL::VERIFY_NONE if defined? config[:insecure]),
99
+ ssl_ca_file: (config[:capath] if defined? config[:capath]),
100
+ headers: { 'X-Consul-Token' => config[:token] } }
101
+
102
+ json = RestClient::Resource.new(url, options).get
103
+ peers = JSON.parse(json).length.to_i
104
+ if peers < config[:min]
105
+ critical "[#{peers}] peers is below critical threshold of [#{config[:min]}]"
106
+ elsif peers != config[:expected]
107
+ warning "[#{peers}] peers is outside of expected count of [#{config[:expected]}]"
108
+ else
109
+ ok 'Peers within threshold'
110
+ end
111
+ rescue Errno::ECONNREFUSED
112
+ critical 'Consul is not responding'
113
+ rescue RestClient::RequestTimeout
114
+ critical 'Consul Connection timed out'
115
+ rescue RestClient::Exception => e
116
+ unknown "Consul returned: #{e}"
117
+ end
118
+ end
@@ -0,0 +1,161 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # check-consul-service-health
6
+ #
7
+ # DESCRIPTION:
8
+ # This plugin assists in checking the check status of a Consul Service
9
+ # In addition, it provides additional Yieldbot logic for Output containing
10
+ # JSON.
11
+ #
12
+ # OUTPUT:
13
+ # plain text
14
+ #
15
+ # PLATFORMS:
16
+ # Linux
17
+ #
18
+ # DEPENDENCIES:
19
+ # gem: sensu-plugin
20
+ # gem: diplomat
21
+ #
22
+ # USAGE:
23
+ # ./check-consul-service-health -s influxdb
24
+ # ./check-consul-service-health -a
25
+ #
26
+ # NOTES:
27
+ #
28
+ # LICENSE:
29
+ # Copyright 2015 Yieldbot, Inc. <devops@yieldbot.com>
30
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
31
+ # for details.
32
+ #
33
+
34
+ require 'sensu-plugin/check/cli'
35
+ require 'diplomat'
36
+ require 'json'
37
+
38
+ #
39
+ # Service Status
40
+ #
41
+ class CheckConsulServiceHealth < Sensu::Plugin::Check::CLI
42
+ option :consul,
43
+ description: 'consul server',
44
+ long: '--consul SERVER',
45
+ default: 'http://localhost:8500'
46
+
47
+ option :nodename,
48
+ description: 'check all consul services running on the specified node',
49
+ short: '-n NODENAME',
50
+ long: '--node NODENAME'
51
+
52
+ option :service,
53
+ description: 'a service managed by consul',
54
+ short: '-s SERVICE',
55
+ long: '--service SERVICE',
56
+ default: 'consul'
57
+
58
+ option :tags,
59
+ description: 'filter services by a comma-separated list of tags (requires --service)',
60
+ short: '-t TAGS',
61
+ long: '--tags TAGS'
62
+
63
+ option :all,
64
+ description: 'get all services (not compatible with --tags)',
65
+ short: '-a',
66
+ long: '--all'
67
+
68
+ option :fail_if_not_found,
69
+ description: 'fail if no service is found',
70
+ short: '-f',
71
+ long: '--fail-if-not-found'
72
+
73
+ option :token,
74
+ description: 'ACL token',
75
+ long: '--token ACL_TOKEN'
76
+
77
+ # Get the service checks for the given service
78
+ def acquire_service_data
79
+ if config[:tags] && config[:service]
80
+ tags = config[:tags].split(',').to_set
81
+ services = []
82
+ Diplomat::Health.service(config[:service]).each do |s|
83
+ if s['Service']['Tags'].to_set.superset? tags
84
+ services.push(*s['Checks'])
85
+ end
86
+ end
87
+ services
88
+ elsif config[:nodename]
89
+ data = []
90
+ begin
91
+ services = Diplomat::Node.get(config[:nodename]).Services
92
+ rescue StandardError
93
+ services = {}
94
+ end
95
+ services.each_value do |service|
96
+ Diplomat::Health.checks(service['Service']).each do |check|
97
+ data.push(check) if check.Node == config[:nodename]
98
+ end
99
+ end
100
+ data
101
+ elsif config[:all]
102
+ Diplomat::Health.state('any')
103
+ else
104
+ Diplomat::Health.checks(config[:service])
105
+ end
106
+ end
107
+
108
+ # Do work
109
+ def run
110
+ if config[:tags] && config[:all]
111
+ critical 'Cannot specify --tags and --all simultaneously (Consul health/service/ versus health/state/).'
112
+ end
113
+
114
+ Diplomat.configure do |dc|
115
+ dc.url = config[:consul]
116
+ dc.acl_token = config[:token]
117
+ headers = {}
118
+ headers['X-Consul-Token'] = config[:token] if config[:token]
119
+ dc.options = {
120
+ headers: headers
121
+ }
122
+ end
123
+
124
+ found = false
125
+ warnings = false
126
+ criticals = false
127
+ checks = []
128
+
129
+ # Process all of the nonpassing service checks
130
+ acquire_service_data.each do |d|
131
+ found = true
132
+ checkId = d['CheckID'] # rubocop:disable Style/VariableName
133
+ checkStatus = d['Status'] # rubocop:disable Style/VariableName
134
+
135
+ # If we are passing do nothing
136
+ next if checkStatus == 'passing'
137
+
138
+ checks.push(
139
+ checkId => d['Output'],
140
+ 'Status' => checkStatus
141
+ )
142
+
143
+ warnings = true if %w[warning].include? checkStatus
144
+ criticals = true if %w[critical unknown].include? checkStatus
145
+ end
146
+
147
+ if config[:fail_if_not_found] && !found
148
+ msg = 'Could not find checks for any services'
149
+ if config[:service]
150
+ msg = "Could not find checks for service #{config[:service]}"
151
+ if config[:tags]
152
+ msg += " with tags #{config[:tags]}"
153
+ end
154
+ end
155
+ critical msg
156
+ end
157
+ critical checks if criticals
158
+ warning checks if warnings
159
+ ok
160
+ end
161
+ end
@@ -0,0 +1,73 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # check-consul-stale-peers
6
+ #
7
+ # DESCRIPTION:
8
+ # This plugin checks the raft configuration for stale ("unknown") peers.
9
+ #
10
+ # OUTPUT:
11
+ # plain text
12
+ #
13
+ # PLATFORMS:
14
+ # Linux
15
+ #
16
+ # DEPENDENCIES:
17
+ # gem: sensu-plugin
18
+ # gem: rest-client
19
+ #
20
+ # USAGE:
21
+ # Connect to localhost, go critical when there are any stale peers:
22
+ # ./check-consul-stale-peers
23
+ #
24
+ # Connect to a remote Consul server over HTTPS:
25
+ # ./check-consul-stale-peers -s 192.168.42.42 -p 4443 -P https
26
+ #
27
+ # Go critical when the cluster has two or more stale peers:
28
+ # ./check-consul-stale-peers -W 1 -C 2
29
+ #
30
+ # NOTES:
31
+ #
32
+ # LICENSE:
33
+ # Copyright 2018, Jonathan Hartman <j@hartman.io>
34
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
35
+ # for details.
36
+ #
37
+
38
+ require 'sensu-plugins-consul/check/base'
39
+
40
+ #
41
+ # Consul stale peers
42
+ #
43
+ class ConsulStalePeers < SensuPluginsConsul::Check::Base
44
+ option :warning,
45
+ description: 'Warn when there are this many stale peers',
46
+ short: '-W NUMBER_OF_PEERS',
47
+ long: '--warning NUMBER_OF_PEERS',
48
+ proc: proc(&:to_i),
49
+ default: 1
50
+
51
+ option :critical,
52
+ description: 'Go critical when there are this many stale peers',
53
+ short: '-C NUMBER_OF_PEERS',
54
+ long: '--critical NUMBER_OF_PEERS',
55
+ proc: proc(&:to_i),
56
+ default: 1
57
+
58
+ def run
59
+ raft = consul_get('operator/raft/configuration')
60
+
61
+ res = raft['Servers'].select { |s| s['Node'] == '(unknown)' }.length
62
+
63
+ msg = "Cluster contains #{res} stale peer#{'s' unless res == 1}"
64
+
65
+ if res >= config[:critical]
66
+ critical msg
67
+ elsif res >= config[:warning]
68
+ warning msg
69
+ else
70
+ ok msg
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,160 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # check-service-consul
6
+ #
7
+ # DESCRIPTION:
8
+ # This plugin checks if consul says a service is 'passing' or
9
+ # 'critical'
10
+ #
11
+ # OUTPUT:
12
+ # plain text
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: sensu-plugin
19
+ # gem: diplomat
20
+ #
21
+ # USAGE:
22
+ # ./check-service-consul -s influxdb
23
+ # ./check-service-consul -a
24
+ #
25
+ # NOTES:
26
+ #
27
+ # LICENSE:
28
+ # Copyright 2015 Yieldbot, Inc. <Sensu-Plugins>
29
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
30
+ # for details.
31
+ #
32
+
33
+ require 'sensu-plugin/check/cli'
34
+ require 'diplomat'
35
+
36
+ #
37
+ # Service Status
38
+ #
39
+ class ServiceStatus < Sensu::Plugin::Check::CLI
40
+ option :consul,
41
+ description: 'consul server',
42
+ long: '--consul SERVER',
43
+ default: 'http://localhost:8500'
44
+
45
+ option :service,
46
+ description: 'a service managed by consul',
47
+ short: '-s SERVICE',
48
+ long: '--service SERVICE',
49
+ default: 'consul'
50
+
51
+ option :tags,
52
+ description: 'filter services by a comma-separated list of tags (requires --service)',
53
+ short: '-t TAGS',
54
+ long: '--tags TAGS'
55
+
56
+ option :all,
57
+ description: 'get all services in a non-passing status (not compatible with --tags)',
58
+ short: '-a',
59
+ long: '--all'
60
+
61
+ option :fail_if_not_found,
62
+ description: 'fail if no service is found',
63
+ short: '-f',
64
+ long: '--fail-if-not-found'
65
+
66
+ option :token,
67
+ description: 'ACL token',
68
+ long: '--token ACL_TOKEN'
69
+
70
+ # Get the check data for the service from consul
71
+ #
72
+ def acquire_service_data
73
+ if config[:tags] && config[:service]
74
+ tags = config[:tags].split(',').to_set
75
+ services = []
76
+ Diplomat::Health.service(config[:service]).each do |s|
77
+ if s['Service']['Tags'].to_set.superset? tags
78
+ services.push(*s['Checks'])
79
+ end
80
+ end
81
+ return services
82
+ elsif config[:all]
83
+ Diplomat::Health.state('any')
84
+ else
85
+ Diplomat::Health.checks(config[:service])
86
+ end
87
+ rescue Faraday::ConnectionFailed => e
88
+ warning "Connection error occurred: #{e}"
89
+ rescue Diplomat::UnknownStatus => e
90
+ if e.message.include?('403')
91
+ critical %(ACL token is not authorized to access service "#{config[:service]}")
92
+ else
93
+ critical "Unhandled exception(#{e.class}) -- #{e.message}"
94
+ end
95
+ rescue Faraday::ClientError => e
96
+ if e.response[:status] == 403
97
+ critical %(ACL token is not authorized to access service "#{config[:service]}": #{e.response[:body]})
98
+ else
99
+ unknown "Exception occurred when checking consul service: #{e}"
100
+ end
101
+ rescue StandardError => e
102
+ unknown "Exception occurred when checking consul service: #{e}"
103
+ end
104
+
105
+ # Main function
106
+ #
107
+ def run
108
+ if config[:tags] && config[:all]
109
+ critical 'Cannot specify --tags and --all simultaneously (Consul health/service/ versus health/state/).'
110
+ end
111
+
112
+ Diplomat.configure do |dc|
113
+ dc.url = config[:consul]
114
+ dc.acl_token = config[:token]
115
+ dc.options = {
116
+ headers: {
117
+ 'X-Consul-Token' => config[:token]
118
+ }
119
+ }
120
+ end
121
+
122
+ data = acquire_service_data
123
+ passing = []
124
+ failing = []
125
+ data.each do |d|
126
+ if d['Status'] == 'passing'
127
+ passing << {
128
+ 'node' => d['Node'],
129
+ 'service' => d['ServiceName'],
130
+ 'service_id' => d['ServiceID'],
131
+ 'notes' => d['Notes']
132
+ }
133
+ elsif d['Status'] == 'critical'
134
+ failing << {
135
+ 'node' => d['Node'],
136
+ 'service' => d['ServiceName'],
137
+ 'service_id' => d['ServiceID'],
138
+ 'notes' => d['Notes']
139
+ }
140
+ end
141
+ end
142
+
143
+ if failing.empty? && passing.empty?
144
+ msg = 'Could not find checks for any services'
145
+ if config[:service]
146
+ msg = "Could not find checks for service #{config[:service]}"
147
+ if config[:tags]
148
+ msg += " with tags #{config[:tags]}"
149
+ end
150
+ end
151
+ if config[:fail_if_not_found]
152
+ critical msg
153
+ else
154
+ unknown msg
155
+ end
156
+ end
157
+ critical failing unless failing.empty?
158
+ ok passing unless passing.empty?
159
+ end
160
+ end