cloudstrap 0.40.6.pre → 0.41.0.pre
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 +4 -4
- data/bin/cloudstrap-teardown +274 -0
- data/cloudstrap.gemspec +1 -0
- metadata +24 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 50dc8355b21605ab2efa9d6b50ef736790aef7cd
|
|
4
|
+
data.tar.gz: fa0935623212f01051ce772e926998f11e7af097
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8c3056ac6b788d62c78abae32e2a4a6d3567ed02d0b0701308ac7e18d2916b4f1cd86e8881c7cdab6db8ee6ab63d77edca826b35e82f9185988723ccaafb2df1
|
|
7
|
+
data.tar.gz: edb1a9a3b503d94cbb226d3ecdee5fe53878a036dc1334453df12c8f5982cf2c97d8d5a3ce86c6cb1df5009583ea246a39a23582b2ef8fda94c17b921c154213
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
abort 'usage: cloudstrap-teardown <vpc>' if ARGV.empty?
|
|
4
|
+
|
|
5
|
+
require 'aws-sdk'
|
|
6
|
+
require 'concurrent'
|
|
7
|
+
require 'tty/spinner'
|
|
8
|
+
|
|
9
|
+
ARBITRARY_DELAY_TO_PLEASE_THE_EYES = (0.8..1.2)
|
|
10
|
+
|
|
11
|
+
spinner = ->(s) { TTY::Spinner.new "[:spinner] #{s} ...", format: :arrow_pulse }
|
|
12
|
+
|
|
13
|
+
show = lambda do |text, &block|
|
|
14
|
+
Concurrent::IVar.new.tap do |ivar|
|
|
15
|
+
spinner.(text).run('done!') do
|
|
16
|
+
ivar.set block.call
|
|
17
|
+
end
|
|
18
|
+
end.value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wait_a_bit
|
|
22
|
+
sleep rand ARBITRARY_DELAY_TO_PLEASE_THE_EYES
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def user_wants_to_go_fast?
|
|
26
|
+
true unless %w(false nil).include? ENV.fetch('CLOUDSTRAP_GO_ZOOM') { 'false' }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# AWS Resources are lazy by nature.
|
|
31
|
+
##
|
|
32
|
+
|
|
33
|
+
eager = lambda do |method, object|
|
|
34
|
+
if object.respond_to? :flat_map
|
|
35
|
+
object.flat_map(&eager.(method))
|
|
36
|
+
else
|
|
37
|
+
object.public_send(method).map(&:itself)
|
|
38
|
+
end
|
|
39
|
+
end.curry
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Explore VPC
|
|
43
|
+
##
|
|
44
|
+
|
|
45
|
+
task = {}
|
|
46
|
+
|
|
47
|
+
task[:vpcs] = Concurrent.dataflow do
|
|
48
|
+
show.('Discovering VPCs') do
|
|
49
|
+
Aws::EC2::Resource.new.vpcs.select { |vpc| ARGV.include? vpc.id }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
54
|
+
|
|
55
|
+
task[:internet_gateways] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
56
|
+
show.("Discovering Internet Gateways in #{vpcs.size} VPCs") do
|
|
57
|
+
eager.(:internet_gateways).(vpcs)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
62
|
+
|
|
63
|
+
task[:instances] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
64
|
+
show.("Discovering Instances in #{vpcs.size} VPCs") do
|
|
65
|
+
eager.(:instances).(vpcs)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
70
|
+
|
|
71
|
+
task[:subnets] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
72
|
+
show.("Discovering Subnets in #{vpcs.size} VPCs") do
|
|
73
|
+
eager.(:subnets).(vpcs)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
78
|
+
|
|
79
|
+
task[:security_groups] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
80
|
+
show.("Discovering Security Groups in #{vpcs.size} VPCs") do
|
|
81
|
+
eager.(:security_groups).(vpcs)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
86
|
+
|
|
87
|
+
task[:route_tables] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
88
|
+
show.("Discovering Route Tables in #{vpcs.size} VPCs") do
|
|
89
|
+
eager.(:instances).(vpcs)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
94
|
+
|
|
95
|
+
task[:routes] = Concurrent.dataflow(task[:route_tables]) do |route_tables|
|
|
96
|
+
show.("Discovering Routes in #{route_tables.size} Route Tables") do
|
|
97
|
+
eager.(:routes).(route_tables)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
102
|
+
|
|
103
|
+
task[:sg_ingress_rules] = Concurrent.dataflow(task[:security_groups]) do |security_groups|
|
|
104
|
+
show.("Discovering Ingress Rules in #{security_groups.size} Security Groups") do
|
|
105
|
+
security_groups.map do |security_group|
|
|
106
|
+
ingress_rules = security_group.ip_permissions.map(&:to_h).map do |rule|
|
|
107
|
+
rule.reject { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
|
|
108
|
+
end
|
|
109
|
+
[security_group, ingress_rules]
|
|
110
|
+
end.to_h
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
115
|
+
|
|
116
|
+
task[:sg_egress_rules] = Concurrent.dataflow(task[:security_groups]) do |security_groups|
|
|
117
|
+
show.("Discovering Egress Rules in #{security_groups.size} Security Groups") do
|
|
118
|
+
security_groups.map do |security_group|
|
|
119
|
+
egress_rules = security_group.ip_permissions_egress.map(&:to_h).map do |rule|
|
|
120
|
+
rule.reject { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
|
|
121
|
+
end
|
|
122
|
+
[security_group, egress_rules]
|
|
123
|
+
end.to_h
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
128
|
+
|
|
129
|
+
task[:nat_gateways] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
130
|
+
show.("Discovering NAT Gateways in #{vpcs.size} VPCs") do
|
|
131
|
+
query = Aws::EC2::Client.new.describe_nat_gateways
|
|
132
|
+
(query.successful? ? query.nat_gateways : [])
|
|
133
|
+
.select { |ngw| vpcs.any? { |vpc| ngw.vpc_id == vpc.id } }
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
138
|
+
|
|
139
|
+
task[:classic_elbs] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
140
|
+
show.("Discovering Classic Load Balancers in #{vpcs.size} VPCs") do
|
|
141
|
+
query = Aws::ElasticLoadBalancing::Client.new.describe_load_balancers
|
|
142
|
+
(query.successful? ? query.load_balancer_descriptions : [])
|
|
143
|
+
.select { |elb| vpcs.any? { |vpc| elb.vpc_id == vpc.id } }
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
148
|
+
|
|
149
|
+
task[:application_elbs] = Concurrent.dataflow(task[:vpcs]) do |vpcs|
|
|
150
|
+
show.("Discovering Application Load Balancers in #{vpcs.size} VPCs") do
|
|
151
|
+
query = Aws::ElasticLoadBalancingV2::Client.new.describe_load_balancers
|
|
152
|
+
(query.successful? ? query.load_balancers : [])
|
|
153
|
+
.select { |elb| vpcs.any? { |vpc| elb.vpc_id == vpc.id } }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# Burn it to the ground
|
|
159
|
+
##
|
|
160
|
+
|
|
161
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
162
|
+
|
|
163
|
+
task[:instances_relocated] = Concurrent.dataflow(task[:instances], task[:security_groups]) do |instances, security_groups|
|
|
164
|
+
show.("Relocating #{instances.size} Instances to #{security_groups.size} Default Security Groups") do
|
|
165
|
+
instances.map do |instance|
|
|
166
|
+
default = security_groups
|
|
167
|
+
.select { |sg| sg.vpc_id == instance.vpc_id }
|
|
168
|
+
.find { |sg| sg.group_name == 'default' }
|
|
169
|
+
instance.modify_attribute groups: [default.id]
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
175
|
+
|
|
176
|
+
task[:nat_gateways_deleted] = Concurrent.dataflow(task[:nat_gateways]) do |gateways|
|
|
177
|
+
show.("Deleting #{gateways.size} NAT Gateways") do
|
|
178
|
+
gateways.map do |ngw|
|
|
179
|
+
Aws::EC2::Client.new.delete_nat_gateway nat_gateway_id: ngw.nat_gateway_id
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
185
|
+
|
|
186
|
+
task[:instances_terminated] = Concurrent.dataflow(task[:instances], task[:instances_relocated]) do |instances|
|
|
187
|
+
show.("Terminating #{instances.size} Instances") do
|
|
188
|
+
instances.each(&:terminate).map(&:wait_until_terminated)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
193
|
+
|
|
194
|
+
task[:igw_detached] = Concurrent.dataflow(task[:internet_gateways], task[:instances_terminated], task[:nat_gateways_deleted]) do |gateways|
|
|
195
|
+
show.("Detaching #{gateways.size} Internet Gateways") do
|
|
196
|
+
gateways.map do |igw|
|
|
197
|
+
igw.attachments.map(&:vpc_id).map do |vpc|
|
|
198
|
+
igw.detach_from_vpc vpc_id: vpc
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
205
|
+
|
|
206
|
+
task[:igw_deleted] = Concurrent.dataflow(task[:internet_gateways], task[:igw_detached]) do |gateways|
|
|
207
|
+
show.("Deleting #{gateways.size} Internet Gateways") do
|
|
208
|
+
gateways.map(&:delete)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
213
|
+
|
|
214
|
+
task[:sg_ingress_revoked] = Concurrent.dataflow(task[:sg_ingress_rules]) do |ingress|
|
|
215
|
+
count = ingress.values.map(&:size).reduce(:+)
|
|
216
|
+
show.("Revoking #{count} Ingress Rules for Security Groups") do
|
|
217
|
+
ingress.map do |sg, rules|
|
|
218
|
+
sg.revoke_ingress ip_permissions: rules unless rules.empty?
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
224
|
+
|
|
225
|
+
task[:sg_egress_revoked] = Concurrent.dataflow(task[:sg_egress_rules]) do |egress|
|
|
226
|
+
count = egress.values.map(&:size).reduce(:+)
|
|
227
|
+
show.("Revoking #{count} Egress Rules for Security Groups") do
|
|
228
|
+
egress.map do |sg, rules|
|
|
229
|
+
sg.revoke_egress ip_permissions: rules unless rules.empty?
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
235
|
+
|
|
236
|
+
task[:security_groups_deleted] = Concurrent.dataflow(task[:security_groups], task[:sg_ingress_revoked], task[:sg_egress_revoked]) do |all_security_groups|
|
|
237
|
+
security_groups = all_security_groups.reject { |sg| sg.group_name == 'default' }
|
|
238
|
+
show.("Deleting #{security_groups.size} Security Groups") do
|
|
239
|
+
security_groups.map(&:delete)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
244
|
+
|
|
245
|
+
task[:subnets_deleted] = Concurrent.dataflow(task[:subnets]) do |subnets|
|
|
246
|
+
show.("Deleting #{subnets.size} Subnets") do
|
|
247
|
+
subnets.map(&:delete)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
252
|
+
|
|
253
|
+
task[:routes_deleted] = Concurrent.dataflow(task[:routes]) do |all_routes|
|
|
254
|
+
routes = all_routes.reject { |route| route.gateway_id == 'local' }
|
|
255
|
+
show.("Deleting #{routes.size} Routes") do
|
|
256
|
+
routes.each(&:delete)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
wait_a_bit unless user_wants_to_go_fast?
|
|
261
|
+
|
|
262
|
+
vpcs_deleted = Concurrent.dataflow(task[:vpcs], *task.values) do |vpcs|
|
|
263
|
+
show.("Deleting #{vpcs.size} VPCs") do
|
|
264
|
+
vpcs.map do |vpc|
|
|
265
|
+
begin
|
|
266
|
+
vpc.delete
|
|
267
|
+
rescue Aws::EC2::Errors::DependencyViolation => e
|
|
268
|
+
e
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
puts vpcs_deleted.value
|
data/cloudstrap.gemspec
CHANGED
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
|
20
20
|
gem.add_runtime_dependency 'sshkit', '~> 1.11', '>= 1.11.0'
|
|
21
21
|
gem.add_runtime_dependency 'java-properties', '~> 0.1', '>= 0.1.1'
|
|
22
22
|
gem.add_runtime_dependency 'pastel', '~> 0.6', '>= 0.6.0'
|
|
23
|
+
gem.add_runtime_dependency 'tty-spinner', '~> 0.4', '>= 0.4.1'
|
|
23
24
|
gem.add_runtime_dependency 'faraday', '~> 0.9', '>= 0.9.0'
|
|
24
25
|
gem.add_runtime_dependency 'burdened-acrobat', '~> 0.3', '>= 0.3.4'
|
|
25
26
|
gem.add_runtime_dependency 'path53', '~> 0.4', '>= 0.4.8'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cloudstrap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.41.0.pre
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Olstrom
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-12-
|
|
11
|
+
date: 2016-12-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk
|
|
@@ -170,6 +170,26 @@ dependencies:
|
|
|
170
170
|
- - ">="
|
|
171
171
|
- !ruby/object:Gem::Version
|
|
172
172
|
version: 0.6.0
|
|
173
|
+
- !ruby/object:Gem::Dependency
|
|
174
|
+
name: tty-spinner
|
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - "~>"
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0.4'
|
|
180
|
+
- - ">="
|
|
181
|
+
- !ruby/object:Gem::Version
|
|
182
|
+
version: 0.4.1
|
|
183
|
+
type: :runtime
|
|
184
|
+
prerelease: false
|
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
186
|
+
requirements:
|
|
187
|
+
- - "~>"
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: '0.4'
|
|
190
|
+
- - ">="
|
|
191
|
+
- !ruby/object:Gem::Version
|
|
192
|
+
version: 0.4.1
|
|
173
193
|
- !ruby/object:Gem::Dependency
|
|
174
194
|
name: faraday
|
|
175
195
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -255,6 +275,7 @@ email: chris@olstrom.com
|
|
|
255
275
|
executables:
|
|
256
276
|
- cloudstrap
|
|
257
277
|
- cloudstrap-dns
|
|
278
|
+
- cloudstrap-teardown
|
|
258
279
|
extensions: []
|
|
259
280
|
extra_rdoc_files: []
|
|
260
281
|
files:
|
|
@@ -263,6 +284,7 @@ files:
|
|
|
263
284
|
- README.org
|
|
264
285
|
- bin/cloudstrap
|
|
265
286
|
- bin/cloudstrap-dns
|
|
287
|
+
- bin/cloudstrap-teardown
|
|
266
288
|
- cloudstrap.gemspec
|
|
267
289
|
- lib/cloudstrap.rb
|
|
268
290
|
- lib/cloudstrap/agent.rb
|