aws-cleanup 1.0.0 → 1.0.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.
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