sensu-plugins-aws-boutetnico 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/LICENSE +22 -0
  4. data/README.md +333 -0
  5. data/bin/check-alb-target-group-health.rb +100 -0
  6. data/bin/check-asg-instances-created.rb +129 -0
  7. data/bin/check-asg-instances-inservice.rb +109 -0
  8. data/bin/check-autoscaling-cpucredits.rb +160 -0
  9. data/bin/check-beanstalk-elb-metric.rb +123 -0
  10. data/bin/check-beanstalk-health.rb +123 -0
  11. data/bin/check-certificate-expiry.rb +123 -0
  12. data/bin/check-cloudfront-tag.rb +70 -0
  13. data/bin/check-cloudwatch-alarm.rb +102 -0
  14. data/bin/check-cloudwatch-alarms.rb +89 -0
  15. data/bin/check-cloudwatch-composite-metric.rb +199 -0
  16. data/bin/check-cloudwatch-metric.rb +123 -0
  17. data/bin/check-configservice-rules.rb +76 -0
  18. data/bin/check-direct-connect-virtual-interfaces.rb +84 -0
  19. data/bin/check-dynamodb-capacity.rb +194 -0
  20. data/bin/check-dynamodb-throttle.rb +188 -0
  21. data/bin/check-ebs-burst-limit.rb +143 -0
  22. data/bin/check-ebs-snapshots.rb +104 -0
  23. data/bin/check-ec2-cpu_balance.rb +139 -0
  24. data/bin/check-ec2-filter.rb +190 -0
  25. data/bin/check-ec2-network.rb +133 -0
  26. data/bin/check-ecs-service-health.rb +155 -0
  27. data/bin/check-efs-metric.rb +145 -0
  28. data/bin/check-eip-allocation.rb +64 -0
  29. data/bin/check-elasticache-failover.rb +113 -0
  30. data/bin/check-elb-certs.rb +132 -0
  31. data/bin/check-elb-health-fog.rb +114 -0
  32. data/bin/check-elb-health-sdk.rb +176 -0
  33. data/bin/check-elb-health.rb +116 -0
  34. data/bin/check-elb-instances-inservice.rb +103 -0
  35. data/bin/check-elb-latency.rb +166 -0
  36. data/bin/check-elb-nodes.rb +133 -0
  37. data/bin/check-elb-sum-requests.rb +157 -0
  38. data/bin/check-emr-cluster.rb +144 -0
  39. data/bin/check-emr-steps.rb +90 -0
  40. data/bin/check-eni-status.rb +110 -0
  41. data/bin/check-expiring-reservations.rb +117 -0
  42. data/bin/check-instance-events.rb +154 -0
  43. data/bin/check-instance-health.rb +108 -0
  44. data/bin/check-instance-reachability.rb +107 -0
  45. data/bin/check-instances-count.rb +94 -0
  46. data/bin/check-kms-key.rb +73 -0
  47. data/bin/check-rds-events.rb +141 -0
  48. data/bin/check-rds-pending.rb +91 -0
  49. data/bin/check-rds.rb +382 -0
  50. data/bin/check-redshift-events.rb +108 -0
  51. data/bin/check-reserved-instances.rb +80 -0
  52. data/bin/check-route.rb +122 -0
  53. data/bin/check-route53-domain-expiration.rb +78 -0
  54. data/bin/check-s3-bucket-visibility.rb +176 -0
  55. data/bin/check-s3-bucket.rb +86 -0
  56. data/bin/check-s3-object.rb +205 -0
  57. data/bin/check-s3-tag.rb +70 -0
  58. data/bin/check-sensu-client.rb +184 -0
  59. data/bin/check-ses-limit.rb +89 -0
  60. data/bin/check-ses-statistics.rb +149 -0
  61. data/bin/check-sns-subscriptions.rb +52 -0
  62. data/bin/check-sqs-messages.rb +168 -0
  63. data/bin/check-subnet-ip-consumption.rb +234 -0
  64. data/bin/check-trustedadvisor-service-limits.rb +90 -0
  65. data/bin/check-vpc-nameservers.rb +87 -0
  66. data/bin/check-vpc-vpn.rb +98 -0
  67. data/bin/handler-ec2_node.rb +241 -0
  68. data/bin/handler-scale-asg-down.rb +131 -0
  69. data/bin/handler-scale-asg-up.rb +131 -0
  70. data/bin/handler-ses.rb +107 -0
  71. data/bin/handler-sns.rb +64 -0
  72. data/bin/metrics-asg.rb +156 -0
  73. data/bin/metrics-autoscaling-instance-count.rb +101 -0
  74. data/bin/metrics-billing.rb +97 -0
  75. data/bin/metrics-cloudfront.rb +159 -0
  76. data/bin/metrics-ec2-count.rb +137 -0
  77. data/bin/metrics-ec2-filter.rb +97 -0
  78. data/bin/metrics-elasticache.rb +166 -0
  79. data/bin/metrics-elb.rb +169 -0
  80. data/bin/metrics-emr-steps.rb +82 -0
  81. data/bin/metrics-rds.rb +153 -0
  82. data/bin/metrics-reservation-utilization.rb +84 -0
  83. data/bin/metrics-s3.rb +107 -0
  84. data/bin/metrics-ses.rb +62 -0
  85. data/bin/metrics-sqs.rb +98 -0
  86. data/bin/metrics-waf.rb +111 -0
  87. data/lib/sensu-plugins-aws.rb +4 -0
  88. data/lib/sensu-plugins-aws/cloudwatch-common.rb +92 -0
  89. data/lib/sensu-plugins-aws/common.rb +35 -0
  90. data/lib/sensu-plugins-aws/filter.rb +47 -0
  91. data/lib/sensu-plugins-aws/version.rb +8 -0
  92. metadata +456 -0
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # CHANGELOG:
4
+ # * 0.8.0:
5
+ # - Added support to use ec2_region from client definition
6
+ # * 0.7.0:
7
+ # - Added method instance_id to check in client config section
8
+ # - Update to new API event naming and simplifying ec2_node_should_be_deleted method and fixing
9
+ # match that will work with any user state defined.
10
+ # * 0.6.0:
11
+ # - Fixed ec2_node_should_be_deleted to account for an empty insances array
12
+ # * 0.5.0:
13
+ # - Adds configuration to filter by state reason
14
+ # * 0.4.0:
15
+ # - Adds ability to specify a list of states an individual client can have in
16
+ # EC2. If none is specified, it filters out 'terminated' and 'stopped'
17
+ # instances by default.
18
+ # - Updates how we are "puts"-ing to the log.
19
+ # * 0.3.0:
20
+ # - Updates handler to additionally filter stopped instances.
21
+ # * 0.2.1:
22
+ # - Updates requested configuration snippets so they'll be redacted by
23
+ # default.
24
+ # * 0.2.0:
25
+ # - Renames handler from chef_ec2_node to ec2_node
26
+ # - Removes Chef-related stuff from handler
27
+ # - Updates documentation
28
+ # * 0.1.0:
29
+ # - Initial release
30
+ #
31
+ # This handler deletes a Sensu client if it's been stopped or terminated in EC2.
32
+ # Optionally, you may specify a client attribute `ec2_states`, a list of valid
33
+ # states an instance may have.
34
+ #
35
+ # You may also specify a client attribute `ec2_state_reasons`, a list of regular
36
+ # expressions to match state reasons against. This is useful if you want to fail
37
+ # on any `Client.*` state reason or on `Server.*` state reason. The default is
38
+ # to match any state reason `.*` Regardless, eventually a client will be
39
+ # deleted once AWS stops responding that the instance id exists.
40
+ #
41
+ # You could specify a ec2_states.json config file for the states like so:
42
+ #
43
+ # {
44
+ # "ec2_node": {
45
+ # "ec2_states": [
46
+ # "terminated",
47
+ # "stopping",
48
+ # "shutting-down",
49
+ # "stopped"
50
+ # ]
51
+ # }
52
+ # }
53
+ #
54
+ # And add that to your /etc/sensu/conf.d directory.
55
+ # If you do not specify any states the handler would not work
56
+ #
57
+ # NOTE: The implementation for correlating Sensu clients to EC2 instances may
58
+ # need to be modified to fit your organization. The current implementation
59
+ # assumes that Sensu clients' names are the same as their instance IDs in EC2.
60
+ # If this is not the case, you can either sub-class this handler and override
61
+ # `ec2_node_should_be_deleted?` in your own organization-specific handler, or modify this
62
+ # handler to suit your needs.
63
+ #
64
+ #
65
+ # A Sensu Client configuration using the ec2_region attribute:
66
+ # {
67
+ # "client": {
68
+ # "name": "i-424242",
69
+ # "address": "127.0.0.1",
70
+ # "ec2_region": "eu-west-1",
71
+ # "subscriptions": ["all"]
72
+ # }
73
+ # }
74
+ # or embeded in the ec2 block
75
+ # {
76
+ # "client": {
77
+ # "name": "i-424242",
78
+ # "address": "127.0.0.1",
79
+ # "ec2" : {
80
+ # "region": "eu-west-1"
81
+ # },
82
+ # "subscriptions": ["all"]
83
+ # }
84
+ # }
85
+ #
86
+ # Or a Sensu Server configuration snippet:
87
+ # {
88
+ # "aws": {
89
+ # "access_key": "adsafdafda",
90
+ # "secret_key": "qwuieohajladsafhj23nm",
91
+ # "region": "us-east-1c"
92
+ # }
93
+ # }
94
+ #
95
+ # Or you can set the following environment variables:
96
+ # - AWS_ACCESS_KEY_ID
97
+ # - AWS_SECRET_ACCESS_KEY
98
+ # - EC2_REGION
99
+ #
100
+ # If none of the settings are found it will then attempt to
101
+ # generate temporary credentials from the IAM instance profile
102
+ #
103
+ # If region is not specified in either of the above 3 mechanisms
104
+ # we will make a request for the EC2 instances current region.
105
+ #
106
+ # To use, you can set it as the keepalive handler for a client:
107
+ # {
108
+ # "client": {
109
+ # "name": "i-424242",
110
+ # "address": "127.0.0.1",
111
+ # "keepalive": {
112
+ # "handler": "ec2_node"
113
+ # },
114
+ # "subscriptions": ["all"]
115
+ # }
116
+ # }
117
+ #
118
+ # You can also use this handler with a filter:
119
+ # {
120
+ # "filters": {
121
+ # "ghost_nodes": {
122
+ # "attributes": {
123
+ # "check": {
124
+ # "name": "keepalive",
125
+ # "status": 2
126
+ # },
127
+ # "occurrences": "eval: value > 2"
128
+ # }
129
+ # }
130
+ # },
131
+ # "handlers": {
132
+ # "ec2_node": {
133
+ # "type": "pipe",
134
+ # "command": "/etc/sensu/handlers/ec2_node.rb",
135
+ # "severities": ["warning","critical"],
136
+ # "filter": "ghost_nodes"
137
+ # }
138
+ # }
139
+ # }
140
+ #
141
+ # Copyleft 2013 Yet Another Clever Name
142
+ #
143
+ # Based off of the `chef_node` handler by Heavy Water Operations, LLC
144
+ #
145
+ # Released under the same terms as Sensu (the MIT license); see
146
+ # LICENSE for details
147
+
148
+ require 'timeout'
149
+ require 'sensu-handler'
150
+ require 'net/http'
151
+ require 'uri'
152
+ require 'aws-sdk'
153
+ require 'sensu-plugins-aws'
154
+
155
+ class Ec2Node < Sensu::Handler
156
+ include Common
157
+
158
+ def filter; end
159
+
160
+ # Method handle
161
+ def handle
162
+ # Call ec2_node_should_be_deleted method and check for instance state and if valid delete from the sensu API otherwise
163
+ # instance is in invalid state
164
+ if ec2_node_should_be_deleted?
165
+ delete_sensu_client!
166
+ else
167
+ puts "[EC2 Node] #{instance_id} is in an invalid state"
168
+ end
169
+ end
170
+
171
+ # Method to delete client from sensu API
172
+ def delete_sensu_client!
173
+ response = api_request(:DELETE, '/clients/' + @event['client']['name']).code
174
+ deletion_status(response)
175
+ end
176
+
177
+ def instance_id
178
+ @event['client']['name']
179
+ end
180
+
181
+ # Method to check if there is any insance and if instance is in a valid state that could be deleted
182
+ def ec2_node_should_be_deleted?
183
+ # Defining region for aws SDK object
184
+ ec2 = Aws::EC2::Client.new(region: region)
185
+ settings['ec2_node'] = {} unless settings['ec2_node']
186
+ instance_states = @event['client']['ec2_states'] || settings['ec2_node']['ec2_states'] || ['shutting-down', 'terminated', 'stopping', 'stopped']
187
+ instance_reasons = @event['client']['ec2_state_reasons'] || settings['ec2_node']['ec2_state_reasons'] || %w[Client.UserInitiatedShutdown Server.SpotInstanceTermination Client.InstanceInitiatedShutdown]
188
+
189
+ begin
190
+ # Finding the instance
191
+ instances = ec2.describe_instances(instance_ids: [instance_id]).reservations[0]
192
+ # If instance is empty/nil instance id is not valid so client can be deleted
193
+ if instances.nil? || instances.empty?
194
+ true
195
+ else
196
+ # Checking for instance state and reason, and if matches any of the user defined or default reasons then
197
+ # method returns True
198
+
199
+ # Returns instance state reason in AWS i.e: "Client.UserInitiatedShutdown"
200
+ instance_state_reason = instances.instances[0].state_reason.nil? ? nil : instances.instances[0].state_reason.code
201
+ # Returns the instance state i.e: "terminated"
202
+ instance_state = instances.instances[0].state.name
203
+
204
+ # Return true is instance state and instance reason is valid
205
+ instance_states.include?(instance_state) && instance_reasons.include?(instance_state_reason)
206
+ end
207
+ rescue Aws::EC2::Errors::InvalidInstanceIDNotFound
208
+ true
209
+ end
210
+ end
211
+
212
+ def region
213
+ @region ||= begin
214
+ region_check = ENV['EC2_REGION']
215
+ region_check = settings['aws']['region'] if settings.key?('aws')
216
+ region_check = @event['client']['ec2_region'] if @event['client'].key?('ec2_region')
217
+ region_check = @event['client']['ec2']['region'] if @event['client'].key?('ec2') && @event['client']['ec2'].key?('region')
218
+ if region_check.nil? || region_check.empty?
219
+ region_check = Net::HTTP.get(URI('http://169.254.169.254/latest/meta-data/placement/availability-zone'))
220
+ matches = /(\w+\-\w+\-\d+)/.match(region_check)
221
+ if !matches.nil? && !matches.captures.empty?
222
+ region_check = matches.captures[0]
223
+ end
224
+ end
225
+ region_check
226
+ end
227
+ end
228
+
229
+ def deletion_status(code)
230
+ case code
231
+ when '202'
232
+ puts "[EC2 Node] 202: Successfully deleted Sensu client: #{@event['client']['name']}"
233
+ when '404'
234
+ puts "[EC2 Node] 404: Unable to delete #{@event['client']['name']}, doesn't exist!"
235
+ when '500'
236
+ puts "[EC2 Node] 500: Miscellaneous error when deleting #{@event['client']['name']}"
237
+ else
238
+ puts "[EC2 Node] #{code}: Completely unsure of what happened!"
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,131 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # handler-scale-down-asg
4
+ #
5
+ # DESCRIPTION:
6
+ # => Decreases the desired capacity of an AutoscalingGroup
7
+ #
8
+ # OUTPUT:
9
+ # plain text
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: aws-sdk
17
+ #
18
+ # USAGE:
19
+ # -j JSONCONFIG - The name of a json config file to be used
20
+ #
21
+ # NOTES:
22
+ # Json config by default should be named asg_scaler.json and should have 2 levels.
23
+ # First level contains: "asg_scaler"
24
+ # Second level contains: "autoscaling_group" and "cooldown_period"
25
+ # example of a valid asg_scaler.json:
26
+ # {
27
+ # "asg_scaler":
28
+ # {
29
+ # "autoscaling_group":"SomeGroupName",
30
+ # "cooldown_period":"36"
31
+ # }
32
+ # }
33
+ #
34
+ # LICENSE:
35
+ # Brian Sizemore <bpsizemore@gmail.com>
36
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
37
+ # for details.
38
+ #
39
+
40
+ require 'aws-sdk'
41
+ require 'json'
42
+ require 'sensu-handler'
43
+
44
+ class AsgScaler < Sensu::Handler
45
+ option :json_config,
46
+ description: 'Name of the json config file',
47
+ short: '-j JSONCONFIG',
48
+ long: '--json JSONCONFIG',
49
+ default: 'asg_scaler'
50
+
51
+ def autoscaling_group
52
+ get_setting('autoscaling_group')
53
+ end
54
+
55
+ def cooldown_period
56
+ get_setting('cooldown_period')
57
+ end
58
+
59
+ def json_config
60
+ cli ||= AsgScaler.new
61
+ cli.config[:json_config]
62
+ end
63
+
64
+ def get_setting(name)
65
+ config_file ||= File.read("#{json_config}.json")
66
+ config ||= JSON.parse(config_file)
67
+ config['asg_scaler'][name]
68
+ end
69
+
70
+ def handle
71
+ @asg = autoscaling_group
72
+ @autoscaling = Aws::AutoScaling::Client.new
73
+ if !out_of_cooldown
74
+ puts "An autoscaling event took place within the past #{cooldown_period} minutes. No action will be taken."
75
+ else
76
+ puts "No event has taken place within the past #{cooldown_period} minutes. Proceeding..."
77
+ begin_scaling
78
+ end
79
+ end
80
+
81
+ def asg_min_instances
82
+ resp = @autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: [@asg],
83
+ max_records: 1)
84
+ resp[0][0][3]
85
+ end
86
+
87
+ def filter_silenced
88
+ # The inhereted filter_silenced method is not working, currently investigating.
89
+ # Handler works properly with this spoofed method.
90
+ end
91
+
92
+ def out_of_cooldown
93
+ resp = @autoscaling.describe_scaling_activities(auto_scaling_group_name: @asg,
94
+ max_records: 1)
95
+ resp = resp[0][0][4].to_s
96
+ resp = resp.sub(' ', 'T')
97
+ resp = resp.sub(' UTC', '+00:00')
98
+
99
+ # Time of last autoscaling event
100
+ aws = DateTime.iso8601(resp) # rubocop: disable Style/DateTime
101
+
102
+ # Current System Time
103
+ now = DateTime.now.new_offset(0) # rubocop: disable Style/DateTime
104
+ diff = (now - aws).to_f # This produces time since last event in days
105
+ diff = diff * 24 * 60 # This produces the time since last event in minutes
106
+ diff > cooldown_period.to_f
107
+ end
108
+
109
+ def current_size
110
+ resp = @autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: [@asg],
111
+ max_records: 1)
112
+ resp[0][0][5]
113
+ end
114
+
115
+ def scale_down
116
+ size = current_size.to_i
117
+ new_size = size - 1
118
+ puts 'scaling down...'
119
+ @autoscaling.set_desired_capacity(auto_scaling_group_name: @asg,
120
+ desired_capacity: new_size)
121
+ end
122
+
123
+ def begin_scaling
124
+ stack_size = current_size
125
+ if stack_size > asg_min_instances
126
+ scale_down
127
+ else
128
+ puts 'The cluster has the minimum amount of instances. No action will be taken.'
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,131 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # handler-scale-up-asg
4
+ #
5
+ # DESCRIPTION:
6
+ # => Increases the desired capacity of an AutoscalingGroup
7
+ #
8
+ # OUTPUT:
9
+ # plain text
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: aws-sdk
17
+ #
18
+ # USAGE:
19
+ # -j JSONCONFIG - The name of a json config file to be used
20
+ #
21
+ # NOTES:
22
+ # Json config by default should be named asg_scaler.json and should have 2 levels.
23
+ # First level contains: "asg_scaler"
24
+ # Second level contains: "autoscaling_group" and "cooldown_period"
25
+ # example of a valid asg_scaler.json:
26
+ # {
27
+ # "asg_scaler":
28
+ # {
29
+ # "autoscaling_group":"SomeGroupName",
30
+ # "cooldown_period":"36"
31
+ # }
32
+ # }
33
+ #
34
+ # LICENSE:
35
+ # Brian Sizemore <bpsizemore@gmail.com>
36
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
37
+ # for details.
38
+ #
39
+
40
+ require 'aws-sdk'
41
+ require 'json'
42
+ require 'sensu-handler'
43
+
44
+ class AsgScaler < Sensu::Handler
45
+ option :json_config,
46
+ description: 'Name of the json config file',
47
+ short: '-j JSONCONFIG',
48
+ long: '--json JSONCONFIG',
49
+ default: 'asg_scaler'
50
+
51
+ def autoscaling_group
52
+ get_setting('autoscaling_group')
53
+ end
54
+
55
+ def cooldown_period
56
+ get_setting('cooldown_period')
57
+ end
58
+
59
+ def json_config
60
+ cli ||= AsgScaler.new
61
+ cli.config[:json_config]
62
+ end
63
+
64
+ def get_setting(name)
65
+ config_file ||= File.read("#{json_config}.json")
66
+ config ||= JSON.parse(config_file)
67
+ config['asg_scaler'][name]
68
+ end
69
+
70
+ def handle
71
+ @asg = autoscaling_group
72
+ @autoscaling = Aws::AutoScaling::Client.new
73
+ if !out_of_cooldown
74
+ puts "An autoscaling event took place within the past #{cooldown_period} minutes. No action will be taken."
75
+ else
76
+ puts "No event has taken place within the past #{cooldown_period} minutes. Proceeding..."
77
+ begin_scaling
78
+ end
79
+ end
80
+
81
+ def asg_max_instances
82
+ resp = @autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: [@asg],
83
+ max_records: 1)
84
+ resp[0][0][4]
85
+ end
86
+
87
+ def filter_silenced
88
+ # The inhereted filter_silenced method is not working, currently investigating.
89
+ # Handler works properly with this spoofed method.
90
+ end
91
+
92
+ def out_of_cooldown
93
+ resp = @autoscaling.describe_scaling_activities(auto_scaling_group_name: @asg,
94
+ max_records: 1)
95
+ resp = resp[0][0][4].to_s
96
+ resp = resp.sub(' ', 'T')
97
+ resp = resp.sub(' UTC', '+00:00')
98
+
99
+ # Time of last autoscaling event
100
+ aws = DateTime.iso8601(resp) # rubocop: disable Style/DateTime
101
+
102
+ # Current System Time
103
+ now = DateTime.now.new_offset(0) # rubocop: disable Style/DateTime
104
+ diff = (now - aws).to_f # This produces time since last event in days
105
+ diff = diff * 24 * 60 # This produces the time since last event in minutes
106
+ diff > cooldown_period.to_f
107
+ end
108
+
109
+ def current_size
110
+ resp = @autoscaling.describe_auto_scaling_groups(auto_scaling_group_names: [@asg],
111
+ max_records: 1)
112
+ resp[0][0][5]
113
+ end
114
+
115
+ def scale_up
116
+ size = current_size.to_i
117
+ new_size = size + 1
118
+ puts 'scaling down...'
119
+ @autoscaling.set_desired_capacity(auto_scaling_group_name: @asg,
120
+ desired_capacity: new_size)
121
+ end
122
+
123
+ def begin_scaling
124
+ stack_size = current_size
125
+ if stack_size < asg_max_instances
126
+ scale_up
127
+ else
128
+ puts 'The cluster has the maximum amount of instances. No action will be taken.'
129
+ end
130
+ end
131
+ end