sensu-plugins-aws 0.0.1.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data/CHANGELOG.md +15 -0
- data/LICENSE +22 -0
- data/README.md +125 -0
- data/bin/autoscaling-instance-count-metrics.rb +87 -0
- data/bin/check-dynamodb-capacity.rb +183 -0
- data/bin/check-dynamodb-throttle.rb +177 -0
- data/bin/check-ec2-network.rb +131 -0
- data/bin/check-elb-certs.rb +149 -0
- data/bin/check-elb-health-fog.rb +121 -0
- data/bin/check-elb-health-sdk.rb +124 -0
- data/bin/check-elb-health.rb +122 -0
- data/bin/check-elb-latency.rb +175 -0
- data/bin/check-elb-nodes.rb +145 -0
- data/bin/check-elb-sum-requests.rb +168 -0
- data/bin/check-instance-events.rb +130 -0
- data/bin/check-rds-events.rb +84 -0
- data/bin/check-rds.rb +251 -0
- data/bin/check-redshift-events.rb +120 -0
- data/bin/check-ses-limit.rb +91 -0
- data/bin/check-sqs-messages.rb +107 -0
- data/bin/check_vpc_vpn.py +42 -0
- data/bin/ec2-count-metrics.rb +144 -0
- data/bin/ec2-node.rb +157 -0
- data/bin/elasticache-metrics.rb +200 -0
- data/bin/elb-full-metrics.rb +144 -0
- data/bin/elb-latency-metrics.rb +150 -0
- data/bin/elb-metrics.rb +150 -0
- data/bin/sqs-metrics.rb +84 -0
- data/lib/sensu-plugins-AWS.rb +7 -0
- data.tar.gz.sig +0 -0
- metadata +330 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,131 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-ec2-network
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# Check EC2 Network Metrics by CloudWatch API.
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain-text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: aws-sdk
|
16
|
+
# gem: sensu-plugin
|
17
|
+
#
|
18
|
+
# USAGE:
|
19
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} --warning-over 1000000 --critical-over 1500000
|
20
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkIn --warning-over 1000000 --critical-over 1500000
|
21
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkOut --warning-over 1000000 --critical-over 1500000
|
22
|
+
#
|
23
|
+
# NOTES:
|
24
|
+
#
|
25
|
+
# LICENSE:
|
26
|
+
# Yohei Kawahara <inokara@gmail.com>
|
27
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
28
|
+
# for details.
|
29
|
+
#
|
30
|
+
|
31
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
32
|
+
require 'sensu-plugin/check/cli'
|
33
|
+
require 'aws-sdk'
|
34
|
+
|
35
|
+
class CheckEc2Network < Sensu::Plugin::Check::CLI
|
36
|
+
option :access_key_id,
|
37
|
+
short: '-k N',
|
38
|
+
long: '--access-key-id ID',
|
39
|
+
description: 'AWS access key ID'
|
40
|
+
|
41
|
+
option :secret_access_key,
|
42
|
+
short: '-s N',
|
43
|
+
long: '--secret-access-key KEY',
|
44
|
+
description: 'AWS secret access key'
|
45
|
+
|
46
|
+
option :region,
|
47
|
+
short: '-r R',
|
48
|
+
long: '--region REGION',
|
49
|
+
description: 'AWS region'
|
50
|
+
|
51
|
+
option :instance_id,
|
52
|
+
short: '-i instance-id',
|
53
|
+
long: '--instance-id instance-ids',
|
54
|
+
description: 'EC2 Instance ID to check.'
|
55
|
+
|
56
|
+
option :end_time,
|
57
|
+
short: '-t T',
|
58
|
+
long: '--end-time TIME',
|
59
|
+
default: Time.now,
|
60
|
+
description: 'CloudWatch metric statistics end time'
|
61
|
+
|
62
|
+
option :period,
|
63
|
+
short: '-p N',
|
64
|
+
long: '--period SECONDS',
|
65
|
+
default: 60,
|
66
|
+
description: 'CloudWatch metric statistics period'
|
67
|
+
|
68
|
+
option :direction,
|
69
|
+
short: '-d NetworkIn or NetworkOut',
|
70
|
+
long: '--direction NetworkIn or NetworkOut',
|
71
|
+
default: 'NetworkIn',
|
72
|
+
description: 'Select NetworkIn or NetworkOut'
|
73
|
+
|
74
|
+
%w(warning critical).each do |severity|
|
75
|
+
option :"#{severity}_over",
|
76
|
+
long: "--#{severity}-over COUNT",
|
77
|
+
description: "Trigger a #{severity} if network traffice is over specified Bytes"
|
78
|
+
end
|
79
|
+
|
80
|
+
def aws_config
|
81
|
+
hash = {}
|
82
|
+
hash.update access_key_id: config[:access_key_id], secret_access_key: config[:secret_access_key] if config[:access_key_id] && config[:secret_access_key]
|
83
|
+
hash.update region: config[:region] if config[:region]
|
84
|
+
hash
|
85
|
+
end
|
86
|
+
|
87
|
+
def ec2
|
88
|
+
@ec2 ||= AWS::EC2.new aws_config
|
89
|
+
end
|
90
|
+
|
91
|
+
def cloud_watch
|
92
|
+
@cloud_watch ||= AWS::CloudWatch.new aws_config
|
93
|
+
end
|
94
|
+
|
95
|
+
def network_metric(instance)
|
96
|
+
cloud_watch.metrics.with_namespace('AWS/EC2').with_metric_name("#{config[:direction]}").with_dimensions(name: 'InstanceId', value: instance).first
|
97
|
+
end
|
98
|
+
|
99
|
+
def statistics_options
|
100
|
+
{
|
101
|
+
start_time: config[:end_time] - 300,
|
102
|
+
end_time: config[:end_time],
|
103
|
+
statistics: ['Average'],
|
104
|
+
period: config[:period]
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def latest_value(metric)
|
109
|
+
value = metric.statistics(statistics_options.merge unit: 'Bytes')
|
110
|
+
# #YELLOW
|
111
|
+
unless value.datapoints[0].nil? # rubocop:disable IfUnlessModifier, GuardClause
|
112
|
+
value.datapoints[0][:average].to_f
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def check_metric(instance)
|
117
|
+
metric = network_metric instance
|
118
|
+
latest_value metric
|
119
|
+
end
|
120
|
+
|
121
|
+
def run
|
122
|
+
metric_value = check_metric config[:instance_id]
|
123
|
+
if !metric_value.nil? && metric_value > config[:critical_over].to_f
|
124
|
+
critical "#{config[:direction]} at #{metric_value} Bytes"
|
125
|
+
elsif !metric_value.nil? && metric_value > config[:warning_over].to_f
|
126
|
+
warning "#{config[:direction]} at #{metric_value} Bytes"
|
127
|
+
else
|
128
|
+
ok "#{config[:direction]} at #{metric_value} Bytes"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-elb-certs
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin looks up all ELBs in the organization and checks https
|
7
|
+
# endpoints for expiring certificates
|
8
|
+
#
|
9
|
+
# OUTPUT:
|
10
|
+
# plain-text
|
11
|
+
#
|
12
|
+
# PLATFORMS:
|
13
|
+
# Linux
|
14
|
+
#
|
15
|
+
# DEPENDENCIES:
|
16
|
+
# gem: aws-sdk
|
17
|
+
# gem: sensu-plugin
|
18
|
+
# gem: openssl
|
19
|
+
# gem: net/http
|
20
|
+
#
|
21
|
+
# USAGE:
|
22
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} --warning-over 1000000 --critical-over 1500000
|
23
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkIn --warning-over 1000000 --critical-over 1500000
|
24
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkOut --warning-over 1000000 --critical-over 1500000
|
25
|
+
#
|
26
|
+
# NOTES:
|
27
|
+
#
|
28
|
+
# LICENSE:
|
29
|
+
# Copyright (c) 2013, Peter Burkholder, pburkholder@pobox.com
|
30
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
31
|
+
# for details.
|
32
|
+
#
|
33
|
+
|
34
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
35
|
+
require 'sensu-plugin/check/cli'
|
36
|
+
require 'aws-sdk'
|
37
|
+
require 'net/http'
|
38
|
+
require 'openssl'
|
39
|
+
|
40
|
+
class CheckELBCerts < Sensu::Plugin::Check::CLI
|
41
|
+
option :aws_access_key,
|
42
|
+
short: '-a AWS_ACCESS_KEY',
|
43
|
+
long: '--aws-access-key AWS_ACCESS_KEY',
|
44
|
+
description: "AWS Access Key. Either set ENV['AWS_ACCESS_KEY_ID'] or provide it as an option",
|
45
|
+
default: ENV['AWS_ACCESS_KEY_ID']
|
46
|
+
|
47
|
+
option :aws_secret_access_key,
|
48
|
+
short: '-s AWS_SECRET_ACCESS_KEY',
|
49
|
+
long: '--aws-secret-access-key AWS_SECRET_ACCESS_KEY',
|
50
|
+
description: "AWS Secret Access Key. Either set ENV['AWS_SECRET_ACCESS_KEY'] or provide it as an option",
|
51
|
+
default: ENV['AWS_SECRET_ACCESS_KEY']
|
52
|
+
|
53
|
+
option :aws_region,
|
54
|
+
short: '-r AWS_REGION',
|
55
|
+
long: '--aws-region REGION',
|
56
|
+
description: 'AWS Region (such as eu-west-1).',
|
57
|
+
default: 'us-east-1'
|
58
|
+
|
59
|
+
option :warn_under,
|
60
|
+
short: '-w WARN_NUM',
|
61
|
+
long: '--warn WARN_NUM',
|
62
|
+
description: 'Warn on minimum number of days to SSL/TLS certificate expiration',
|
63
|
+
default: 30,
|
64
|
+
proc: proc(&:to_i)
|
65
|
+
|
66
|
+
option :crit_under,
|
67
|
+
short: '-c CRIT_NUM',
|
68
|
+
long: '--crit CRIT_NUM',
|
69
|
+
description: 'Minimum number of days to SSL/TLS certificate expiration',
|
70
|
+
default: 5,
|
71
|
+
proc: proc(&:to_i)
|
72
|
+
|
73
|
+
option :verbose,
|
74
|
+
short: '-v',
|
75
|
+
long: '--verbose',
|
76
|
+
description: 'Provide SSL/TLS certificate expiration details even when OK',
|
77
|
+
default: false
|
78
|
+
|
79
|
+
def cert_message(count, descriptor, limit)
|
80
|
+
message = (count == 1 ? '1 ELB cert is ' : "#{count} ELB certs are ")
|
81
|
+
message += "#{descriptor} #{limit} day"
|
82
|
+
message += (limit == 1 ? '' : 's') # rubocop:disable UselessAssignment
|
83
|
+
end
|
84
|
+
|
85
|
+
def aws_config
|
86
|
+
hash = {}
|
87
|
+
hash.update access_key_id: config[:aws_access_key], secret_access_key: config[:aws_secret_access_key]\
|
88
|
+
if config[:aws_access_key] && config[:aws_secret_access_key]
|
89
|
+
hash.update region: config[:aws_region]
|
90
|
+
hash
|
91
|
+
end
|
92
|
+
|
93
|
+
def run
|
94
|
+
ok_message = []
|
95
|
+
warning_message = []
|
96
|
+
critical_message = []
|
97
|
+
|
98
|
+
AWS.start_memoizing
|
99
|
+
|
100
|
+
elb = AWS::ELB.new aws_config
|
101
|
+
|
102
|
+
begin
|
103
|
+
elb.load_balancers.each do |lb|
|
104
|
+
lb.listeners.each do |listener| # rubocop:disable Style/Next
|
105
|
+
if listener.protocol.to_s == 'https'
|
106
|
+
url = URI.parse("https://#{lb.dns_name}:#{listener.port}")
|
107
|
+
http = Net::HTTP.new(url.host, url.port)
|
108
|
+
http.use_ssl = true
|
109
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
110
|
+
cert = ''
|
111
|
+
|
112
|
+
begin
|
113
|
+
http.start { cert = http.peer_cert }
|
114
|
+
rescue => e
|
115
|
+
critical "An issue occurred attempting to get cert: #{e.message}"
|
116
|
+
end
|
117
|
+
|
118
|
+
cert_days_remaining = ((cert.not_after - Time.now) / 86_400).to_i
|
119
|
+
message = sprintf '%s(%d)', lb.name, cert_days_remaining
|
120
|
+
|
121
|
+
if config[:crit_under] > 0 && config[:crit_under] >= cert_days_remaining
|
122
|
+
critical_message << message
|
123
|
+
elsif config[:warn_under] > 0 && config[:warn_under] >= cert_days_remaining
|
124
|
+
warning_message << message
|
125
|
+
else
|
126
|
+
ok_message << message
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
rescue => e
|
132
|
+
unknown "An error occurred processing AWS ELB API: #{e.message}"
|
133
|
+
end
|
134
|
+
|
135
|
+
if critical_message.length > 0
|
136
|
+
message = cert_message(critical_message.length, 'expiring within', config[:crit_under])
|
137
|
+
message += ': ' + critical_message.sort.join(' ')
|
138
|
+
critical message
|
139
|
+
elsif warning_message.length > 0
|
140
|
+
message = cert_message(warning_message.length, 'expiring within', config[:warn_under])
|
141
|
+
message += ': ' + warning_message.sort.join(' ')
|
142
|
+
warning message
|
143
|
+
else
|
144
|
+
message = cert_message(ok_message.length, 'valid for at least', config[:warn_under])
|
145
|
+
message += ': ' + ok_message.sort.join(' ') if config[:verbose]
|
146
|
+
ok message
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-elb-health-fog
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# DESCRIPTION:
|
7
|
+
# This plugin checks the health of an Amazon Elastic Load Balancer.
|
8
|
+
#
|
9
|
+
# OUTPUT:
|
10
|
+
# plain-text
|
11
|
+
#
|
12
|
+
# PLATFORMS:
|
13
|
+
# Linux
|
14
|
+
#
|
15
|
+
# DEPENDENCIES:
|
16
|
+
# gem: fog
|
17
|
+
# gem: sensu-plugin
|
18
|
+
# gem: uri
|
19
|
+
#
|
20
|
+
# USAGE:
|
21
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} --warning-over 1000000 --critical-over 1500000
|
22
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkIn --warning-over 1000000 --critical-over 1500000
|
23
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkOut --warning-over 1000000 --critical-over 1500000
|
24
|
+
#
|
25
|
+
# NOTES:
|
26
|
+
#
|
27
|
+
# LICENSE:
|
28
|
+
# Copyright (c) 2014, Panagiotis Papadomitsos <pj@ezgr.net>
|
29
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
30
|
+
# for details.
|
31
|
+
#
|
32
|
+
|
33
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
34
|
+
require 'sensu-plugin/check/cli'
|
35
|
+
require 'net/http'
|
36
|
+
require 'uri'
|
37
|
+
require 'fog/aws'
|
38
|
+
|
39
|
+
class ELBHealth < Sensu::Plugin::Check::CLI
|
40
|
+
option :aws_access_key,
|
41
|
+
short: '-a AWS_ACCESS_KEY',
|
42
|
+
long: '--aws-access-key AWS_ACCESS_KEY',
|
43
|
+
description: "AWS Access Key. Either set ENV['AWS_ACCESS_KEY_ID'] or provide it as an option",
|
44
|
+
required: true,
|
45
|
+
default: ENV['AWS_ACCESS_KEY_ID']
|
46
|
+
|
47
|
+
option :aws_secret_access_key,
|
48
|
+
short: '-s AWS_SECRET_ACCESS_KEY',
|
49
|
+
long: '--aws-secret-access-key AWS_SECRET_ACCESS_KEY',
|
50
|
+
description: "AWS Secret Access Key. Either set ENV['AWS_SECRET_ACCESS_KEY'] or provide it as an option",
|
51
|
+
required: true,
|
52
|
+
default: ENV['AWS_SECRET_ACCESS_KEY']
|
53
|
+
|
54
|
+
option :aws_region,
|
55
|
+
short: '-r AWS_REGION',
|
56
|
+
long: '--aws-region REGION',
|
57
|
+
description: 'AWS Region (such as eu-west-1). If you do not specify a region, it will be detected by the server the script is run on'
|
58
|
+
|
59
|
+
option :elb_name,
|
60
|
+
short: '-n ELB_NAME',
|
61
|
+
long: '--elb-name ELB_NAME',
|
62
|
+
description: 'The Elastic Load Balancer name of which you want to check the health',
|
63
|
+
required: true
|
64
|
+
|
65
|
+
option :instances,
|
66
|
+
short: '-i INSTANCES',
|
67
|
+
long: '--instances INSTANCES',
|
68
|
+
description: 'Comma separated list of specific instances IDs inside the ELB of which you want to check the health'
|
69
|
+
|
70
|
+
option :verbose,
|
71
|
+
short: '-v',
|
72
|
+
long: '--verbose',
|
73
|
+
description: 'Enable a little bit more verbose reports about instance health',
|
74
|
+
boolean: true,
|
75
|
+
default: false
|
76
|
+
|
77
|
+
def query_instance_region
|
78
|
+
instance_az = nil
|
79
|
+
Timeout.timeout(3) do
|
80
|
+
instance_az = Net::HTTP.get(URI('http://169.254.169.254/latest/meta-data/placement/availability-zone/'))
|
81
|
+
end
|
82
|
+
instance_az[0...-1]
|
83
|
+
rescue
|
84
|
+
raise "Cannot obtain this instance's Availability Zone. Maybe not running on AWS?"
|
85
|
+
end
|
86
|
+
|
87
|
+
def aws_config
|
88
|
+
hash = {}
|
89
|
+
hash.update access_key_id: config[:access_key_id], secret_access_key: config[:secret_access_key] if config[:access_key_id] && config[:secret_access_key]
|
90
|
+
hash.update region: config[:region]
|
91
|
+
hash
|
92
|
+
end
|
93
|
+
|
94
|
+
def run
|
95
|
+
aws_region = (config[:aws_region].nil? || config[:aws_region].empty?) ? query_instance_region : config[:aws_region]
|
96
|
+
begin
|
97
|
+
elb = Fog::AWS::ELB.new aws_config
|
98
|
+
if config[:instances]
|
99
|
+
instances = config[:instances].split(',')
|
100
|
+
health = elb.describe_instance_health(config[:elb_name], instances)
|
101
|
+
else
|
102
|
+
health = elb.describe_instance_health(config[:elb_name])
|
103
|
+
end
|
104
|
+
unhealthy_instances = {}
|
105
|
+
health.body['DescribeInstanceHealthResult']['InstanceStates'].each do |instance|
|
106
|
+
unhealthy_instances[instance['InstanceId']] = instance['State'] unless instance['State'].eql?('InService')
|
107
|
+
end
|
108
|
+
if unhealthy_instances.empty?
|
109
|
+
ok "All instances on ELB #{aws_region}::#{config[:elb_name]} healthy!"
|
110
|
+
else
|
111
|
+
if config[:verbose]
|
112
|
+
critical "Unhealthy instances detected: #{unhealthy_instances.map { |id, state| '[' + id + '::' + state + ']' }.join(' ') }"
|
113
|
+
else
|
114
|
+
critical "Detected [#{unhealthy_instances.size}] unhealthy instances"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
rescue => e
|
118
|
+
warning "An issue occured while communicating with the AWS EC2 API: #{e.message}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-elb-health-sdk
|
4
|
+
# Last Update: 1/22/2015 by bkett
|
5
|
+
# ===
|
6
|
+
#
|
7
|
+
# DESCRIPTION:
|
8
|
+
# This plugin checks the health of an Amazon Elastic Load Balancer or all ELBs in a given region.
|
9
|
+
#
|
10
|
+
# OUTPUT:
|
11
|
+
# plain-text
|
12
|
+
#
|
13
|
+
# PLATFORMS:
|
14
|
+
# Linux
|
15
|
+
#
|
16
|
+
# DEPENDENCIES:
|
17
|
+
# gem: aws-sdk
|
18
|
+
# gem: uri
|
19
|
+
# gem: net/http
|
20
|
+
# gem: sensu-plugin
|
21
|
+
#
|
22
|
+
# Copyright (c) 2015, Benjamin Kett <bkett@umn.edu>
|
23
|
+
#
|
24
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
25
|
+
# for details.
|
26
|
+
|
27
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
28
|
+
require 'sensu-plugin/check/cli'
|
29
|
+
require 'net/http'
|
30
|
+
require 'uri'
|
31
|
+
require 'aws-sdk'
|
32
|
+
|
33
|
+
class ELBHealth < Sensu::Plugin::Check::CLI
|
34
|
+
option :aws_access_key,
|
35
|
+
short: '-a AWS_ACCESS_KEY',
|
36
|
+
long: '--aws-access-key AWS_ACCESS_KEY',
|
37
|
+
description: "AWS Access Key. Either set ENV['AWS_ACCESS_KEY_ID'] or provide it as an option",
|
38
|
+
default: ENV['AWS_ACCESS_KEY_ID']
|
39
|
+
|
40
|
+
option :aws_secret_access_key,
|
41
|
+
short: '-s AWS_SECRET_ACCESS_KEY',
|
42
|
+
long: '--aws-secret-access-key AWS_SECRET_ACCESS_KEY',
|
43
|
+
description: "AWS Secret Access Key. Either set ENV['AWS_SECRET_ACCESS_KEY'] or provide it as an option",
|
44
|
+
default: ENV['AWS_SECRET_ACCESS_KEY']
|
45
|
+
|
46
|
+
option :aws_region,
|
47
|
+
short: '-r AWS_REGION',
|
48
|
+
long: '--aws-region REGION',
|
49
|
+
description: 'AWS Region (such as eu-west-1).',
|
50
|
+
default: 'us-east-1'
|
51
|
+
|
52
|
+
option :elb_name,
|
53
|
+
short: '-n ELB_NAME',
|
54
|
+
long: '--elb-name ELB_NAME',
|
55
|
+
description: 'The Elastic Load Balancer name of which you want to check the health'
|
56
|
+
|
57
|
+
option :instances,
|
58
|
+
short: '-i INSTANCES',
|
59
|
+
long: '--instances INSTANCES',
|
60
|
+
description: 'Comma separated list of specific instances IDs inside the ELB of which you want to check the health'
|
61
|
+
|
62
|
+
option :verbose,
|
63
|
+
short: '-v',
|
64
|
+
long: '--verbose',
|
65
|
+
description: 'Enable a little bit more verbose reports about instance health',
|
66
|
+
boolean: true,
|
67
|
+
default: false
|
68
|
+
|
69
|
+
def aws_config
|
70
|
+
hash = {}
|
71
|
+
hash.update access_key_id: config[:access_key_id], secret_access_key: config[:secret_access_key] if config[:access_key_id] && config[:secret_access_key]
|
72
|
+
hash.update region: config[:aws_region]
|
73
|
+
hash
|
74
|
+
end
|
75
|
+
|
76
|
+
def elb
|
77
|
+
@elb ||= AWS::ELB.new aws_config
|
78
|
+
end
|
79
|
+
|
80
|
+
def elbs
|
81
|
+
return @elbs if @elbs
|
82
|
+
@elbs = elb.load_balancers.to_a
|
83
|
+
@elbs.select! { |elb| config[:elb_name].include? elb.name } if config[:elb_name]
|
84
|
+
@elbs
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_health(elb)
|
88
|
+
unhealthy_instances = {}
|
89
|
+
if config[:instances]
|
90
|
+
instance_health_hash = elb.instances.health(config[:instances])
|
91
|
+
else
|
92
|
+
instance_health_hash = elb.instances.health
|
93
|
+
end
|
94
|
+
instance_health_hash.each do |instance_health|
|
95
|
+
if instance_health[:state] != 'InService'
|
96
|
+
unhealthy_instances[instance_health[:instance].id] = instance_health[:state]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
if unhealthy_instances.empty?
|
100
|
+
'OK'
|
101
|
+
else
|
102
|
+
unhealthy_instances
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def run
|
107
|
+
@message = (elbs.size > 1 ? config[:aws_region] + ': ' : '')
|
108
|
+
critical = false
|
109
|
+
elbs.each do |elb|
|
110
|
+
result = check_health elb
|
111
|
+
if result != 'OK'
|
112
|
+
@message += "#{elb.name} unhealthy => #{result.map { |id, state| '[' + id + '::' + state + ']' }.join(' ')}. "
|
113
|
+
critical = true
|
114
|
+
else
|
115
|
+
@message += "#{elb.name} => healthy. "
|
116
|
+
end
|
117
|
+
end
|
118
|
+
if critical
|
119
|
+
critical @message
|
120
|
+
else
|
121
|
+
ok @message
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-elb-health
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin checks the health of an Amazon Elastic Load Balancer.
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain-text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: right-aws
|
16
|
+
# gem: uri
|
17
|
+
# gem: sensu-plugin
|
18
|
+
#
|
19
|
+
# USAGE:
|
20
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} --warning-over 1000000 --critical-over 1500000
|
21
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkIn --warning-over 1000000 --critical-over 1500000
|
22
|
+
# ./check-ec2-network.rb -r ${you_region} -i ${your_instance_id} -d NetworkOut --warning-over 1000000 --critical-over 1500000
|
23
|
+
#
|
24
|
+
# NOTES:
|
25
|
+
#
|
26
|
+
# LICENSE:
|
27
|
+
# Copyright (c) 2012, Panagiotis Papadomitsos <pj@ezgr.net>
|
28
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
29
|
+
# for details.
|
30
|
+
#
|
31
|
+
|
32
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
33
|
+
require 'sensu-plugin/check/cli'
|
34
|
+
require 'net/http'
|
35
|
+
require 'uri'
|
36
|
+
require 'right_aws'
|
37
|
+
|
38
|
+
class ELBHealth < Sensu::Plugin::Check::CLI
|
39
|
+
option :aws_access_key,
|
40
|
+
short: '-a AWS_ACCESS_KEY',
|
41
|
+
long: '--aws-access-key AWS_ACCESS_KEY',
|
42
|
+
description: "AWS Access Key. Either set ENV['AWS_ACCESS_KEY_ID'] or provide it as an option",
|
43
|
+
required: true,
|
44
|
+
default: ENV['AWS_ACCESS_KEY_ID']
|
45
|
+
|
46
|
+
option :aws_secret_access_key,
|
47
|
+
short: '-s AWS_SECRET_ACCESS_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
|
+
required: true,
|
51
|
+
default: ENV['AWS_SECRET_ACCESS_KEY']
|
52
|
+
|
53
|
+
option :aws_region,
|
54
|
+
short: '-r AWS_REGION',
|
55
|
+
long: '--aws-region REGION',
|
56
|
+
description: 'AWS Region (such as eu-west-1). If you do not specify a region, it will be detected by the server the script is run on'
|
57
|
+
|
58
|
+
option :elb_name,
|
59
|
+
short: '-n ELB_NAME',
|
60
|
+
long: '--elb-name ELB_NAME',
|
61
|
+
description: 'The Elastic Load Balancer name of which you want to check the health',
|
62
|
+
required: true
|
63
|
+
|
64
|
+
option :instances,
|
65
|
+
short: '-i INSTANCES',
|
66
|
+
long: '--instances INSTANCES',
|
67
|
+
description: 'Comma separated list of specific instances IDs inside the ELB of which you want to check the health'
|
68
|
+
|
69
|
+
option :verbose,
|
70
|
+
short: '-v',
|
71
|
+
long: '--verbose',
|
72
|
+
description: 'Enable a little bit more verbose reports about instance health',
|
73
|
+
boolean: true,
|
74
|
+
default: false
|
75
|
+
|
76
|
+
def query_instance_region
|
77
|
+
instance_az = nil
|
78
|
+
Timeout.timeout(3) do
|
79
|
+
instance_az = Net::HTTP.get(URI('http://169.254.169.254/latest/meta-data/placement/availability-zone/'))
|
80
|
+
end
|
81
|
+
instance_az[0...-1]
|
82
|
+
rescue
|
83
|
+
raise "Cannot obtain this instance's Availability Zone. Maybe not running on AWS?"
|
84
|
+
end
|
85
|
+
|
86
|
+
def run
|
87
|
+
begin
|
88
|
+
aws_region = (config[:aws_region].nil? || config[:aws_region].empty?) ? query_instance_region : config[:aws_region]
|
89
|
+
elb = RightAws::ElbInterface.new(config[:aws_access_key], config[:aws_secret_access_key],
|
90
|
+
logger: Logger.new('/dev/null'),
|
91
|
+
cache: false,
|
92
|
+
server: "elasticloadbalancing.#{aws_region}.amazonaws.com")
|
93
|
+
if config[:instances]
|
94
|
+
instances = config[:instances].split(',')
|
95
|
+
health = elb.describe_instance_health(config[:elb_name], instances)
|
96
|
+
else
|
97
|
+
health = elb.describe_instance_health(config[:elb_name])
|
98
|
+
end
|
99
|
+
rescue => e
|
100
|
+
critical "An issue occured while communicating with the AWS EC2 API: #{e.message}"
|
101
|
+
end
|
102
|
+
# #YELLOW
|
103
|
+
unless health.empty? # rubocop:disable UnlessElse
|
104
|
+
unhealthy_instances = {}
|
105
|
+
health.each do |instance|
|
106
|
+
unhealthy_instances[instance[:instance_id]] = instance[:state] unless instance[:state].eql?('InService')
|
107
|
+
end
|
108
|
+
# #YELLOW
|
109
|
+
unless unhealthy_instances.empty? # rubocop:disable UnlessElse
|
110
|
+
if config[:verbose]
|
111
|
+
critical "Unhealthy instances detected: #{unhealthy_instances.map { |id, state| '[' + id + '::' + state + ']' }.join(' ')}"
|
112
|
+
else
|
113
|
+
critical "Detected [#{unhealthy_instances.size}] unhealthy instances"
|
114
|
+
end
|
115
|
+
else
|
116
|
+
ok "All instances on ELB #{aws_region}::#{config[:elb_name]} healthy!"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
critical 'Failed to retrieve ELB instance health data'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|