aws-cleanup 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d76a721be9a48db71abf45c602cdd0f69bf2e078
4
- data.tar.gz: 634f6578225b28789a040a48eb88b0bc9be6f064
3
+ metadata.gz: 02e9500fcca4dfdde54f6f7192d98edcccf7535f
4
+ data.tar.gz: 7dc4b26dd7fbffdcae6525927dda09e5e5d01059
5
5
  SHA512:
6
- metadata.gz: 918b6032b0dfd66a382466ecf50d0b3dded623e2a87d2499783a4f0fd552e2a5040f15a9d269d118c27de014a8848a92d7f8a4c8318dfe1bef99163c09ca101f
7
- data.tar.gz: 71e69e3bd5b27bace431c01413b9ef05c7f37b0de47b2502bb3d825d38b1ac875b7082d949bc54a930150be5f799d82ad32cb97e5d3c46ef03cf940182047e4e
6
+ metadata.gz: 929a7bf9ded486e1769500f32453c263f417275d3f9a4c2612898621260172116f6077418822fea70b99ffe85393632c752690c5c0964658cf552acf58d694d4
7
+ data.tar.gz: 8c0609881fe5016af4922830c7e2ab731811a8d2d33648ad9a68d99b4280d30e38fcf469f19568cc300941e7adc3a0e7001b8e9c9ef4d8a2b28ab7a5e8751ce1
data/.gitignore CHANGED
@@ -1,9 +1,10 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
7
6
  /pkg/
8
7
  /spec/reports/
9
8
  /tmp/
9
+
10
+ .byebug_history
@@ -3,3 +3,9 @@ LineLength:
3
3
 
4
4
  MethodLength:
5
5
  Max: 30
6
+
7
+ AbcSize:
8
+ Max: 30
9
+
10
+ Documentation:
11
+ Enabled: false
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ aws-cleanup (1.0.1)
5
+ aws-sdk
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ aws-sdk (2.9.16)
11
+ aws-sdk-resources (= 2.9.16)
12
+ aws-sdk-core (2.9.16)
13
+ aws-sigv4 (~> 1.0)
14
+ jmespath (~> 1.0)
15
+ aws-sdk-resources (2.9.16)
16
+ aws-sdk-core (= 2.9.16)
17
+ aws-sigv4 (1.0.0)
18
+ diff-lcs (1.3)
19
+ jmespath (1.3.1)
20
+ rake (10.5.0)
21
+ rspec (3.6.0)
22
+ rspec-core (~> 3.6.0)
23
+ rspec-expectations (~> 3.6.0)
24
+ rspec-mocks (~> 3.6.0)
25
+ rspec-core (3.6.0)
26
+ rspec-support (~> 3.6.0)
27
+ rspec-expectations (3.6.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.6.0)
30
+ rspec-mocks (3.6.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.6.0)
33
+ rspec-support (3.6.0)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ aws-cleanup!
40
+ bundler (~> 1.13)
41
+ rake (~> 10.0)
42
+ rspec (~> 3.0)
43
+
44
+ BUNDLED WITH
45
+ 1.13.3
@@ -1,4 +1,4 @@
1
1
  require 'rubygems'
2
2
  require 'aws-cleanup'
3
3
 
4
- AwsCleanup.run
4
+ AwsCleanup.run ARGV[0]
@@ -5,100 +5,27 @@ class AwsCleanup
5
5
  TEST_INSTANCE_EXPIRE_AGE = (3_600 * 24).freeze
6
6
  TEST_GROUP_ID = 'sg-1e804874'.freeze
7
7
  TEST_GROUP_NAME = 'ci-testing'.freeze
8
+ DELETE_LIMIT = 10
8
9
 
9
- def self.run
10
- AwsCleanup.new.run
10
+ def self.run(resource)
11
+ AwsCleanup.new.run resource
11
12
  end
12
13
 
13
- def run
14
- cleanup_instances
15
- cleaup_alarms
16
- end
17
-
18
- private
19
-
20
- def cleanup_instances
21
- eii = expired_instances_ids
22
- return unless eii.any?
23
- puts 'Deleting instances: ' + eii.join(', ')
24
- ec2.terminate_instances instance_ids: eii
25
- end
26
-
27
- def cleaup_alarms
28
- oa = orphaned_alarms.map(&:alarm_name)
29
- return unless oa.any?
30
- puts 'Deleting alarms: ' + oa.join(', ')
31
- cloudwatch.delete_alarms alarm_names: oa
32
- end
33
-
34
- def orphaned_alarms
35
- insufficient_data_alarms.select do |alarm|
36
- alarm.dimensions.any? &&
37
- !alarm.dimensions.find { |dimension| dimension_in_use? dimension }
14
+ def run(resource = nil)
15
+ if resource
16
+ require "#{resource}-cleanup"
17
+ AwsCleanup.const_get("#{resource.capitalize}Cleanup").run
18
+ return
38
19
  end
39
- end
40
20
 
41
- def dimension_in_use?(dimension)
42
- case dimension.name
43
- when 'InstanceId'
44
- instance_ids.include? dimension.value
45
- when 'QueueName'
46
- queue_names.include? dimension.value
47
- when 'DBInstanceIdentifier'
48
- db_names.include? dimension.value
49
- else
50
- puts "Unsupported dimension: #{dimension.name}"
51
- true
21
+ Dir.glob(File.dirname(File.absolute_path __FILE__) + '/modules/*').each do |resource_file|
22
+ require resource_file
23
+ class_name = "#{File.basename(resource_file).sub('.rb', '').capitalize}Cleanup"
24
+ AwsCleanup.const_get(class_name).run
52
25
  end
53
26
  end
54
27
 
55
- def queue_names
56
- @queue_names ||= sqs.list_queues.queue_urls.map { |q| URI(q).path.split('/')[2..-1].join('/') }
57
- end
58
-
59
- def db_names
60
- @db_names ||= rds.describe_db_instances.db_instances.map(&:db_instance_identifier)
61
- end
62
-
63
- def expired_instances_ids
64
- expired_instances.map(&:instance_id)
65
- end
66
-
67
- def expired_instances
68
- expired_test_instances | instances_expired_by_tag
69
- end
70
-
71
- def expired_test_instances
72
- test_instances.select { |instance| expired_age? TEST_INSTANCE_EXPIRE_AGE, instance.launch_time }
73
- end
74
-
75
- def test_instances
76
- instances.select do |instance|
77
- instance.security_groups.find do |sg|
78
- sg.group_name == TEST_GROUP_NAME || sg.group_id == TEST_GROUP_ID
79
- end ||
80
- instance.tags.find { |t| t.key == 'Type' && t.value == 'test' }
81
- end
82
- end
83
-
84
- def instances_expired_by_tag
85
- instances.select do |instance|
86
- instance.tags.find do |t|
87
- (t.key == 'expire_after' && expired_age?(t.value, instance.launch_time)) ||
88
- (t.key == 'expires' && expired_time?(t.value))
89
- end
90
- end
91
- end
92
-
93
- def expired_age?(secs, launch_time)
94
- Time.now > (launch_time + secs)
95
- end
96
-
97
- def expired_time?(timestamp)
98
- # `timestamp` should be a string in this format:
99
- # 2017-05-10 13:04:01 -0400
100
- Time.now > Time.parse(timestamp)
101
- end
28
+ private
102
29
 
103
30
  def instance_ids
104
31
  instances.map(&:instance_id)
@@ -111,23 +38,7 @@ class AwsCleanup
111
38
  ).reservations.map(&:instances).flatten
112
39
  end
113
40
 
114
- def insufficient_data_alarms
115
- cloudwatch.describe_alarms(state_value: 'INSUFFICIENT_DATA').metric_alarms
116
- end
117
-
118
- def cloudwatch
119
- @cloudwatch ||= Aws::CloudWatch::Client.new
120
- end
121
-
122
41
  def ec2
123
42
  @ec2 ||= Aws::EC2::Client.new
124
43
  end
125
-
126
- def sqs
127
- @sqs ||= Aws::SQS::Client.new
128
- end
129
-
130
- def rds
131
- @rds ||= Aws::RDS::Client.new
132
- end
133
44
  end
@@ -1,3 +1,3 @@
1
1
  class AwsCleanup
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
@@ -0,0 +1,64 @@
1
+ class CloudwatchCleanup < AwsCleanup
2
+ def self.run
3
+ CloudwatchCleanup.new.cleaup_alarms
4
+ end
5
+
6
+ def cleaup_alarms
7
+ oa = orphaned_alarms.map(&:alarm_name)
8
+
9
+ if oa.any?
10
+ puts 'Deleting alarms: ' + oa.join(', ')
11
+ cloudwatch.delete_alarms alarm_names: oa
12
+ return
13
+ end
14
+
15
+ puts 'No alarms to clean up'
16
+ end
17
+
18
+ private
19
+
20
+ def orphaned_alarms
21
+ insufficient_data_alarms.select do |alarm|
22
+ alarm.dimensions.any? &&
23
+ !alarm.dimensions.find { |dimension| dimension_in_use? dimension }
24
+ end
25
+ end
26
+
27
+ def dimension_in_use?(dimension)
28
+ case dimension.name
29
+ when 'InstanceId'
30
+ instance_ids.include? dimension.value
31
+ when 'QueueName'
32
+ queue_names.include? dimension.value
33
+ when 'DBInstanceIdentifier'
34
+ db_names.include? dimension.value
35
+ else
36
+ puts "Unsupported dimension: #{dimension.name}"
37
+ true
38
+ end
39
+ end
40
+
41
+ def db_names
42
+ @db_names ||= rds.describe_db_instances.db_instances.map(&:db_instance_identifier)
43
+ end
44
+
45
+ def queue_names
46
+ @queue_names ||= sqs.list_queues.queue_urls.map { |q| URI(q).path.split('/')[2..-1].join('/') }
47
+ end
48
+
49
+ def insufficient_data_alarms
50
+ cloudwatch.describe_alarms(state_value: 'INSUFFICIENT_DATA').metric_alarms
51
+ end
52
+
53
+ def cloudwatch
54
+ @cloudwatch ||= Aws::CloudWatch::Client.new
55
+ end
56
+
57
+ def sqs
58
+ @sqs ||= Aws::SQS::Client.new
59
+ end
60
+
61
+ def rds
62
+ @rds ||= Aws::RDS::Client.new
63
+ end
64
+ end
@@ -0,0 +1,67 @@
1
+ class InstancesCleanup < AwsCleanup
2
+ def self.run
3
+ InstancesCleanup.new.cleanup_instances
4
+ end
5
+
6
+ def cleanup_instances
7
+ eii = expired_instances_ids
8
+ if eii.any?
9
+ prompt_user eii if eii.count > DELETE_LIMIT
10
+ puts 'Deleting instances: ' + eii.join(', ')
11
+ ec2.terminate_instances instance_ids: eii
12
+ return
13
+ end
14
+
15
+ puts 'No instances to clean up'
16
+ end
17
+
18
+ private
19
+
20
+ def prompt_user(eii)
21
+ puts "WARNING: The following #{eii.count} instances will be terminated."
22
+ print 'Are you sure? '
23
+ return if %w(y ye yes).include? gets.strip
24
+ puts 'Aborted'
25
+ exit 1
26
+ end
27
+
28
+ def expired_instances_ids
29
+ expired_instances.map(&:instance_id)
30
+ end
31
+
32
+ def expired_instances
33
+ expired_test_instances | instances_expired_by_tag
34
+ end
35
+
36
+ def expired_test_instances
37
+ test_instances.select { |instance| expired_age? TEST_INSTANCE_EXPIRE_AGE, instance.launch_time }
38
+ end
39
+
40
+ def test_instances
41
+ instances.select do |instance|
42
+ instance.security_groups.find do |sg|
43
+ sg.group_name == TEST_GROUP_NAME || sg.group_id == TEST_GROUP_ID
44
+ end ||
45
+ instance.tags.find { |t| t.key == 'Type' && t.value == 'test' }
46
+ end
47
+ end
48
+
49
+ def instances_expired_by_tag
50
+ instances.select do |instance|
51
+ instance.tags.find do |t|
52
+ (t.key == 'expire_after' && expired_age?(t.value, instance.launch_time)) ||
53
+ (t.key == 'expires' && expired_time?(t.value))
54
+ end
55
+ end
56
+ end
57
+
58
+ def expired_age?(secs, launch_time)
59
+ Time.now > (launch_time + secs)
60
+ end
61
+
62
+ def expired_time?(timestamp)
63
+ # `timestamp` should be a string in this format:
64
+ # 2017-05-10 13:04:01 -0400
65
+ Time.now > Time.parse(timestamp)
66
+ end
67
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-cleanup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Herot
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-10 00:00:00.000000000 Z
11
+ date: 2017-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -79,6 +79,7 @@ files:
79
79
  - ".rubocop.yml"
80
80
  - ".travis.yml"
81
81
  - Gemfile
82
+ - Gemfile.lock
82
83
  - LICENSE.txt
83
84
  - README.md
84
85
  - Rakefile
@@ -88,6 +89,8 @@ files:
88
89
  - exe/aws-cleanup
89
90
  - lib/aws-cleanup.rb
90
91
  - lib/aws-cleanup/version.rb
92
+ - lib/modules/cloudwatch.rb
93
+ - lib/modules/instances.rb
91
94
  homepage: https://github.com/evertrue/aws-cleanup
92
95
  licenses:
93
96
  - Apache License 2.0