cloudstrap 0.39.0.pre → 0.40.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c4cb5dae19069f5a05437bf292d88715c9b6fd8
4
- data.tar.gz: 350a4301002b19771dc901e32bbd314d95d9b109
3
+ metadata.gz: 8d4dab6f668ddb8812d72e3e547d8b86bc6247a0
4
+ data.tar.gz: 4ca88cf04a0516c9ecce532d7e8e84fec74f2d12
5
5
  SHA512:
6
- metadata.gz: 86ae2e41ca6d4f34c46df1b46fa43165dd7862224093f6d1e97d15adfd2ec34702068cb6a1bb41f6d25a66784a6c3057899f1d7ffbde960bc57678feb951dab6
7
- data.tar.gz: 94b34808bd260573df7dc6a1f0377c0e652191e7dae0739d596810647f9832e1b5c347f742599457d31710a684516f42fbd83b6419aad96960103c20a6ca9916
6
+ metadata.gz: 871a1b64c78022fa8b450f7f92583f71b385d436338e3f065dccf6b949b60d2b0c17fc43b4b7e0548725ef0b3f232cc1fe053a161d863bcd4028208b98fbb59b
7
+ data.tar.gz: 3c22f7ff09d79d32677a934ecbdb8cf797738dc90ca2ec21ffd4169f31f816ae6371166c7469126a35600958e357a01ec9f14b4493428db82af2823d095f9952
data/bin/cloudstrap CHANGED
@@ -69,7 +69,7 @@ BOOTSTRAP_WITHOUT_HUMAN_OVERSIGHT=#{!agent.requires_human_oversight?}
69
69
  # Public IPs Enabled in Public Subnet? #{agent.enable_public_ips}
70
70
  # Gateway Attached to VPC? #{agent.attach_gateway}
71
71
  # Route to Internet via Gateway? #{agent.default_route}
72
- # Route to NAT Gateway from Private Subnet? #{agent.nat_route}
72
+ # Route to NAT Gateway from Private Subnets? #{agent.configure_nat_routes}
73
73
  # SSH Allowed to Jumpbox? #{agent.allow_ssh}
74
74
  # SSH Key uploaded to AWS? #{agent.upload_ssh_key}
75
75
  # HDP bootstrap.properties configured? #{agent.configure_hdp}
data/cloudstrap.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_runtime_dependency 'faraday', '~> 0.9', '>= 0.9.0'
24
24
  gem.add_runtime_dependency 'burdened-acrobat', '~> 0.3', '>= 0.3.4'
25
25
  gem.add_runtime_dependency 'path53', '~> 0.4', '>= 0.4.8'
26
+ gem.add_runtime_dependency 'ipaddress', '~> 0.8', '>= 0.8.3'
26
27
  end
data/lib/cloudstrap.rb CHANGED
@@ -2,3 +2,4 @@ require_relative 'cloudstrap/agent'
2
2
  require_relative 'cloudstrap/amazon'
3
3
  require_relative 'cloudstrap/bootstrap_agent'
4
4
  require_relative 'cloudstrap/config'
5
+ require_relative 'cloudstrap/network'
@@ -6,6 +6,7 @@ require_relative 'amazon'
6
6
  require_relative 'config'
7
7
  require_relative 'errors'
8
8
  require_relative 'hdp/bootstrap_properties'
9
+ require_relative 'network'
9
10
  require_relative 'ssh'
10
11
 
11
12
  module Cloudstrap
@@ -150,32 +151,19 @@ module Cloudstrap
150
151
  find_jumpbox_security_group || create_jumpbox_security_group
151
152
  end
152
153
 
154
+ Contract None => Network
155
+ def network
156
+ @network ||= Network.new config.vpc_cidr_block
157
+ end
158
+
153
159
  Contract None => String
154
160
  def private_subnet
155
- @private_subnet ||= ENV.fetch('BOOTSTRAP_PRIVATE_SUBNET_ID') do
156
- cache.fetch(:private_subnet_id) do
157
- properties = { vpc_id: vpc, cidr_block: config.private_cidr_block }
158
- cache.store(:private_subnet_id, (ec2.subnet(properties) || ec2.create_subnet(properties)).tap do |subnet|
159
- ec2.assign_name bootstrap_tag, subnet.subnet_id unless subnet.tags.any? do |tag|
160
- tag.key == 'Name' && tag.value = bootstrap_tag
161
- end
162
- end.subnet_id)
163
- end
164
- end
161
+ private_subnets.values.first
165
162
  end
166
163
 
167
164
  Contract None => String
168
165
  def public_subnet
169
- @public_subnet ||= ENV.fetch('BOOTSTRAP_PUBLIC_SUBNET_ID') do
170
- cache.fetch(:public_subnet_id) do
171
- properties = { vpc_id: vpc, cidr_block: config.public_cidr_block }
172
- cache.store(:public_subnet_id, (ec2.subnet(properties) || ec2.create_subnet(properties)).tap do |subnet|
173
- ec2.assign_name bootstrap_tag, subnet.subnet_id unless subnet.tags.any? do |tag|
174
- tag.key == 'Name' && tag.value = bootstrap_tag
175
- end
176
- end.subnet_id)
177
- end
178
- end
166
+ public_subnets.values.first
179
167
  end
180
168
 
181
169
  Contract None => String
@@ -235,14 +223,51 @@ module Cloudstrap
235
223
  end
236
224
  end
237
225
 
226
+ Contract None => HashOf[String, String]
227
+ def public_subnets
228
+ network.public_layout(*ec2.availability_zone_names).map do |az, cidr|
229
+ properties = { vpc_id: vpc, cidr_block: cidr, availability_zone: az }
230
+ subnet = ec2.subnet(properties) || ec2.create_subnet(properties)
231
+ ec2.assign_name bootstrap_tag, subnet.subnet_id unless subnet
232
+ .tags
233
+ .any? do |tag|
234
+ tag.key == 'Name' && tag.value == bootstrap_tag
235
+ end
236
+ [az, subnet.subnet_id]
237
+ end.to_h
238
+ end
239
+
238
240
  Contract None => ArrayOf[String]
239
241
  def subnets
240
242
  [public_subnet, private_subnet]
241
243
  end
242
244
 
245
+ Contract None => HashOf[String, String]
246
+ def private_subnets
247
+ network.private_layout(*ec2.availability_zone_names).map do |az, cidr|
248
+ properties = { vpc_id: vpc, cidr_block: cidr, availability_zone: az }
249
+ subnet = ec2.subnet(properties) || ec2.create_subnet(properties)
250
+ ec2.assign_name bootstrap_tag, subnet.subnet_id unless subnet
251
+ .tags
252
+ .any? do |tag|
253
+ tag.key == 'Name' && tag.value == bootstrap_tag
254
+ end
255
+ [az, subnet.subnet_id]
256
+ end.to_h
257
+ end
258
+
243
259
  Contract None => Bool
244
260
  def enable_public_ips
245
- ec2.map_public_ip_on_launch?(public_subnet) || ec2.map_public_ip_on_launch(public_subnet, true)
261
+ public_subnets.all? do |_, subnet|
262
+ ec2.map_public_ip_on_launch?(subnet) || ec2.map_public_ip_on_launch(subnet, true)
263
+ end
264
+ end
265
+
266
+ Contract None => Bool
267
+ def configure_nat_routes
268
+ private_subnets.all? do |_, subnet|
269
+ ec2.associate_route_table private_route_table, subnet
270
+ end
246
271
  end
247
272
 
248
273
  Contract None => String
@@ -348,28 +373,12 @@ module Cloudstrap
348
373
 
349
374
  Contract None => String
350
375
  def public_availability_zone
351
- @public_availability_zone ||= ENV.fetch('BOOTSTRAP_PUBLIC_AVAILABILITY_ZONE') do
352
- cache.fetch(:public_availability_zone) do
353
- cache.store(:public_availability_zone, ec2
354
- .subnets
355
- .select { |subnet| subnet.subnet_id == public_subnet }
356
- .map { |subnet| subnet.availability_zone }
357
- .first)
358
- end
359
- end
376
+ public_subnets.keys.first
360
377
  end
361
378
 
362
379
  Contract None => String
363
380
  def private_availability_zone
364
- @private_availability_zone ||= ENV.fetch('BOOTSTRAP_PRIVATE_AVAILABILITY_ZONE') do
365
- cache.fetch(:private_availability_zone) do
366
- cache.store(:private_availability_zone, ec2
367
- .subnets
368
- .select { |subnet| subnet.subnet_id == private_subnet }
369
- .map { |subnet| subnet.availability_zone }
370
- .first)
371
- end
372
- end
381
+ private_subnets.keys.first
373
382
  end
374
383
 
375
384
  Contract None => String
@@ -400,8 +409,8 @@ module Cloudstrap
400
409
  .define('GlusterNodeCount', config.gluster_count)
401
410
  .define('AWS.Region', config.region)
402
411
  .define('AWS.AvailabilityZones', public_availability_zone)
403
- .define('AWS.PublicSubnetIDsAndAZ', [public_subnet, public_availability_zone].join(':'))
404
- .define('AWS.PrivateSubnetIDsAndAZ', [private_subnet, private_availability_zone].join(':'))
412
+ .define('AWS.PublicSubnetIDsAndAZ', public_subnets.invert.map { |*s| s.join(':') }.join(','))
413
+ .define('AWS.PrivateSubnetIDsAndAZ', private_subnets.invert.map { |*s| s.join(':') }.join(','))
405
414
  .define('AWS.Keypair', bootstrap_tag)
406
415
  .define('AWS.KeypairFile', '/home/ubuntu/.ssh/id_rsa')
407
416
  .define('AWS.JumpboxCIDR', '0.0.0.0/0')
@@ -283,13 +283,15 @@ module Cloudstrap
283
283
  Contract KeywordArgs[
284
284
  cidr_block: Optional[String],
285
285
  vpc_id: Optional[String],
286
- subnet_id: Optional[String]
286
+ subnet_id: Optional[String],
287
+ availability_zone: Optional[String]
287
288
  ] => ArrayOf[::Aws::EC2::Types::Subnet]
288
- def subnets(cidr_block: nil, vpc_id: nil, subnet_id: nil)
289
+ def subnets(cidr_block: nil, vpc_id: nil, subnet_id: nil, availability_zone: nil)
289
290
  subnets
290
291
  .select { |subnet| subnet_id.nil? || subnet.subnet_id == subnet_id }
291
292
  .select { |subnet| vpc_id.nil? || subnet.vpc_id == vpc_id }
292
293
  .select { |subnet| cidr_block.nil? || subnet.cidr_block == cidr_block }
294
+ .select { |subnet| availability_zone.nil? || subnet.availability_zone == availability_zone }
293
295
  end
294
296
 
295
297
  Contract Args[Any] => Any
@@ -311,7 +313,8 @@ module Cloudstrap
311
313
 
312
314
  Contract KeywordArgs[
313
315
  cidr_block: String,
314
- vpc_id: String
316
+ vpc_id: String,
317
+ availability_zone: Optional[String]
315
318
  ] => ::Aws::EC2::Types::Subnet
316
319
  def create_subnet(**properties)
317
320
  call_api(:create_subnet, properties).subnet
@@ -413,6 +416,22 @@ module Cloudstrap
413
416
  region_names.include? region_name
414
417
  end
415
418
 
419
+ Contract None => ArrayOf[Aws::EC2::Types::AvailabilityZone]
420
+ def availability_zones!
421
+ @availability_zones = call_api(:describe_availability_zones)
422
+ .availability_zones
423
+ end
424
+
425
+ Contract None => ArrayOf[Aws::EC2::Types::AvailabilityZone]
426
+ def availability_zones
427
+ @availability_zones ||= availability_zones!
428
+ end
429
+
430
+ Contract None => ArrayOf[String]
431
+ def availability_zone_names
432
+ availability_zones.map(&:zone_name)
433
+ end
434
+
416
435
  private
417
436
 
418
437
  def client
@@ -0,0 +1,45 @@
1
+ require 'ipaddress'
2
+
3
+ module Cloudstrap
4
+ class Network
5
+ def initialize(network = '10.0.0.0')
6
+ @network = IPAddress(network).tap { |n| n.prefix = 16 }
7
+ self
8
+ end
9
+
10
+ attr_reader :network
11
+
12
+ def subnets
13
+ @subnets ||= network.subnet 24
14
+ end
15
+
16
+ def public
17
+ @public ||= subnets.select { |subnet| subnet.octet(2).even? }
18
+ end
19
+
20
+ def private
21
+ @private ||= subnets.select { |subnet| subnet.octet(2).odd? }
22
+ end
23
+
24
+ def public_layout(*zones)
25
+ zones
26
+ .zip(public.take(zones.size))
27
+ .map { |zone, subnet| [zone, "#{subnet}/#{subnet.prefix}"] }
28
+ .to_h
29
+ end
30
+
31
+ def private_layout(*zones)
32
+ zones
33
+ .zip(private.take(zones.size))
34
+ .map { |zone, subnet| [zone, "#{subnet}/#{subnet.prefix}"] }
35
+ .to_h
36
+ end
37
+
38
+ def layout(*zones)
39
+ {
40
+ public: public_layout(*zones),
41
+ private: private_layout(*zones)
42
+ }
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0.pre
4
+ version: 0.40.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Olstrom
@@ -230,6 +230,26 @@ dependencies:
230
230
  - - ">="
231
231
  - !ruby/object:Gem::Version
232
232
  version: 0.4.8
233
+ - !ruby/object:Gem::Dependency
234
+ name: ipaddress
235
+ requirement: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - "~>"
238
+ - !ruby/object:Gem::Version
239
+ version: '0.8'
240
+ - - ">="
241
+ - !ruby/object:Gem::Version
242
+ version: 0.8.3
243
+ type: :runtime
244
+ prerelease: false
245
+ version_requirements: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - "~>"
248
+ - !ruby/object:Gem::Version
249
+ version: '0.8'
250
+ - - ">="
251
+ - !ruby/object:Gem::Version
252
+ version: 0.8.3
233
253
  description:
234
254
  email: chris@olstrom.com
235
255
  executables:
@@ -257,6 +277,7 @@ files:
257
277
  - lib/cloudstrap/config.rb
258
278
  - lib/cloudstrap/errors.rb
259
279
  - lib/cloudstrap/hdp/bootstrap_properties.rb
280
+ - lib/cloudstrap/network.rb
260
281
  - lib/cloudstrap/seed_properties.rb
261
282
  - lib/cloudstrap/ssh.rb
262
283
  - lib/cloudstrap/ssh/client.rb