bosh_cli_plugin_aws 1.5.0.pre.1113

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.
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,103 @@
1
+ module Bosh
2
+ module Aws
3
+ class Route53
4
+
5
+ def initialize(credentials)
6
+ @aws_provider = AwsProvider.new(credentials)
7
+ end
8
+
9
+ def create_zone(zone)
10
+ zone = "#{zone}." unless zone =~ /\.$/
11
+ aws_route53.client.create_hosted_zone(:name => zone, :caller_reference => generate_unique_name)
12
+ true
13
+ end
14
+
15
+ def delete_zone(zone)
16
+ zone = "#{zone}." unless zone =~ /\.$/
17
+ aws_route53.client.delete_hosted_zone(:id => get_zone_id(zone))
18
+ true
19
+ end
20
+
21
+ def add_record(host, zone, addresses, options={})
22
+ host = "\\052" if host == "*"
23
+ zone = "#{zone}." unless zone =~ /\.$/
24
+ addresses = [addresses] unless addresses.kind_of?(Array)
25
+ type = options[:type] || "A"
26
+ ttl = options[:ttl] || 3600
27
+ aws_route53.client.change_resource_record_sets(
28
+ hosted_zone_id: get_zone_id(zone),
29
+ change_batch: {
30
+ changes: [
31
+ {
32
+ action: "CREATE",
33
+ resource_record_set: {
34
+ name: "#{host}.#{zone}",
35
+ type: type,
36
+ ttl: ttl,
37
+ resource_records: addresses.map {|address| { value: address} }
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ )
43
+ true
44
+ end
45
+
46
+ def delete_record(host, zone, options={})
47
+ host = "\\052" if host == "*"
48
+ zone = "#{zone}." unless zone =~ /\.$/
49
+ record_name = "#{host}.#{zone}"
50
+ record_type = options[:type] || "A"
51
+
52
+ zone_response = aws_route53.client.list_resource_record_sets(:hosted_zone_id => get_zone_id(zone))
53
+ resource_record_set = zone_response.data[:resource_record_sets].find do |rr|
54
+ rr[:name] == record_name && rr[:type] == record_type
55
+ end
56
+
57
+ unless resource_record_set
58
+ raise "no #{record_type} record found for #{record_name}"
59
+ end
60
+ aws_route53.client.change_resource_record_sets(
61
+ hosted_zone_id: get_zone_id(zone),
62
+ change_batch: {
63
+ changes: [
64
+ {
65
+ action: "DELETE",
66
+ resource_record_set: resource_record_set
67
+ }
68
+ ]
69
+ }
70
+ )
71
+ true
72
+ end
73
+
74
+ def delete_all_records(options = {})
75
+ omit_types = options[:omit_types] || []
76
+ aws_route53.hosted_zones.each do |zone|
77
+ zone.rrsets.each do |rs|
78
+ rs.delete unless omit_types.include?(rs.type)
79
+ end
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ attr_reader :aws_provider
86
+
87
+ def aws_route53
88
+ aws_provider.route53
89
+ end
90
+
91
+ def get_zone_id(name)
92
+ zones_response = aws_route53.client.list_hosted_zones
93
+ zone = zones_response.data[:hosted_zones].find { |zone| zone[:name] == name }
94
+ raise "Zone not found for #{name} in route53 zones response #{zones_response.inspect}" if zone.nil?
95
+ zone.fetch(:id)
96
+ end
97
+
98
+ def generate_unique_name
99
+ SecureRandom.uuid
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,93 @@
1
+ module Bosh
2
+ module Aws
3
+ class S3
4
+ def initialize(credentials)
5
+ @aws_provider = AwsProvider.new(credentials)
6
+ end
7
+
8
+ def create_bucket(bucket_name)
9
+ aws_s3.buckets.create(bucket_name)
10
+ end
11
+
12
+ def move_bucket(old_bucket, new_bucket)
13
+ fetch_bucket(old_bucket).objects.each do |object|
14
+ object.move_to(object.key, :bucket_name => new_bucket)
15
+ end
16
+ end
17
+
18
+ def delete_bucket(bucket_name)
19
+ bucket = fetch_bucket(bucket_name)
20
+
21
+ bucket.clear!
22
+ bucket.delete
23
+ rescue AWS::S3::Errors::NoSuchBucket
24
+ end
25
+
26
+ def empty
27
+ aws_s3.buckets.each do |bucket|
28
+ begin
29
+ bucket.delete!
30
+ rescue AWS::S3::Errors::NoSuchBucket
31
+ # when the bucket goes away while going through the list
32
+ end
33
+ end
34
+ end
35
+
36
+ def bucket_names
37
+ aws_s3.buckets.map &:name
38
+ end
39
+
40
+ def bucket_exists?(bucket_name)
41
+ bucket_names.include?(bucket_name)
42
+ end
43
+
44
+ def upload_to_bucket(bucket_name, object_name, io)
45
+ bucket = fetch_bucket(bucket_name)
46
+ bucket.objects[object_name].write(io)
47
+ end
48
+
49
+ def objects_in_bucket(bucket_name)
50
+ fetch_bucket(bucket_name).objects.map { |object| object.key }
51
+ end
52
+
53
+ def fetch_object_contents(bucket_name, object_name)
54
+ bucket = fetch_bucket(bucket_name)
55
+ Bosh::Common.retryable(on: AWS::S3::Errors::NoSuchBucket, tries: 10) do
56
+ bucket.objects[object_name].read
57
+ end
58
+ rescue AWS::S3::Errors::NoSuchKey
59
+ nil
60
+ end
61
+
62
+ def copy_remote_file(bucket_name, remote_file, file_name)
63
+ say("Fetching remote file #{remote_file} from #{bucket_name} bucket")
64
+ bucket = aws_s3.buckets[bucket_name]
65
+ object = bucket.objects[remote_file]
66
+ release_file = Tempfile.new file_name
67
+ Bosh::Cli::FileWithProgressBar.open(release_file, 'wb') do |f|
68
+ f.size=object.content_length
69
+ object.read do |chunk|
70
+ f.write chunk
71
+ end
72
+ end
73
+ release_file
74
+ rescue AWS::S3::Errors::NoSuchKey => e
75
+ new_exception = Exception.new("Can't find #{remote_file} in bucket #{bucket_name}")
76
+ new_exception.set_backtrace(e.backtrace)
77
+ raise new_exception
78
+ end
79
+
80
+ private
81
+
82
+ attr_reader :aws_provider
83
+
84
+ def fetch_bucket(bucket_name)
85
+ aws_s3.buckets[bucket_name]
86
+ end
87
+
88
+ def aws_s3
89
+ aws_provider.s3
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,5 @@
1
+ module Bosh
2
+ module Aws
3
+ VERSION = '1.5.0.pre.1113'
4
+ end
5
+ end
@@ -0,0 +1,181 @@
1
+ module Bosh
2
+ module Aws
3
+ class VPC
4
+
5
+ DEFAULT_CIDR = "10.0.0.0/16"
6
+ DEFAULT_ROUTE = "0.0.0.0/0"
7
+ NAT_INSTANCE_DEFAULTS = {
8
+ :image_id => "ami-f619c29f",
9
+ :instance_type => "m1.small"
10
+ }
11
+
12
+ def initialize(ec2, aws_vpc)
13
+ @ec2 = ec2
14
+ @aws_vpc = aws_vpc
15
+ end
16
+
17
+ def self.create(ec2, cidr = DEFAULT_CIDR, instance_tenancy = nil)
18
+ vpc_options = instance_tenancy ? {instance_tenancy: instance_tenancy} : {}
19
+ self.new(ec2, ec2.vpcs.create(cidr, vpc_options))
20
+ end
21
+
22
+ def self.find(ec2, vpc_id)
23
+ self.new(ec2, ec2.vpcs[vpc_id])
24
+ end
25
+
26
+ def make_internet_gateway_default_route_for_subnet(subnet)
27
+ route_table = @aws_vpc.route_tables.create
28
+ route_table.create_route(DEFAULT_ROUTE, internet_gateway: @aws_vpc.internet_gateway)
29
+ subnet.route_table = route_table
30
+ end
31
+
32
+ def make_nat_instance_default_route_for_subnet(subnet, nat_instance)
33
+ route_table = @aws_vpc.route_tables.create
34
+ route_table.create_route(DEFAULT_ROUTE, instance: nat_instance)
35
+ subnet.route_table = route_table
36
+ end
37
+
38
+ def vpc_id
39
+ @aws_vpc.id
40
+ end
41
+
42
+ def cidr_block
43
+ @aws_vpc.cidr_block
44
+ end
45
+
46
+ def instances_count
47
+ @aws_vpc.instances.count
48
+ end
49
+
50
+ def dhcp_options
51
+ @aws_vpc.dhcp_options
52
+ end
53
+
54
+ def state
55
+ @aws_vpc.state
56
+ end
57
+
58
+ def subnets
59
+ Hash[@aws_vpc.subnets.map { |subnet| [subnet.tags["Name"], subnet.id] }]
60
+ end
61
+
62
+ def delete_vpc
63
+ @aws_vpc.delete
64
+ Bosh::Common.retryable(tries: 30, sleep: 5, on: []) do
65
+ begin
66
+ false if @aws_vpc.state
67
+ rescue AWS::EC2::Errors::InvalidVpcID::NotFound
68
+ true
69
+ end
70
+ end
71
+
72
+ rescue ::AWS::EC2::Errors::DependencyViolation
73
+ err "#{@aws_vpc.id} has dependencies that this tool does not delete"
74
+ end
75
+
76
+ def create_security_groups(groups_specs)
77
+ groups_specs.each do |group_spec|
78
+ if group_name_available group_spec["name"]
79
+ security_group = @aws_vpc.security_groups.create(group_spec["name"])
80
+ Bosh::AwsCloud::ResourceWait.for_sgroup(sgroup: security_group, state: true)
81
+ group_spec["ingress"].each do |ingress|
82
+ range_match = ingress["ports"].to_s.match(/(\d+)\s*-\s*(\d+)/)
83
+ ports = range_match ? (range_match[1].to_i)..(range_match[2].to_i) : ingress["ports"].to_i
84
+ security_group.authorize_ingress(ingress["protocol"], ports, ingress["sources"])
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ def delete_security_groups
91
+ @aws_vpc.security_groups.reject { |group| group.name == "default" }.each(&:delete)
92
+ end
93
+
94
+ def security_group_by_name(name)
95
+ @aws_vpc.security_groups.detect { |sg| sg.name == name }
96
+ end
97
+
98
+ def create_subnets(subnets)
99
+ subnets.each_pair do |name, subnet_spec|
100
+ yield "Making subnet #{name} #{subnet_spec["cidr"]}:" if block_given?
101
+ options = {}
102
+ options[:availability_zone] = subnet_spec["availability_zone"] if subnet_spec["availability_zone"]
103
+
104
+ subnet = @aws_vpc.subnets.create(subnet_spec["cidr"], options)
105
+ Bosh::AwsCloud::ResourceWait.for_subnet(subnet: subnet, state: :available)
106
+
107
+ subnet.add_tag("Name", :value => name)
108
+ end
109
+ end
110
+
111
+ def extract_nat_instance_specs(specs)
112
+ subnet_specs_with_nats = specs.select do |_, subnet_spec|
113
+ subnet_spec.has_key?("nat_instance")
114
+ end
115
+
116
+ subnet_specs_with_nats.map do |subnet_name, subnet_spec|
117
+ nat_instance_spec = subnet_spec["nat_instance"]
118
+ nat_instance_spec["subnet_id"] = subnets[subnet_name]
119
+ nat_instance_spec
120
+ end
121
+ end
122
+
123
+ def create_nat_instances(subnets)
124
+ extract_nat_instance_specs(subnets).each do |subnet_spec|
125
+ @ec2.create_nat_instance(subnet_spec)
126
+ end
127
+ end
128
+
129
+ def setup_subnet_routes(subnet_specs)
130
+ subnet_specs.each_pair do |name, subnet_spec|
131
+ if subnet_spec["default_route"]
132
+ subnet = @aws_vpc.subnets[subnets[name]]
133
+ yield " Making routing table for #{name}" if block_given?
134
+ yield " Binding default route to #{subnet_spec["default_route"]}" if block_given?
135
+ if subnet_spec["default_route"] == "igw"
136
+ make_internet_gateway_default_route_for_subnet(subnet)
137
+ else
138
+ make_nat_instance_default_route_for_subnet(subnet, @ec2.get_running_instance_by_name(subnet_spec["default_route"]))
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def delete_subnets
145
+ @aws_vpc.subnets.each(&:delete)
146
+ end
147
+
148
+ def delete_route_tables
149
+ @aws_vpc.route_tables.reject(&:main?).each(&:delete)
150
+ end
151
+
152
+ def delete_network_interfaces
153
+ @aws_vpc.network_interfaces.each(&:delete)
154
+ end
155
+
156
+ def create_dhcp_options(options)
157
+ default_dhcp_opts = @aws_vpc.dhcp_options
158
+
159
+ new_dhcp_options = @ec2.dhcp_options.create(options)
160
+ new_dhcp_options.associate(vpc_id)
161
+ #say "\tcreated and associated DHCP options #{new_dhcp_options.id}".make_green
162
+
163
+ default_dhcp_opts.delete
164
+ end
165
+
166
+ def attach_internet_gateway(gateway_id)
167
+ @aws_vpc.internet_gateway = gateway_id
168
+ end
169
+
170
+ private
171
+
172
+ def group_name_available(name)
173
+ @aws_vpc.security_groups.each { |group| group.delete if group.name == name }
174
+ true
175
+ rescue ::AWS::EC2::Errors::DependencyViolation => e
176
+ say "unable to delete security group: #{name}: #{e.message}".make_yellow
177
+ false
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,31 @@
1
+ require 'aws-sdk'
2
+ require 'logger'
3
+
4
+ # since this plugin is abusing the AWS CPI, the following hack is needed so that
5
+ # task_checkpoint & logger is available when ResourceWait.for_resource is called
6
+ require "cloud"
7
+ Config = Struct.new(:task_checkpoint, :logger)
8
+ Bosh::Clouds::Config.configure(Config.new(true, Logger.new(File::NULL)))
9
+
10
+ require "cloud/aws/resource_wait"
11
+ require "common/ssl"
12
+
13
+ require "bosh_cli_plugin_aws/version"
14
+ require "bosh_cli_plugin_aws/ec2"
15
+ require "bosh_cli_plugin_aws/route53"
16
+ require "bosh_cli_plugin_aws/s3"
17
+ require "bosh_cli_plugin_aws/vpc"
18
+ require "bosh_cli_plugin_aws/rds"
19
+ require "bosh_cli_plugin_aws/elb"
20
+ require "bosh_cli_plugin_aws/bosh_bootstrap"
21
+ require "bosh_cli_plugin_aws/micro_bosh_bootstrap"
22
+ require "bosh_cli_plugin_aws/aws_config"
23
+ require 'bosh_cli_plugin_aws/aws_provider'
24
+ require "bosh/cli/commands/aws"
25
+ require "bosh/cli/commands/micro"
26
+ require "bosh_cli_plugin_aws/microbosh_manifest"
27
+ require "bosh_cli_plugin_aws/bat_manifest"
28
+ require "bosh_cli_plugin_aws/bosh_manifest"
29
+ require "bosh_cli_plugin_aws/migration_helper"
30
+ require "bosh_cli_plugin_aws/migration"
31
+ require "bosh_cli_plugin_aws/migrator"
@@ -0,0 +1,8 @@
1
+ class CreateKeyPairs < Bosh::Aws::Migration
2
+ def execute
3
+ say "allocating #{config["key_pairs"].length} KeyPair(s)"
4
+ config["key_pairs"].each do |name, path|
5
+ ec2.force_add_key_pair(name, path)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,65 @@
1
+ class CreateVpc < Bosh::Aws::Migration
2
+ def execute
3
+ receipt = {}
4
+
5
+ receipt["aws"] = config["aws"]
6
+
7
+ vpc = Bosh::Aws::VPC.create(ec2, config["vpc"]["cidr"], config["vpc"]["instance_tenancy"])
8
+ receipt["vpc"] = {"id" => vpc.vpc_id, "domain" => config["vpc"]["domain"]}
9
+
10
+ receipt["original_configuration"] = config
11
+
12
+ unless was_vpc_eventually_available?(vpc)
13
+ err "VPC #{vpc.vpc_id} was not available within 60 seconds, giving up"
14
+ end
15
+
16
+ say "creating internet gateway"
17
+ igw = ec2.create_internet_gateway
18
+ vpc.attach_internet_gateway(igw.id)
19
+
20
+ security_groups = config["vpc"]["security_groups"]
21
+ say "creating security groups: #{security_groups.map { |group| group["name"] }.join(", ")}"
22
+ vpc.create_security_groups(security_groups)
23
+
24
+ subnets = config["vpc"]["subnets"]
25
+ say "creating subnets: #{subnets.keys.join(", ")}"
26
+ vpc.create_subnets(subnets) { |msg| say " #{msg}" }
27
+ vpc.create_nat_instances(subnets)
28
+ vpc.setup_subnet_routes(subnets) { |msg| say " #{msg}" }
29
+ receipt["vpc"]["subnets"] = vpc.subnets
30
+
31
+ elbs = config["vpc"]["elbs"]
32
+ ssl_certs = config["ssl_certs"]
33
+
34
+ say "creating load balancers: #{elbs.keys.join(", ")}" if elbs
35
+ elbs.each do |name, settings|
36
+ settings["domain"] = config["vpc"]["domain"]
37
+ e = elb.create(name, vpc, settings, ssl_certs)
38
+ if settings["dns_record"]
39
+ say "adding CNAME record for #{settings["dns_record"]}.#{config["vpc"]["domain"]}"
40
+ route53.add_record(settings["dns_record"], config["vpc"]["domain"], [e.dns_name], {ttl: settings["ttl"], type: 'CNAME'})
41
+ end
42
+ end
43
+
44
+ dhcp_options = config["vpc"]["dhcp_options"]
45
+ say "creating DHCP options"
46
+ vpc.create_dhcp_options(dhcp_options)
47
+ rescue Bosh::Aws::ELB::BadCertificateError => e
48
+ err e.message
49
+ ensure
50
+ save_receipt("aws_vpc_receipt", receipt)
51
+ end
52
+
53
+ private
54
+
55
+ def was_vpc_eventually_available?(vpc)
56
+ (1..60).any? do |attempt|
57
+ begin
58
+ sleep 1 unless attempt == 1
59
+ vpc.state.to_s == "available"
60
+ rescue Exception => e
61
+ say("Waiting for vpc, continuing after #{e.class}: #{e.message}")
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,37 @@
1
+ class CreateRoute53Records < Bosh::Aws::Migration
2
+ def execute
3
+ receipt = {}
4
+ elastic_ip_specs = config["elastic_ips"]
5
+
6
+ if elastic_ip_specs
7
+ receipt["elastic_ips"] = {}
8
+ else
9
+ return
10
+ end
11
+
12
+ count = elastic_ip_specs.map{|_, spec| spec["instances"]}.inject(:+)
13
+ say "allocating #{count} elastic IP(s)"
14
+ ec2.allocate_elastic_ips(count)
15
+
16
+ elastic_ips = ec2.elastic_ips
17
+
18
+ elastic_ip_specs.each do |name, job|
19
+ receipt["elastic_ips"][name] = {"ips" => elastic_ips.shift(job["instances"])}
20
+ end
21
+
22
+ elastic_ip_specs.each do |name, job|
23
+ if job["dns_record"]
24
+ say "adding A record for #{job["dns_record"]}.#{config["vpc"]["domain"]}"
25
+ route53.add_record(
26
+ job["dns_record"],
27
+ config["vpc"]["domain"],
28
+ receipt["elastic_ips"][name]["ips"],
29
+ {ttl: job["ttl"]}
30
+ ) # shouldn't have to get domain from config["vpc"]["domain"]; should use config["name"]
31
+ receipt["elastic_ips"][name]["dns_record"] = job["dns_record"]
32
+ end
33
+ end
34
+ ensure
35
+ save_receipt("aws_route53_receipt", receipt)
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ class CreateRdsDbs < Bosh::Aws::Migration
2
+ include Bosh::Aws::MigrationHelper
3
+
4
+ def execute
5
+ if !config["rds"]
6
+ say "rds not set in config. Skipping"
7
+ return
8
+ end
9
+
10
+ vpc_receipt = load_receipt("aws_vpc_receipt")
11
+ db_names = %w(ccdb uaadb)
12
+ db_configs = config['rds'].select {|c| db_names.include?(c['instance']) }
13
+ RdsDb.aws_rds = rds
14
+ dbs = []
15
+
16
+ begin
17
+ db_configs.each do |rds_db_conf|
18
+ rds_args = { vpc_receipt: vpc_receipt, rds_db_conf: rds_db_conf }
19
+ rds_db = RdsDb.new(rds_args)
20
+ dbs << rds_db
21
+ rds_db.create!
22
+ end
23
+
24
+ if RdsDb.was_rds_eventually_available?
25
+ dbs.each { |db| db.update_receipt }
26
+ else
27
+ err "RDS was not available within 60 minutes, giving up"
28
+ end
29
+
30
+ ensure
31
+ save_receipt("aws_rds_receipt", RdsDb.receipt)
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,4 @@
1
+ class CreateS3 < Bosh::Aws::Migration
2
+ def execute
3
+ end
4
+ end
@@ -0,0 +1,33 @@
1
+ class CreateMoreUniqueS3Buckets < Bosh::Aws::Migration
2
+ def s3_safe_full_domain_name
3
+ config['vpc']['domain'].gsub(".","-")
4
+ end
5
+
6
+ def old_prefix
7
+ config['name']
8
+ end
9
+
10
+ def buckets
11
+ {
12
+ "#{s3_safe_full_domain_name}-bosh-blobstore" => "#{old_prefix}-bosh-blobstore",
13
+ "#{s3_safe_full_domain_name}-bosh-artifacts" => "#{old_prefix}-bosh-artifacts"
14
+ }
15
+ end
16
+
17
+ def execute
18
+ return if s3_safe_full_domain_name == old_prefix
19
+
20
+ buckets.each_key do |bucket|
21
+ say "creating bucket #{bucket}"
22
+ s3.create_bucket(bucket)
23
+ end
24
+
25
+ buckets.each_pair do |new_bucket, old_bucket|
26
+ next unless s3.bucket_exists?(old_bucket)
27
+ say "moving contents of #{old_bucket} to #{new_bucket}"
28
+ s3.move_bucket(old_bucket, new_bucket)
29
+ say "deleting bucket #{old_bucket}"
30
+ s3.delete_bucket(old_bucket)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ class CreateBoshRdsDb < Bosh::Aws::Migration
2
+ include Bosh::Aws::MigrationHelper
3
+
4
+ def execute
5
+ vpc_receipt = load_receipt("aws_vpc_receipt")
6
+ db_names = %w(bosh)
7
+ db_configs = config['rds'].select {|c| db_names.include?(c['instance']) }
8
+ RdsDb.aws_rds = rds
9
+ dbs = []
10
+
11
+ begin
12
+ db_configs.each do |rds_db_conf|
13
+ rds_args = { vpc_receipt: vpc_receipt, rds_db_conf: rds_db_conf }
14
+ rds_db = RdsDb.new(rds_args)
15
+ dbs << rds_db
16
+ rds_db.create!
17
+ end
18
+
19
+ if RdsDb.was_rds_eventually_available?
20
+ dbs.each { |db| db.update_receipt }
21
+ else
22
+ err "RDS was not available within 60 minutes, giving up"
23
+ end
24
+
25
+ ensure
26
+ save_receipt("aws_rds_bosh_receipt", RdsDb.receipt)
27
+ end
28
+ end
29
+
30
+ end