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.
- data/lib/bosh/cli/commands/aws.rb +464 -0
- data/lib/bosh_cli_plugin_aws/aws_config.rb +141 -0
- data/lib/bosh_cli_plugin_aws/aws_provider.rb +53 -0
- data/lib/bosh_cli_plugin_aws/bat_manifest.rb +40 -0
- data/lib/bosh_cli_plugin_aws/bootstrap.rb +31 -0
- data/lib/bosh_cli_plugin_aws/bosh_bootstrap.rb +158 -0
- data/lib/bosh_cli_plugin_aws/bosh_manifest.rb +71 -0
- data/lib/bosh_cli_plugin_aws/ec2.rb +265 -0
- data/lib/bosh_cli_plugin_aws/elb.rb +132 -0
- data/lib/bosh_cli_plugin_aws/micro_bosh_bootstrap.rb +64 -0
- data/lib/bosh_cli_plugin_aws/microbosh_manifest.rb +117 -0
- data/lib/bosh_cli_plugin_aws/migration.rb +40 -0
- data/lib/bosh_cli_plugin_aws/migration_helper.rb +150 -0
- data/lib/bosh_cli_plugin_aws/migrator.rb +137 -0
- data/lib/bosh_cli_plugin_aws/rds.rb +182 -0
- data/lib/bosh_cli_plugin_aws/route53.rb +103 -0
- data/lib/bosh_cli_plugin_aws/s3.rb +93 -0
- data/lib/bosh_cli_plugin_aws/version.rb +5 -0
- data/lib/bosh_cli_plugin_aws/vpc.rb +181 -0
- data/lib/bosh_cli_plugin_aws.rb +31 -0
- data/migrations/20130412000811_create_key_pairs.rb +8 -0
- data/migrations/20130412004642_create_vpc.rb +65 -0
- data/migrations/20130412181302_create_route53_records.rb +37 -0
- data/migrations/20130412183544_create_rds_dbs.rb +35 -0
- data/migrations/20130412192351_create_s3.rb +4 -0
- data/migrations/20130529212130_create_more_unique_s3_buckets.rb +33 -0
- data/migrations/20130531180445_create_bosh_rds_db.rb +30 -0
- data/migrations/20130826150635_update_elb_for_websockets.rb +97 -0
- data/migrations/20130827000001_add_secondary_az_to_vpc.rb +34 -0
- data/templates/aws_configuration_template.yml.erb +187 -0
- data/templates/aws_migration.erb +5 -0
- data/templates/aws_migration_spec.erb +12 -0
- data/templates/bat.yml.erb +84 -0
- data/templates/bosh.yml.erb +198 -0
- data/templates/micro_bosh.yml.erb +82 -0
- 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,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,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,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
|