bosh_cli_plugin_aws 1.5.0.pre.1113

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/lib/bosh/cli/commands/aws.rb +464 -0
  2. data/lib/bosh_cli_plugin_aws/aws_config.rb +141 -0
  3. data/lib/bosh_cli_plugin_aws/aws_provider.rb +53 -0
  4. data/lib/bosh_cli_plugin_aws/bat_manifest.rb +40 -0
  5. data/lib/bosh_cli_plugin_aws/bootstrap.rb +31 -0
  6. data/lib/bosh_cli_plugin_aws/bosh_bootstrap.rb +158 -0
  7. data/lib/bosh_cli_plugin_aws/bosh_manifest.rb +71 -0
  8. data/lib/bosh_cli_plugin_aws/ec2.rb +265 -0
  9. data/lib/bosh_cli_plugin_aws/elb.rb +132 -0
  10. data/lib/bosh_cli_plugin_aws/micro_bosh_bootstrap.rb +64 -0
  11. data/lib/bosh_cli_plugin_aws/microbosh_manifest.rb +117 -0
  12. data/lib/bosh_cli_plugin_aws/migration.rb +40 -0
  13. data/lib/bosh_cli_plugin_aws/migration_helper.rb +150 -0
  14. data/lib/bosh_cli_plugin_aws/migrator.rb +137 -0
  15. data/lib/bosh_cli_plugin_aws/rds.rb +182 -0
  16. data/lib/bosh_cli_plugin_aws/route53.rb +103 -0
  17. data/lib/bosh_cli_plugin_aws/s3.rb +93 -0
  18. data/lib/bosh_cli_plugin_aws/version.rb +5 -0
  19. data/lib/bosh_cli_plugin_aws/vpc.rb +181 -0
  20. data/lib/bosh_cli_plugin_aws.rb +31 -0
  21. data/migrations/20130412000811_create_key_pairs.rb +8 -0
  22. data/migrations/20130412004642_create_vpc.rb +65 -0
  23. data/migrations/20130412181302_create_route53_records.rb +37 -0
  24. data/migrations/20130412183544_create_rds_dbs.rb +35 -0
  25. data/migrations/20130412192351_create_s3.rb +4 -0
  26. data/migrations/20130529212130_create_more_unique_s3_buckets.rb +33 -0
  27. data/migrations/20130531180445_create_bosh_rds_db.rb +30 -0
  28. data/migrations/20130826150635_update_elb_for_websockets.rb +97 -0
  29. data/migrations/20130827000001_add_secondary_az_to_vpc.rb +34 -0
  30. data/templates/aws_configuration_template.yml.erb +187 -0
  31. data/templates/aws_migration.erb +5 -0
  32. data/templates/aws_migration_spec.erb +12 -0
  33. data/templates/bat.yml.erb +84 -0
  34. data/templates/bosh.yml.erb +198 -0
  35. data/templates/micro_bosh.yml.erb +82 -0
  36. metadata +163 -0
@@ -0,0 +1,464 @@
1
+ require "aws-sdk"
2
+ require "securerandom"
3
+ require_relative "../../../bosh_cli_plugin_aws"
4
+
5
+ module Bosh::Cli::Command
6
+ class AWS < Base
7
+ DEFAULT_CIDR = "10.0.0.0/16" # KILL
8
+
9
+ attr_reader :output_state, :config_dir, :ec2
10
+ attr_accessor :vpc
11
+
12
+ def initialize(runner = [])
13
+ super(runner)
14
+ @output_state = {}
15
+ end
16
+
17
+ usage "aws"
18
+ desc "show bosh aws sub-commands"
19
+ def help
20
+ say "bosh aws sub-commands:\n"
21
+ commands = Bosh::Cli::Config.commands.values.find_all { |command| command.usage =~ /^aws/ }
22
+ Bosh::Cli::Command::Help.list_commands(commands)
23
+ end
24
+
25
+ usage "aws bootstrap micro"
26
+ desc "rm deployments dir, creates a deployments/micro/micro_bosh.yml and deploys the microbosh"
27
+ def bootstrap_micro
28
+ options[:hm_director_password] = SecureRandom.base64
29
+ options[:hm_director_user] ||= 'hm'
30
+
31
+ bootstrap = Bosh::Aws::MicroBoshBootstrap.new(runner, options)
32
+ bootstrap.start
33
+
34
+ bootstrap.create_user(options[:hm_director_user], options[:hm_director_password])
35
+
36
+ if interactive?
37
+ username = ask("Enter username: ")
38
+ password = ask("Enter password: ") { |q| q.echo = "*" }
39
+
40
+ if username.blank? || password.blank?
41
+ err("Please enter username and password")
42
+ end
43
+
44
+ bootstrap.create_user(username, password)
45
+ else
46
+ bootstrap.create_user("admin", SecureRandom.base64)
47
+ end
48
+ end
49
+
50
+ usage "aws bootstrap bosh"
51
+ desc "bootstrap full bosh deployment"
52
+ def bootstrap_bosh(config_file = nil)
53
+ target_required
54
+ err "To bootstrap BOSH, first log in to `#{config.target}'" unless logged_in?
55
+
56
+ options[:hm_director_user] ||= 'hm'
57
+ options[:hm_director_password] = SecureRandom.base64
58
+
59
+ bootstrap = Bosh::Aws::BoshBootstrap.new(director, s3(config_file), self.options)
60
+ bootstrap.start
61
+
62
+ say "For security purposes, please provide a username and password for BOSH Director"
63
+ username = ask("Enter username: ")
64
+ password = ask("Enter password: ") { |q| q.echo = "*" }
65
+
66
+ bootstrap.create_user(username, password)
67
+
68
+ say "BOSH deployed successfully. You are logged in as #{username}."
69
+
70
+ bootstrap.create_user(options[:hm_director_user], options[:hm_director_password])
71
+ rescue Bosh::Aws::BootstrapError => e
72
+ err "Unable to bootstrap bosh: #{e.message}"
73
+ end
74
+
75
+ usage "aws generate micro_bosh"
76
+ desc "generate micro_bosh.yml"
77
+ def create_micro_bosh_manifest(vpc_receipt_file, route53_receipt_file)
78
+ vpc_config = load_yaml_file(vpc_receipt_file)
79
+ route53_config = load_yaml_file(route53_receipt_file)
80
+
81
+ options[:hm_director_user] ||= 'hm'
82
+ options[:hm_director_password] = SecureRandom.base64
83
+
84
+ manifest = Bosh::Aws::MicroboshManifest.new(vpc_config, route53_config, options)
85
+
86
+ write_yaml(manifest, manifest.file_name)
87
+ end
88
+
89
+ usage "aws generate bosh"
90
+ desc "generate bosh.yml deployment manifest"
91
+ def create_bosh_manifest(vpc_receipt_file, route53_receipt_file, bosh_rds_receipt_file)
92
+ target_required
93
+
94
+ options[:hm_director_user] ||= 'hm'
95
+ options[:hm_director_password] = SecureRandom.base64
96
+
97
+ vpc_config = load_yaml_file(vpc_receipt_file)
98
+ route53_config = load_yaml_file(route53_receipt_file)
99
+ bosh_rds_config = load_yaml_file(bosh_rds_receipt_file)
100
+ bosh_manifest = Bosh::Aws::BoshManifest.new(vpc_config, route53_config, director.uuid, bosh_rds_config, options)
101
+
102
+ write_yaml(bosh_manifest, bosh_manifest.file_name)
103
+ end
104
+
105
+ usage "aws generate bat"
106
+ desc "generate bat.yml"
107
+ def create_bat_manifest(vpc_receipt_file, route53_receipt_file, stemcell_version, stemcell_name)
108
+ target_required
109
+
110
+ vpc_config = load_yaml_file(vpc_receipt_file)
111
+ route53_config = load_yaml_file(route53_receipt_file)
112
+ manifest = Bosh::Aws::BatManifest.new(
113
+ vpc_config, route53_config, stemcell_version, director.uuid, stemcell_name)
114
+
115
+ write_yaml(manifest, manifest.file_name)
116
+ end
117
+
118
+ usage "aws create"
119
+ desc "create everything in migrations"
120
+ option "--trace", "print all HTTP traffic"
121
+ def create(config_file = nil)
122
+ if !!options[:trace]
123
+ require 'logger'
124
+ ::AWS.config(:logger => Logger.new($stdout), :http_wire_trace => true)
125
+ end
126
+
127
+ Bosh::Aws::Migrator.new(load_config(config_file)).migrate
128
+ end
129
+
130
+ usage "aws create s3"
131
+ desc "create only the s3 buckets"
132
+ def create_s3(config_file = nil)
133
+ Bosh::Aws::Migrator.new(load_config(config_file)).migrate_version("20130412192351")
134
+ end
135
+
136
+ usage "aws create key_pairs"
137
+ desc "creates only the key pairs"
138
+ def create_key_pairs(config_file = nil)
139
+ Bosh::Aws::Migrator.new(load_config(config_file)).migrate_version("20130412000811")
140
+ end
141
+
142
+ usage "aws create route53 records"
143
+ desc "creates only the Route 53 records"
144
+ def create_route53_records(config_file = nil)
145
+ Bosh::Aws::Migrator.new(load_config(config_file)).migrate_version("20130412181302")
146
+ end
147
+
148
+ usage "aws create vpc"
149
+ desc "creates only the VPC"
150
+ def create_vpc(config_file = nil)
151
+ Bosh::Aws::Migrator.new(load_config(config_file)).migrate_version("20130412004642")
152
+ end
153
+
154
+ usage "aws destroy"
155
+ desc "destroy everything in an AWS account"
156
+ def destroy(config_file = nil)
157
+ delete_all_elbs(config_file)
158
+ delete_all_ec2(config_file)
159
+ delete_all_ebs(config_file)
160
+ delete_all_rds_dbs(config_file)
161
+ delete_all_s3(config_file)
162
+ delete_all_vpcs(config_file)
163
+ delete_all_key_pairs(config_file)
164
+ delete_all_elastic_ips(config_file)
165
+ delete_all_security_groups(config_file)
166
+ delete_all_route53_records(config_file)
167
+ end
168
+
169
+ private
170
+
171
+ def s3(config_file)
172
+ config = load_config(config_file)
173
+ Bosh::Aws::S3.new(config["aws"])
174
+ end
175
+
176
+ def delete_vpc(details_file)
177
+ details = load_yaml_file details_file
178
+
179
+ ec2 = Bosh::Aws::EC2.new(details["aws"])
180
+ vpc = Bosh::Aws::VPC.find(ec2, details["vpc"]["id"])
181
+ route53 = Bosh::Aws::Route53.new(details["aws"])
182
+
183
+ err("#{vpc.instances_count} instance(s) running in #{vpc.vpc_id} - delete them first") if vpc.instances_count > 0
184
+
185
+ dhcp_options = vpc.dhcp_options
186
+
187
+ Bosh::Common.retryable(sleep: aws_retry_wait_time,
188
+ tries: 120, on: [::AWS::Errors::Base]) do |tries, e|
189
+ say("unable to delete resource: #{e}") if tries > 0
190
+ vpc.delete_security_groups
191
+ vpc.delete_subnets
192
+ ec2.delete_internet_gateways(ec2.internet_gateway_ids)
193
+ vpc.delete_vpc
194
+ dhcp_options.delete
195
+
196
+ if details["key_pairs"]
197
+ details["key_pairs"].each do |name|
198
+ ec2.remove_key_pair name
199
+ end
200
+ end
201
+
202
+ if details["elastic_ips"]
203
+ details["elastic_ips"].values.each do |job|
204
+ ec2.release_elastic_ips(job["ips"])
205
+ if job["dns_record"]
206
+ route53.delete_record(job["dns_record"], details["vpc"]["domain"])
207
+ end
208
+ end
209
+ end
210
+ true # retryable block must yield true if we only want to retry on Exceptions
211
+ end
212
+
213
+ say "deleted VPC and all dependencies".make_green
214
+ end
215
+
216
+ def delete_all_vpcs(config_file)
217
+ config = load_config(config_file)
218
+
219
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
220
+ vpc_ids = ec2.vpcs.map { |vpc| vpc.id }
221
+ dhcp_options = []
222
+
223
+ unless vpc_ids.empty?
224
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
225
+ say("VPCs:\n\t#{vpc_ids.join("\n\t")}")
226
+
227
+ if confirmed?("Are you sure you want to delete all VPCs?")
228
+ vpc_ids.each do |vpc_id|
229
+ vpc = Bosh::Aws::VPC.find(ec2, vpc_id)
230
+ err("#{vpc.instances_count} instance(s) running in #{vpc.vpc_id} - delete them first") if vpc.instances_count > 0
231
+
232
+ dhcp_options << vpc.dhcp_options
233
+
234
+ vpc.delete_network_interfaces
235
+ vpc.delete_security_groups
236
+ ec2.delete_internet_gateways(ec2.internet_gateway_ids)
237
+ vpc.delete_subnets
238
+ vpc.delete_route_tables
239
+ vpc.delete_vpc
240
+ end
241
+ dhcp_options.uniq(&:id).map(&:delete)
242
+ end
243
+ else
244
+ say("No VPCs found")
245
+ end
246
+ end
247
+
248
+ def delete_all_key_pairs(config_file)
249
+ config = load_config(config_file)
250
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
251
+
252
+ if confirmed?("Are you sure you want to delete all SSH Keypairs?")
253
+ say "Deleting all key pairs..."
254
+ ec2.remove_all_key_pairs
255
+ end
256
+ end
257
+
258
+ def delete_all_elastic_ips(config_file)
259
+ config = load_config(config_file)
260
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
261
+
262
+ if confirmed?("Are you sure you want to delete all Elastic IPs?")
263
+ say "Releasing all elastic IPs..."
264
+ ec2.release_all_elastic_ips
265
+ end
266
+ end
267
+
268
+ def delete_all_s3(config_file)
269
+ config = load_config(config_file)
270
+
271
+ check_instance_count(config)
272
+
273
+ s3 = Bosh::Aws::S3.new(config["aws"])
274
+ bucket_names = s3.bucket_names
275
+
276
+ unless bucket_names.empty?
277
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
278
+ say("Buckets:\n\t#{bucket_names.join("\n\t")}")
279
+
280
+ s3.empty if confirmed?("Are you sure you want to empty and delete all buckets?")
281
+ else
282
+ say("No S3 buckets found")
283
+ end
284
+ end
285
+
286
+ def delete_all_ec2(config_file)
287
+ config = load_config(config_file)
288
+ credentials = config["aws"]
289
+ check_instance_count(config)
290
+ ec2 = Bosh::Aws::EC2.new(credentials)
291
+
292
+ formatted_names = ec2.instance_names.map { |id, name| "#{name} (id: #{id})" }
293
+ unless formatted_names.empty?
294
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
295
+ say("Instances:\n\t#{formatted_names.join("\n\t")}")
296
+
297
+ if confirmed?("Are you sure you want to terminate all terminatable EC2 instances and their associated non-persistent EBS volumes?")
298
+ say "Terminating instances and waiting for them to die..."
299
+ if !ec2.terminate_instances
300
+ say "Warning: instances did not terminate yet after 100 retries".make_red
301
+ end
302
+ end
303
+ else
304
+ say("No EC2 instances found")
305
+ end
306
+ end
307
+
308
+ def delete_all_elbs(config_file)
309
+ config = load_config(config_file)
310
+ credentials = config["aws"]
311
+ elb = Bosh::Aws::ELB.new(credentials)
312
+ elb_names = elb.names
313
+ if elb_names.any? && confirmed?("Are you sure you want to delete all ELBs (#{elb_names.join(", ")})?")
314
+ elb.delete_elbs
315
+ end
316
+ end
317
+
318
+ def delete_server_certificates(config_file)
319
+ config = load_config(config_file)
320
+ credentials = config["aws"]
321
+ elb = Bosh::Aws::ELB.new(credentials)
322
+ certificates = elb.server_certificate_names
323
+
324
+ if certificates.any? && confirmed?("Are you sure you want to delete all server certificates? (#{certificates.join(", ")})")
325
+ elb.delete_server_certificates
326
+ say "Server certificates deleted."
327
+ end
328
+ end
329
+
330
+ def delete_all_rds_dbs(config_file)
331
+ config = load_config(config_file)
332
+ credentials = config["aws"]
333
+ check_instance_count(config)
334
+ rds = Bosh::Aws::RDS.new(credentials)
335
+
336
+ formatted_names = rds.database_names.map { |instance, db| "#{instance}\t(database_name: #{db})" }
337
+
338
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
339
+ say("Database Instances:\n\t#{formatted_names.join("\n\t")}")
340
+
341
+ if confirmed?("Are you sure you want to delete all databases?")
342
+ rds.delete_databases unless formatted_names.empty?
343
+ err("not all rds instances could be deleted") unless all_rds_instances_deleted?(rds)
344
+
345
+ delete_all_rds_subnet_groups(config_file)
346
+ delete_all_rds_security_groups(config_file)
347
+ rds.delete_db_parameter_group('utf8')
348
+ end
349
+ end
350
+
351
+ def delete_all_rds_subnet_groups(config_file)
352
+ config = load_config(config_file)
353
+ credentials = config["aws"]
354
+ rds = Bosh::Aws::RDS.new(credentials)
355
+ rds.delete_subnet_groups
356
+ end
357
+
358
+ def delete_all_rds_security_groups(config_file)
359
+ config = load_config(config_file)
360
+ credentials = config["aws"]
361
+ rds = Bosh::Aws::RDS.new(credentials)
362
+ rds.delete_security_groups
363
+ end
364
+
365
+ def delete_all_ebs(config_file)
366
+ config = load_config(config_file)
367
+ credentials = config["aws"]
368
+ ec2 = Bosh::Aws::EC2.new(credentials)
369
+ check_volume_count(config)
370
+
371
+ if ec2.volume_count > 0
372
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
373
+ say("It will delete #{ec2.volume_count} EBS volume(s)")
374
+
375
+ ec2.delete_volumes if confirmed?("Are you sure you want to delete all unattached EBS volumes?")
376
+ else
377
+ say("No EBS volumes found")
378
+ end
379
+ end
380
+
381
+ def delete_all_security_groups(config_file)
382
+ config = load_config(config_file)
383
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
384
+
385
+ if confirmed?('Are you sure you want to delete all security groups?')
386
+ Bosh::Common.retryable(sleep: aws_retry_wait_time,
387
+ tries: 120, on: [::AWS::EC2::Errors::InvalidGroup::InUse]) do |tries, e|
388
+ say("unable to delete security groups: #{e}") if tries > 0
389
+ ec2.delete_all_security_groups
390
+ true # retryable block must yield true if we only want to retry on Exceptions
391
+ end
392
+ end
393
+ end
394
+
395
+ def delete_all_route53_records(config_file)
396
+ config = load_config(config_file)
397
+ route53 = Bosh::Aws::Route53.new(config["aws"])
398
+
399
+ say("THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red)
400
+
401
+ omit_types = options[:omit_types] || %w[NS SOA]
402
+ if omit_types.empty?
403
+ msg = "Are you sure you want to delete all records from Route 53?"
404
+ else
405
+ msg = "Are you sure you want to delete all but #{omit_types.join("/")} records from Route 53?"
406
+ end
407
+
408
+ route53.delete_all_records(omit_types: omit_types) if confirmed?(msg)
409
+ end
410
+
411
+ def all_rds_instances_deleted?(rds)
412
+ return true if rds.databases.count == 0
413
+ (1..120).any? do |attempt|
414
+ say "waiting for RDS deletion..."
415
+ sleep 10
416
+ rds.databases.each do |db_instance|
417
+ begin
418
+ say " #{db_instance.db_name} #{db_instance.db_instance_status}"
419
+ rescue ::AWS::RDS::Errors::DBInstanceNotFound
420
+ # it is possible for a db to be deleted between the time the
421
+ # each returns an instance and when we print out its info
422
+ end
423
+ end
424
+ rds.databases.count == 0
425
+ end
426
+ end
427
+
428
+ def deployment_manifest_state
429
+ @output_state["deployment_manifest"] ||= {}
430
+ end
431
+
432
+ def deployment_properties
433
+ deployment_manifest_state["properties"] ||= {}
434
+ end
435
+
436
+ def flush_output_state(file_path)
437
+ File.open(file_path, 'w') { |f| f.write output_state.to_yaml }
438
+ end
439
+
440
+ def check_instance_count(config)
441
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
442
+ err("#{ec2.instances_count} instance(s) running. This isn't a dev account (more than 20) please make sure you want to do this, aborting.") if ec2.instances_count > 20
443
+ end
444
+
445
+ def check_volume_count(config)
446
+ ec2 = Bosh::Aws::EC2.new(config["aws"])
447
+ err("#{ec2.volume_count} volume(s) present. This isn't a dev account (more than 20) please make sure you want to do this, aborting.") if ec2.volume_count > 20
448
+ end
449
+
450
+ def default_config_file
451
+ File.expand_path(File.join(
452
+ File.dirname(__FILE__), "..", "..", "..", "..", "templates", "aws_configuration_template.yml.erb"
453
+ ))
454
+ end
455
+
456
+ def load_config(config_file=nil)
457
+ config_file ||= default_config_file
458
+
459
+ Bosh::Aws::AwsConfig.new(config_file).configuration
460
+ end
461
+
462
+ def aws_retry_wait_time; 10; end
463
+ end
464
+ end
@@ -0,0 +1,141 @@
1
+ require 'yaml'
2
+
3
+ module Bosh
4
+ module Aws
5
+ class ConfigurationInvalid < RuntimeError; end
6
+
7
+ class AwsConfig
8
+ def initialize(filename, env = ENV)
9
+ @filename = filename
10
+ @env = env
11
+ end
12
+
13
+ def configuration
14
+ load_configuration(File.read(@filename))
15
+ end
16
+
17
+ def fetch_from_env(key, msg=nil)
18
+ @env.fetch(key) {
19
+ msg ||= "Missing ENV variable #{key}"
20
+ raise(ConfigurationInvalid, msg)
21
+ }
22
+ end
23
+
24
+ def aws_secret_access_key
25
+ fetch_from_env("BOSH_AWS_SECRET_ACCESS_KEY")
26
+ end
27
+
28
+ def aws_access_key_id
29
+ fetch_from_env("BOSH_AWS_ACCESS_KEY_ID")
30
+ end
31
+
32
+ def aws_region
33
+ @env.fetch('BOSH_AWS_REGION', 'us-east-1')
34
+ end
35
+
36
+ def vpc_domain
37
+ @env["BOSH_VPC_DOMAIN"]
38
+ end
39
+
40
+ def vpc_subdomain
41
+ @env["BOSH_VPC_SUBDOMAIN"]
42
+ end
43
+
44
+ def vpc_deployment_name
45
+ if has_vpc_subdomain?
46
+ vpc_subdomain
47
+ elsif has_vpc_domain?
48
+ vpc_domain.gsub('.', '-')
49
+ else
50
+ "deployment"
51
+ end
52
+ end
53
+
54
+ def vpc_generated_domain
55
+ if has_vpc_domain? && has_vpc_subdomain?
56
+ "#{vpc_subdomain}.#{vpc_domain}"
57
+ elsif has_vpc_subdomain?
58
+ "#{vpc_subdomain}.cf-app.com"
59
+ elsif has_vpc_domain?
60
+ vpc_domain
61
+ else
62
+ raise(ConfigurationInvalid, "No domain and subdomain are defined.")
63
+ end
64
+ end
65
+
66
+ def has_vpc_domain?
67
+ vpc_domain && vpc_domain != ""
68
+ end
69
+
70
+ def has_vpc_subdomain?
71
+ vpc_subdomain && vpc_subdomain != ""
72
+ end
73
+
74
+ def vpc_primary_az
75
+ fetch_from_env("BOSH_VPC_PRIMARY_AZ")
76
+ end
77
+
78
+ def vpc_secondary_az
79
+ fetch_from_env("BOSH_VPC_SECONDARY_AZ")
80
+ end
81
+
82
+ def key_pair_name
83
+ @env.fetch("BOSH_KEY_PAIR_NAME", "bosh")
84
+ end
85
+
86
+ def key_pair_path
87
+ @env.fetch("BOSH_KEY_PATH", "#{@env['HOME']}/.ssh/id_rsa_bosh")
88
+ end
89
+
90
+ def elb_ssl_key_file
91
+ @env.fetch("BOSH_AWS_ELB_SSL_KEY", "elb-cfrouter.key")
92
+ end
93
+
94
+ def elb_ssl_cert_file
95
+ @env.fetch("BOSH_AWS_ELB_SSL_CERT", "elb-cfrouter.pem")
96
+ end
97
+
98
+ def elb_ssl_cert_chain_file
99
+ @env["BOSH_AWS_ELB_SSL_CHAIN"]
100
+ end
101
+
102
+ def director_ssl_key_file
103
+ @env.fetch("BOSH_DIRECTOR_SSL_KEY", "director.key")
104
+ end
105
+
106
+ def director_ssl_cert_file
107
+ @env.fetch("BOSH_DIRECTOR_SSL_CERT", "director.pem")
108
+ end
109
+
110
+ def has_package_cache_configuration?
111
+ cache_access_key_id
112
+ end
113
+
114
+ def cache_access_key_id
115
+ @env["BOSH_CACHE_ACCESS_KEY_ID"]
116
+ end
117
+
118
+ def cache_secret_access_key
119
+ unless has_package_cache_configuration?
120
+ raise ConfigurationInvalid, "Missing ENV variable BOSH_CACHE_ACCESS_KEY_ID"
121
+ end
122
+
123
+ fetch_from_env("BOSH_CACHE_SECRET_ACCESS_KEY")
124
+ end
125
+
126
+ def cache_bucket_name
127
+ @env.fetch("BOSH_CACHE_BUCKET_NAME", "bosh-global-package-cache")
128
+ end
129
+
130
+ def production_resources?
131
+ @env['BOSH_PRODUCTION_RESOURCES']
132
+ end
133
+
134
+ def load_configuration(yaml)
135
+ renderer = ERB.new(yaml, 0, '<>%-')
136
+
137
+ YAML.load(renderer.result(binding))
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,53 @@
1
+ module Bosh
2
+ module Aws
3
+ class AwsProvider
4
+ attr_reader :credentials
5
+
6
+ def initialize(credentials)
7
+ @credentials = credentials
8
+ end
9
+
10
+ def ec2
11
+ @ec2 ||= ::AWS::EC2.new(credentials)
12
+ end
13
+
14
+ def elb
15
+ @elb ||= ::AWS::ELB.new(credentials.merge('elb_endpoint' => elb_endpoint))
16
+ end
17
+
18
+ def iam
19
+ @iam ||= ::AWS::IAM.new(credentials)
20
+ end
21
+
22
+ def rds
23
+ @rds ||= ::AWS::RDS.new(credentials.merge('rds_endpoint' => rds_endpoint))
24
+ end
25
+
26
+ def rds_client
27
+ @rds_client ||= ::AWS::RDS::Client.new(credentials.merge('rds_endpoint' => rds_endpoint))
28
+ end
29
+
30
+ def route53
31
+ @aws_route53 ||= ::AWS::Route53.new(credentials)
32
+ end
33
+
34
+ def region
35
+ credentials['region']
36
+ end
37
+
38
+ def s3
39
+ @s3 ||= ::AWS::S3.new(credentials)
40
+ end
41
+
42
+ private
43
+
44
+ def elb_endpoint
45
+ "elasticloadbalancing.#{region}.amazonaws.com"
46
+ end
47
+
48
+ def rds_endpoint
49
+ "rds.#{region}.amazonaws.com"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,40 @@
1
+ require 'net/http'
2
+
3
+ module Bosh
4
+ module Aws
5
+ class BatManifest < MicroboshManifest
6
+ attr_reader :stemcell_version, :director_uuid, :stemcell_name
7
+
8
+ def initialize(vpc_receipt, route53_receipt, stemcell_version, director_uuid, stemcell_name)
9
+ super(vpc_receipt, route53_receipt)
10
+ @stemcell_version = stemcell_version
11
+ @director_uuid = director_uuid
12
+ @stemcell_name = stemcell_name
13
+ end
14
+
15
+ def file_name
16
+ "bat.yml"
17
+ end
18
+
19
+ def deployment_name
20
+ "bat"
21
+ end
22
+
23
+ def domain
24
+ vpc_receipt["vpc"]["domain"] || warning('Missing domain field')
25
+ end
26
+
27
+ def vip
28
+ route53_receipt['elastic_ips']['bat']['ips'][0] || warning('Missing vip field')
29
+ end
30
+
31
+ def to_y
32
+ ERB.new(File.read(get_template("bat.yml.erb"))).result(binding)
33
+ end
34
+
35
+ def get_template(template)
36
+ File.expand_path("../../../templates/#{template}", __FILE__)
37
+ end
38
+ end
39
+ end
40
+ end