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,108 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-redshift-events
4
+ #
5
+ # DESCRIPTION:
6
+ # This plugin checks amazon redshift clusters for maintenance events
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
+ #
20
+ # check for instances in maint in us-east-1:
21
+ # ./check-redshift-events.rb -r us-east-1
22
+ #
23
+ # check for maint events on a single instance in us-east-1 (skip others):
24
+ # ./check-redshift-events.rb -r us-east-1 -i ${your cluster name}
25
+ #
26
+ # check for maint events on multiple instance in us-east-1 (skip others):
27
+ # ./check-redshift-events.rb -r us-east-1 -i ${cluster1,cluster2,cluster3}
28
+ #
29
+ # NOTES:
30
+ #
31
+ # LICENSE:
32
+ # Copyright (c) 2014, Tim Smith, tsmith@chef.io
33
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
34
+ # for details.
35
+ #
36
+
37
+ require 'sensu-plugin/check/cli'
38
+ require 'sensu-plugins-aws'
39
+ require 'aws-sdk'
40
+
41
+ class CheckRedshiftEvents < Sensu::Plugin::Check::CLI
42
+ include Common
43
+
44
+ option :aws_region,
45
+ short: '-r AWS_REGION',
46
+ long: '--aws-region REGION',
47
+ description: 'AWS Region (defaults to us-east-1).',
48
+ default: 'us-east-1'
49
+
50
+ option :instances,
51
+ short: '-i INSTANCES',
52
+ long: '--instances INSTANCES',
53
+ description: 'Comma separated list of instances to check. Defaults to all clusters in the region',
54
+ proc: proc { |a| a.split(',') },
55
+ default: []
56
+
57
+ # setup a redshift connection using aws-sdk
58
+ def redshift
59
+ @redshift ||= Aws::Redshift::Client.new aws_config
60
+ end
61
+
62
+ # fetch all clusters in the region from AWS
63
+ def all_clusters
64
+ @clusters ||= redshift.describe_clusters[:clusters].map { |c| c[:cluster_identifier] }
65
+ end
66
+
67
+ # throw unknown message if the user passed us a missing instance
68
+ def check_missing_instances(instances)
69
+ missing_instances = instances.reject { |i| all_clusters.include?(i) }
70
+ unknown("Passed instance(s): #{missing_instances.join(',')} not found") unless missing_instances.empty?
71
+ end
72
+
73
+ # return an array of clusters that are in maintenance
74
+ def clusters_in_maint(clusters)
75
+ maint_clusters = []
76
+
77
+ # fetch the last 2 hours of events for each cluster
78
+ clusters.each do |cluster_name|
79
+ events_record = redshift.describe_events(start_time: (Time.now - 7200).iso8601, source_type: 'cluster', source_identifier: cluster_name)
80
+
81
+ next if events_record[:events].empty?
82
+
83
+ # if the last event is a start maint event then the cluster is still in maint
84
+ maint_clusters.push(cluster_name) if events_record[:events][-1][:event_id] == 'REDSHIFT-EVENT-2003'
85
+ end
86
+ maint_clusters
87
+ end
88
+
89
+ def run
90
+ begin
91
+ # make sure passed instances exist and only check those instances
92
+ unless config[:instances].empty?
93
+ check_missing_instances(config[:instances])
94
+ all_clusters.select! { |c| config[:instances].include?(c) }
95
+ end
96
+
97
+ maint_clusters = clusters_in_maint(all_clusters)
98
+ rescue StandardError => e
99
+ unknown "An error occurred processing AWS Redshift API: #{e.message}"
100
+ end
101
+
102
+ if maint_clusters.empty?
103
+ ok
104
+ else
105
+ critical("Clusters in maintenance: #{maint_clusters.join(',')}")
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,80 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-reserved-instances
4
+ #
5
+ # DESCRIPTION:
6
+ # This plugin checks if reserved instances expire soon.
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-reserved-instances.rb --aws-region eu-west-1 --use-iam
20
+ #
21
+ # NOTES:
22
+ #
23
+ # LICENSE:
24
+ # Copyright (c) 2015, Olivier Bazoud, olivier.bazoud@gmail.com
25
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
26
+ # for details.
27
+ #
28
+
29
+ require 'sensu-plugin/check/cli'
30
+ require 'sensu-plugins-aws'
31
+ require 'aws-sdk'
32
+
33
+ class CheckReservedInstances < Sensu::Plugin::Check::CLI
34
+ include Common
35
+
36
+ option :aws_region,
37
+ short: '-r AWS_REGION',
38
+ long: '--aws-region REGION',
39
+ description: 'AWS Region (defaults to us-east-1).',
40
+ default: 'us-east-1'
41
+
42
+ option :warning,
43
+ description: 'Warn if expire date is lower age in seconds',
44
+ short: '-w SECONDS',
45
+ long: '--warning SECONDS',
46
+ default: 60 * 60 * 24 * 5,
47
+ proc: proc(&:to_i)
48
+
49
+ option :critical,
50
+ description: 'Critical if expire date is lower age in seconds',
51
+ short: '-c SECONDS',
52
+ long: '--critical SECONDS',
53
+ default: 60 * 60 * 24 * 30 * 2,
54
+ proc: proc(&:to_i)
55
+
56
+ def run
57
+ reserved_instances_critical = []
58
+ reserved_instances_warning = []
59
+
60
+ ec2 = Aws::EC2::Client.new
61
+ reserved_instances = ec2.describe_reserved_instances(filters: [{ name: 'state', values: ['active'] }]).reserved_instances
62
+
63
+ reserved_instances.each do |reserved_instance|
64
+ age = reserved_instance.end.to_i - Time.now.to_i
65
+ if age < config[:critical]
66
+ reserved_instances_critical << reserved_instance.reserved_instances_id
67
+ elsif age < config[:warning]
68
+ reserved_instances_warning << reserved_instance.reserved_instances_id
69
+ end
70
+ end
71
+
72
+ if !reserved_instances_critical.empty?
73
+ critical "Reserved instances will expire soon - #{reserved_instances_critical}"
74
+ elsif !reserved_instances_warning.empty?
75
+ warning "Reserved instances will expire soon - #{reserved_instances_warning}"
76
+ end
77
+
78
+ ok "#{reserved_instances.size} reserved instances"
79
+ end
80
+ end
@@ -0,0 +1,122 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-route
4
+ #
5
+ # DESCRIPTION:
6
+ # This plugin checks a route to an instance / eni on a route table
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
+ # #YELLOW
20
+ #
21
+ # NOTES:
22
+ #
23
+ # LICENSE:
24
+ # Copyright (c) 2014, Leon Gibat, brendan.gibat@gmail.com
25
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
26
+ # for details.
27
+ #
28
+
29
+ require 'sensu-plugin/check/cli'
30
+ require 'aws-sdk'
31
+ require 'sensu-plugins-aws'
32
+
33
+ class CheckRoute < Sensu::Plugin::Check::CLI
34
+ include Common
35
+ include Filter
36
+
37
+ option :aws_region,
38
+ short: '-r AWS_REGION',
39
+ long: '--aws-region REGION',
40
+ description: 'AWS Region (defaults to us-east-1).',
41
+ default: 'us-east-1'
42
+
43
+ option :filter,
44
+ short: '-f FILTER',
45
+ long: '--filter FILTER',
46
+ description: 'String representation of the filter to apply',
47
+ default: '{}'
48
+
49
+ option :network_interface_id,
50
+ description: 'Network interface id of route',
51
+ short: '-n NETWORK_INTERFACE_ID',
52
+ long: '--network-interface-id NETWORK_INTERFACE_ID',
53
+ default: ''
54
+
55
+ option :instance_id,
56
+ description: 'Instance Id attachment of route',
57
+ short: '-i INSTANCE_ID',
58
+ long: '--instance-id INSTANCE_ID',
59
+ default: ''
60
+
61
+ option :destination_cidr_block,
62
+ description: 'Destination CIDR block of route',
63
+ short: '-d DESTINATION_CIDR',
64
+ long: '--destination-cidr DESTINATION_CIDR',
65
+ default: ''
66
+
67
+ option :gateway_id,
68
+ description: 'Gateway Id of route',
69
+ short: '-g GATEWAY_ID',
70
+ long: '--gateway-id GATEWAY_ID',
71
+ default: ''
72
+
73
+ option :state,
74
+ description: 'The route state. Can be either "active" or "blackhole"',
75
+ short: '-s STATE',
76
+ long: '--state STATE',
77
+ default: 'active'
78
+
79
+ option :vpc_peering_id,
80
+ description: 'VPC peering connection id',
81
+ short: '-v VPC_PEERING_ID',
82
+ long: '--vpc-peering-id VPC_PEERING_ID',
83
+ default: ''
84
+
85
+ def run
86
+ begin
87
+ aws_config
88
+ client = Aws::EC2::Client.new
89
+
90
+ filter = Filter.parse(config[:filter])
91
+
92
+ options = { filters: filter }
93
+
94
+ data = client.describe_route_tables(options)
95
+
96
+ data[:route_tables].each do |rt|
97
+ rt[:routes].each do |route|
98
+ checks = true
99
+ if config[:state] != route[:state]
100
+ checks = false
101
+ elsif !config[:vpc_peering_id].empty? && config[:vpc_peering_id] != route[:vpc_peering_connection_id]
102
+ checks = false
103
+ elsif !config[:gateway_id].empty? && config[:gateway_id] != route[:gateway_id]
104
+ checks = false
105
+ elsif !config[:destination_cidr_block].empty? && config[:destination_cidr_block] != route[:destination_cidr_block]
106
+ checks = false
107
+ elsif !config[:instance_id].empty? && config[:instance_id] != route[:instance_id]
108
+ checks = false
109
+ elsif !config[:network_interface_id].empty? && config[:network_interface_id] != route[:network_interface_id]
110
+ checks = false
111
+ end
112
+ if checks
113
+ ok
114
+ end
115
+ end
116
+ end
117
+ rescue StandardError => e
118
+ critical "Error: exception: #{e}"
119
+ end
120
+ critical
121
+ end
122
+ end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # check-route53-domain-expiration
4
+ #
5
+ # DESCRIPTION:
6
+ # Alert when Route53 registered domains are close to expiration
7
+ #
8
+ # OUTPUT:
9
+ # plain-text
10
+ #
11
+ # DEPENDENCIES:
12
+ # gem: aws-sdk
13
+ # gem: sensu-plugin
14
+ #
15
+ # USAGE:
16
+ # check-route53-domain-expiration.rb
17
+ #
18
+ # LICENSE:
19
+ # Eric Heydrick <eheydrick@gmail.com>
20
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
21
+ # for details.
22
+
23
+ require 'sensu-plugins-aws'
24
+ require 'sensu-plugin/check/cli'
25
+ require 'aws-sdk'
26
+
27
+ class CheckRoute53DomainExpiration < Sensu::Plugin::Check::CLI
28
+ include Common
29
+
30
+ option :aws_region,
31
+ short: '-r AWS_REGION',
32
+ long: '--aws-region REGION',
33
+ description: 'AWS Region (defaults to us-east-1).',
34
+ default: 'us-east-1'
35
+
36
+ option :warn,
37
+ short: '-w WARN',
38
+ long: '--warning WARN',
39
+ description: 'Warn if domain expires in less than this many days (default: 30)',
40
+ default: 30,
41
+ proc: proc(&:to_i)
42
+
43
+ option :crit,
44
+ short: '-c CRITICAL',
45
+ long: '--critical CRITICAL',
46
+ description: 'Critical if domain expires in less than this many days (default: 7)',
47
+ default: 7,
48
+ proc: proc(&:to_i)
49
+
50
+ def run
51
+ warn_domains = {}
52
+ crit_domains = {}
53
+
54
+ r53 = Aws::Route53Domains::Client.new(aws_config)
55
+ begin
56
+ domains = r53.list_domains.domains
57
+ domains.each do |domain|
58
+ expiration = DateTime.parse(domain.expiry.to_s) # rubocop: disable Style/DateTime
59
+ days_until_expiration = (expiration - DateTime.now).to_i # rubocop: disable Style/DateTime
60
+ if days_until_expiration <= config[:crit]
61
+ crit_domains[domain] = days_until_expiration
62
+ elsif days_until_expiration <= config[:warn]
63
+ warn_domains[domain] = days_until_expiration
64
+ end
65
+ end
66
+
67
+ if !crit_domains.empty?
68
+ critical "Domains are expiring in less than #{config[:crit]} days: " + crit_domains.map { |d, v| "#{d.domain_name} (in #{v} days)" }.join(', ')
69
+ elsif !warn_domains.empty?
70
+ warning "Domains are expiring in less than #{config[:warn]} days: " + warn_domains.map { |d, v| "#{d.domain_name} (in #{v} days)" }.join(', ')
71
+ else
72
+ ok 'No domains are expiring soon'
73
+ end
74
+ rescue StandardError => e
75
+ unknown "An error occurred communicating with the Route53 API: #{e.message}"
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,176 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-s3-bucket-visibility
4
+ #
5
+ # DESCRIPTION:
6
+ # This plugin checks a bucket for website configuration and bucket policy.
7
+ # It alerts if the bucket has a website configuration, or a policy that has
8
+ # Get or List actions.
9
+ #
10
+ # OUTPUT:
11
+ # plain-text
12
+ #
13
+ # PLATFORMS:
14
+ # Linux
15
+ #
16
+ # DEPENDENCIES:
17
+ # gem: aws-sdk
18
+ # gem: sensu-plugin
19
+ #
20
+ # USAGE:
21
+ # ./check-s3-bucket-visibility.rb --bucket-name mybucket --aws-region eu-west-1
22
+ #
23
+ # NOTES:
24
+ #
25
+ # LICENSE:
26
+ # Copyright (c) 2015, Olivier Bazoud and Ricky Hussmann,
27
+ # olivier.bazoud@gmail.com, ricky.hussmann@gmail.com
28
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
29
+ # for details.
30
+ #
31
+
32
+ require 'aws-sdk-s3'
33
+ require 'sensu-plugin/check/cli'
34
+ require 'sensu-plugins-aws'
35
+
36
+ class CheckS3Bucket < Sensu::Plugin::Check::CLI
37
+ include Common
38
+ option :aws_region,
39
+ short: '-r AWS_REGION',
40
+ long: '--aws-region REGION',
41
+ description: 'AWS Region (defaults to us-east-1).',
42
+ default: 'us-east-1'
43
+
44
+ option :bucket_names,
45
+ short: '-b BUCKET_NAMES',
46
+ long: '--bucket-names',
47
+ description: 'A comma seperated list of S3 buckets to check',
48
+ proc: proc { |b| b.split(',') }
49
+
50
+ option :all_buckets,
51
+ short: '-a BOOL',
52
+ long: '--all-buckets BOOL',
53
+ description: 'If all buckets are true it will look at any buckets that we have access to in the region',
54
+ boolean: true,
55
+ default: false
56
+
57
+ option :exclude_buckets,
58
+ short: '-e EXCLUDED_BUCKETS_COMMA_SEPERATED',
59
+ long: '--excluded-buckets EXCLUDED_BUCKETS_COMMA_SEPERATED',
60
+ description: 'A comma seperated list of buckets to ignore that are expected to have loose permissions',
61
+ proc: proc { |b| b.split(',') }
62
+
63
+ option :exclude_regex_filter,
64
+ long: '--exclude-regex-filter MY_REGEX',
65
+ description: 'A regex to filter out bucket names'
66
+
67
+ option :critical_on_missing,
68
+ short: '-m ',
69
+ long: '--critical-on-missing',
70
+ description: 'The check will fail with CRITICAL rather than WARN when a bucket is not found',
71
+ default: 'false'
72
+
73
+ def true?(obj)
74
+ !obj.nil? && obj.to_s.casecmp('true') != -1
75
+ end
76
+
77
+ def s3_client
78
+ @s3_client ||= Aws::S3::Client.new
79
+ end
80
+
81
+ def s3_resource
82
+ @s3_resource || Aws::S3::Resource.new
83
+ end
84
+
85
+ def list_buckets
86
+ buckets = []
87
+ s3_resource.buckets.each do |bucket|
88
+ if s3_resource.client.get_bucket_location(bucket: bucket.name).location_constraint == config[:aws_region]
89
+ buckets << bucket.name
90
+ else
91
+ p "skipping bucket: #{bucket.name} as is not in the region specified: #{config[:aws_region]}"
92
+ end
93
+ end
94
+ buckets
95
+ end
96
+
97
+ def excluded_bucket?(bucket_name)
98
+ return false if config[:exclude_buckets].nil?
99
+ config[:exclude_buckets].include?(bucket_name)
100
+ end
101
+
102
+ def excluded_bucket_regex?(bucket_name)
103
+ return false if config[:exclude_regex_filter].nil?
104
+ if bucket_name.match(Regexp.new(Regexp.escape(config[:exclude_regex_filter])))
105
+ true
106
+ else
107
+ false
108
+ end
109
+ end
110
+
111
+ def website_configuration?(bucket_name)
112
+ s3_client.get_bucket_website(bucket: bucket_name)
113
+ true
114
+ rescue Aws::S3::Errors::NoSuchWebsiteConfiguration
115
+ false
116
+ end
117
+
118
+ def get_bucket_policy(bucket_name)
119
+ JSON.parse(s3_client.get_bucket_policy(bucket: bucket_name).policy.string)
120
+ rescue Aws::S3::Errors::NoSuchBucketPolicy
121
+ { 'Statement' => [] }
122
+ end
123
+
124
+ def policy_too_permissive?(policy)
125
+ policy['Statement'].any? { |s| statement_too_permissive? s }
126
+ end
127
+
128
+ def statement_too_permissive?(s)
129
+ actions_contain_get_or_list? Array(s['Action'])
130
+ end
131
+
132
+ def actions_contain_get_or_list?(actions)
133
+ actions.any? { |a| !Array(a).grep(/^s3:Get|s3:List|s3:\*/).empty? }
134
+ end
135
+
136
+ def run
137
+ errors = []
138
+ warnings = []
139
+ buckets = if config[:all_buckets]
140
+ list_buckets
141
+ elsif config[:bucket_names] && !config[:bucket_names].empty?
142
+ config[:bucket_names]
143
+ else
144
+ unknown 'you must specify either all buckets or provide list of buckets'
145
+ end
146
+
147
+ buckets.each do |bucket_name|
148
+ if excluded_bucket?(bucket_name)
149
+ p "bucket_name: #{bucket_name} was ignored as it matched excluded_buckets"
150
+ next
151
+ elsif excluded_bucket_regex?(bucket_name)
152
+ p "bucket_name: #{bucket_name} was ignored as it matched exclude_regex_filter: #{Regexp.new(Regexp.escape(config[:exclude_regex_filter]))}"
153
+ next
154
+ end
155
+ begin
156
+ if website_configuration?(bucket_name)
157
+ errors.push "#{bucket_name}: website configuration found"
158
+ end
159
+ if policy_too_permissive?(get_bucket_policy(bucket_name))
160
+ errors.push "#{bucket_name}: bucket policy too permissive"
161
+ end
162
+ rescue Aws::S3::Errors::NoSuchBucket
163
+ mesg = "Bucket #{bucket_name} not found"
164
+ true?(config[:critical_on_missing]) ? errors.push(mesg) : warnings.push(mesg)
165
+ end
166
+ end
167
+
168
+ if !errors.empty?
169
+ critical errors.join '; '
170
+ elsif !warnings.empty?
171
+ warning warnings.join '; '
172
+ else
173
+ ok "#{buckets.join ','} not exposed via website or bucket policy"
174
+ end
175
+ end
176
+ end