convox_installer 2.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/convox/client.rb CHANGED
@@ -4,12 +4,20 @@ require 'logger'
4
4
  require 'json'
5
5
  require 'fileutils'
6
6
  require 'rubygems'
7
+ require 'os'
8
+ require 'erb'
7
9
 
8
10
  module Convox
9
11
  class Client
10
- CONVOX_DIR = File.expand_path('~/.convox').freeze
11
- AUTH_FILE = File.join(CONVOX_DIR, 'auth')
12
- HOST_FILE = File.join(CONVOX_DIR, 'host')
12
+ CONVOX_CONFIG_DIR = if OS.mac?
13
+ # Convox v3 moved this to ~/Library/Preferences/convox/ on Mac
14
+ File.expand_path('~/Library/Preferences/convox').freeze
15
+ else
16
+ File.expand_path('~/.convox').freeze
17
+ end
18
+
19
+ AUTH_FILE = File.join(CONVOX_CONFIG_DIR, 'auth')
20
+ CURRENT_FILE = File.join(CONVOX_CONFIG_DIR, 'current')
13
21
 
14
22
  attr_accessor :logger, :config
15
23
 
@@ -57,17 +65,21 @@ module Convox
57
65
  @config = options[:config] || {}
58
66
  end
59
67
 
68
+ # Convox v3 creates a folder for each rack for the Terraform config
69
+ def rack_dir
70
+ stack_name = config.fetch(:stack_name)
71
+ File.join(CONVOX_CONFIG_DIR, 'racks', stack_name)
72
+ end
73
+
60
74
  def backup_convox_host_and_rack
61
- FileUtils.mkdir_p CONVOX_DIR
75
+ FileUtils.mkdir_p CONVOX_CONFIG_DIR
62
76
 
63
- %w[host rack].each do |f|
64
- path = File.join(CONVOX_DIR, f)
65
- next unless File.exist?(path)
77
+ path = File.join(CONVOX_CONFIG_DIR, 'current')
78
+ return unless File.exist?(path)
66
79
 
67
- bak_file = "#{path}.bak"
68
- logger.info "Moving existing #{path} to #{bak_file}..."
69
- FileUtils.mv(path, bak_file)
70
- end
80
+ bak_file = "#{path}.bak"
81
+ logger.info "Moving existing #{path} to #{bak_file}..."
82
+ FileUtils.mv(path, bak_file)
71
83
  end
72
84
 
73
85
  def install_convox
@@ -76,8 +88,12 @@ module Convox
76
88
  stack_name = config.fetch(:stack_name)
77
89
 
78
90
  if rack_already_installed?
79
- logger.info "There is already a Convox stack named #{stack_name} " \
80
- "in the #{region} AWS region. Using this rack. "
91
+ logger.info "There is already a Convox rack named #{stack_name}. Using this rack."
92
+ logger.debug 'If you need to start over, you can run: ' \
93
+ "convox rack uninstall #{stack_name} " \
94
+ '(Make sure you export AWS_ACCESS_KEY_ID and ' \
95
+ "AWS_SECRET_ACCESS_KEY first.)\n" \
96
+ "If this fails, you can try deleting the rack directory: rm -rf #{rack_dir}"
81
97
  return true
82
98
  end
83
99
 
@@ -96,12 +112,22 @@ module Convox
96
112
  'AWS_ACCESS_KEY_ID' => config.fetch(:aws_access_key_id),
97
113
  'AWS_SECRET_ACCESS_KEY' => config.fetch(:aws_secret_access_key)
98
114
  }
115
+ # Set proxy_protocol=true by default to forward client IPs
99
116
  command = %(rack install aws \
100
- --name "#{config.fetch(:stack_name)}" \
101
- "InstanceType=#{config.fetch(:instance_type)}" \
102
- "BuildInstance=")
117
+ "#{config.fetch(:stack_name)}" \
118
+ "node_type=#{config.fetch(:instance_type)}" \
119
+ "proxy_protocol=true" \
120
+ "region=#{config.fetch(:aws_region)}")
121
+ # us-east constantly has problems with the us-east-1c AZ:
122
+ # "Cannot create cluster 'ds-enterprise-cx3' because us-east-1c, the targeted
123
+ # availability zone, does not currently have sufficient capacity to support the cluster.
124
+ # Retry and choose from these availability zones:
125
+ # us-east-1a, us-east-1b, us-east-1d, us-east-1e, us-east-1f
126
+ if config.fetch(:aws_region) == 'us-east-1'
127
+ command += ' "availability_zones=us-east-1a,us-east-1b,us-east-1d,us-east-1e,us-east-1f"'
128
+ end
103
129
 
104
- run_convox_command!(command, env)
130
+ run_convox_command!(command, env, rack_arg: false)
105
131
  end
106
132
 
107
133
  def rack_already_installed?
@@ -109,66 +135,51 @@ module Convox
109
135
 
110
136
  return unless File.exist?(AUTH_FILE)
111
137
 
112
- region = config.fetch(:aws_region)
138
+ # region = config.fetch(:aws_region)
113
139
  stack_name = config.fetch(:stack_name)
140
+ return true if File.exist?(rack_dir)
114
141
 
115
- auth.each do |host, _password|
116
- if host.match?(/^#{stack_name}-\d+\.#{region}\.elb\.amazonaws\.com$/)
117
- return true
118
- end
142
+ auth.each do |rack_name, _password|
143
+ return true if rack_name == stack_name
119
144
  end
120
145
  false
121
146
  end
122
147
 
123
- def validate_convox_auth_and_write_host!
148
+ # Auth for a detached rack is not saved in the auth file anymore.
149
+ # It can be found in the terraform state:
150
+ # ~/Library/Preferences/convox/racks/ds-enterprise-cx3/terraform.tfstate
151
+ # Under outputs/api/value. The API URL contains the convox username and API token as basic auth.
152
+ def validate_convox_rack_and_write_current!
124
153
  require_config(%i[aws_region stack_name])
125
154
 
126
- unless File.exist?(AUTH_FILE)
127
- raise "Could not find auth file at #{AUTH_FILE}!"
155
+ unless rack_already_installed?
156
+ raise "Could not find rack terraform directory at: #{rack_dir}"
128
157
  end
129
158
 
130
- region = config.fetch(:aws_region)
131
- stack = config.fetch(:stack_name)
132
-
133
- match_count = 0
134
- matching_host = nil
135
- auth.each do |host, _password|
136
- if host.match?(/^#{stack}-\d+\.#{region}\.elb\.amazonaws\.com$/)
137
- matching_host = host
138
- match_count += 1
139
- end
140
- end
141
-
142
- if match_count == 1
143
- write_host(matching_host)
144
- return matching_host
145
- end
146
-
147
- error_message = if match_count > 1
148
- 'Found multiple matching hosts for '
149
- else
150
- 'Could not find matching authentication for '
151
- end
152
- error_message += "region: #{region}, stack: #{stack}"
153
- raise error_message
159
+ # Tells the Convox CLI to use our terraform stack
160
+ stack_name = config.fetch(:stack_name)
161
+ write_current(stack_name)
162
+ stack_name
154
163
  end
155
164
 
156
- def write_host(host)
157
- logger.debug "Setting convox host to #{host} (in #{HOST_FILE})..."
158
- File.open(HOST_FILE, 'w') { |f| f.puts host }
165
+ def write_current(rack_name)
166
+ logger.debug "Setting convox rack to #{rack_name} (in #{CURRENT_FILE})..."
167
+ current_hash = { name: rack_name, type: 'terraform' }
168
+ File.open(CURRENT_FILE, 'w') { |f| f.puts current_hash.to_json }
159
169
  end
160
170
 
161
- def validate_convox_rack!
171
+ def validate_convox_rack_api!
162
172
  require_config(%i[
163
173
  aws_region
164
174
  stack_name
165
175
  instance_type
166
176
  ])
167
177
  logger.debug 'Validating that convox rack has the correct attributes...'
178
+ # Convox 3 racks no longer return info about region or type. (These are blank strings.)
168
179
  {
169
180
  provider: 'aws',
170
- region: config.fetch(:aws_region),
171
- type: config.fetch(:instance_type),
181
+ # region: config.fetch(:aws_region),
182
+ # type: config.fetch(:instance_type),
172
183
  name: config.fetch(:stack_name)
173
184
  }.each do |k, v|
174
185
  convox_value = convox_rack_data[k.to_s]
@@ -184,8 +195,22 @@ module Convox
184
195
  def convox_rack_data
185
196
  @convox_rack_data ||= begin
186
197
  logger.debug 'Fetching convox rack attributes...'
187
- convox_output = `convox api get /system`
188
- raise 'convox command failed!' unless $CHILD_STATUS.success?
198
+ command = "convox api get /system --rack #{config.fetch(:stack_name)}"
199
+ logger.debug "+ #{command}"
200
+ # It can take a while for the API to be ready.
201
+ start_time = Time.now
202
+ convox_output = nil
203
+ loop do
204
+ convox_output = `#{command}`
205
+ break if $CHILD_STATUS.success?
206
+
207
+ if Time.now - start_time > 360
208
+ raise 'Could not connect to Convox rack API!'
209
+ end
210
+
211
+ logger.debug 'Waiting for Convox rack API to be ready... (can take a few minutes)'
212
+ sleep 5
213
+ end
189
214
 
190
215
  JSON.parse(convox_output)
191
216
  end
@@ -199,9 +224,10 @@ module Convox
199
224
 
200
225
  logger.info "Creating app: #{app_name}..."
201
226
  logger.info '=> Documentation: ' \
202
- 'https://docs.convox.com/deployment/creating-an-application'
227
+ 'https://docs.convox.com/reference/cli/apps/'
203
228
 
204
- run_convox_command! "apps create #{app_name} --wait"
229
+ # NOTE: --wait flags were removed in Convox 3. It now waits by default.
230
+ run_convox_command! "apps create #{app_name}"
205
231
 
206
232
  retries = 0
207
233
  loop do
@@ -232,7 +258,7 @@ module Convox
232
258
  app_name = config.fetch(:convox_app_name)
233
259
 
234
260
  logger.debug "Looking for existing #{app_name} app..."
235
- convox_output = `convox api get /apps`
261
+ convox_output = `convox api get /apps --rack #{config.fetch(:stack_name)}`
236
262
  raise 'convox command failed!' unless $CHILD_STATUS.success?
237
263
 
238
264
  apps = JSON.parse(convox_output)
@@ -247,128 +273,117 @@ module Convox
247
273
  end
248
274
 
249
275
  # Create the s3 bucket, and also apply a CORS configuration
250
- def create_s3_bucket!
276
+ # Convox v3 update - They removed support for S3 resources, so we have to do
277
+ # in terraform now (which is actually pretty nice!)
278
+ def add_s3_bucket
251
279
  require_config(%i[s3_bucket_name])
252
- bucket_name = config.fetch(:s3_bucket_name)
253
- if s3_bucket_exists?
254
- logger.info "#{bucket_name} S3 bucket already exists!"
255
- else
256
- logger.info "Creating S3 bucket resource (#{bucket_name})..."
257
- run_convox_command! 'rack resources create s3 ' \
258
- "--name \"#{bucket_name}\" " \
259
- '--wait'
260
-
261
- retries = 0
262
- loop do
263
- break if s3_bucket_exists?
264
280
 
265
- if retries > 10
266
- raise "Something went wrong while creating the #{bucket_name} S3 bucket! " \
267
- '(Please wait a few moments and then restart the installation script.)'
268
- end
269
- logger.debug 'Waiting for S3 bucket to be ready...'
270
- sleep 3
271
- retries += 1
272
- end
273
-
274
- logger.debug '=> S3 bucket created!'
281
+ unless config.key? :s3_bucket_cors_rule
282
+ logger.debug 'No CORS rule provided in config: s3_bucket_cors_rule (optional)'
283
+ return
275
284
  end
276
285
 
277
- set_s3_bucket_cors_policy
286
+ write_terraform_template('s3_bucket')
278
287
  end
279
288
 
280
- def s3_bucket_exists?
281
- require_config(%i[s3_bucket_name])
282
- bucket_name = config.fetch(:s3_bucket_name)
283
- logger.debug "Looking up S3 bucket resource: #{bucket_name}"
284
- `convox api get /resources/#{bucket_name} 2>/dev/null`
285
- $CHILD_STATUS.success?
289
+ def add_rds_database
290
+ require_config(%i[database_username database_password])
291
+ write_terraform_template('rds')
286
292
  end
287
293
 
288
- def s3_bucket_details
289
- require_config(%i[s3_bucket_name])
290
- @s3_bucket_details ||= begin
291
- bucket_name = config.fetch(:s3_bucket_name)
292
- logger.debug "Fetching S3 bucket resource details for #{bucket_name}..."
293
-
294
- response = `convox api get /resources/#{bucket_name}`
295
- raise 'convox command failed!' unless $CHILD_STATUS.success?
296
-
297
- bucket_data = JSON.parse(response)
298
- s3_url = bucket_data['url']
299
- matches = s3_url.match(
300
- %r{^s3://(?<access_key_id>[^:]*):(?<secret_access_key>[^@]*)@(?<bucket_name>.*)$}
301
- )
302
-
303
- match_keys = %i[access_key_id secret_access_key bucket_name]
304
- unless matches && match_keys.all? { |k| matches[k].present? }
305
- raise "#{s3_url} is an invalid S3 URL!"
306
- end
294
+ def add_elasticache_cluster
295
+ write_terraform_template('elasticache')
296
+ end
307
297
 
308
- {
309
- access_key_id: matches[:access_key_id],
310
- secret_access_key: matches[:secret_access_key],
311
- name: matches[:bucket_name]
312
- }
298
+ def write_terraform_template(name)
299
+ template_path = File.join(__dir__, "../../terraform/#{name}.tf.erb")
300
+ unless File.exist?(template_path)
301
+ raise "Could not find terraform template at: #{template_path}"
313
302
  end
303
+
304
+ template = ERB.new(File.read(template_path))
305
+ template_output = template.result(binding)
306
+
307
+ tf_file_path = File.join(rack_dir, "#{name}.tf")
308
+ logger.debug "Writing terraform config to #{tf_file_path}..."
309
+ File.open(tf_file_path, 'w') { |f| f.puts template_output }
314
310
  end
315
311
 
316
- def set_s3_bucket_cors_policy
317
- require_config(%i[aws_access_key_id aws_secret_access_key])
318
- access_key_id = config.fetch(:aws_access_key_id)
319
- secret_access_key = config.fetch(:aws_secret_access_key)
312
+ def apply_terraform_update!
313
+ logger.info 'Applying terraform update...'
314
+ command = if ENV['DEBUG_TERRAFORM']
315
+ 'terraform plan'
316
+ else
317
+ 'terraform apply -auto-approve'
318
+ end
319
+ logger.debug "+ #{command}"
320
320
 
321
- unless config.key? :s3_bucket_cors_policy
322
- logger.debug 'No CORS policy provided in config: s3_bucket_cors_policy'
323
- return
321
+ env = {
322
+ 'AWS_ACCESS_KEY_ID' => config.fetch(:aws_access_key_id),
323
+ 'AWS_SECRET_ACCESS_KEY' => config.fetch(:aws_secret_access_key)
324
+ }
325
+ Dir.chdir(rack_dir) do
326
+ system env, command
327
+ raise 'terraform command failed!' unless $CHILD_STATUS.success?
324
328
  end
325
- cors_policy_string = config.fetch(:s3_bucket_cors_policy)
326
-
327
- bucket_name = s3_bucket_details[:name]
328
-
329
- logger.debug "Looking up existing CORS policy for #{bucket_name}"
330
- existing_cors_policy_string =
331
- `AWS_ACCESS_KEY_ID=#{access_key_id} \
332
- AWS_SECRET_ACCESS_KEY=#{secret_access_key} \
333
- aws s3api get-bucket-cors --bucket #{bucket_name} 2>/dev/null`
334
- if $CHILD_STATUS.success? && existing_cors_policy_string.present?
335
- # Sort all the nested arrays so that the equality operator works
336
- existing_cors_policy = JSON.parse(existing_cors_policy_string)
337
- cors_policy_json = JSON.parse(cors_policy_string)
338
- [existing_cors_policy, cors_policy_json].each do |policy_json|
339
- next unless policy_json.is_a?(Hash) && policy_json['CORSRules']
340
-
341
- policy_json['CORSRules'].each do |rule|
342
- rule['AllowedHeaders']&.sort!
343
- rule['AllowedMethods']&.sort!
344
- rule['AllowedOrigins']&.sort!
345
- end
346
- end
329
+ end
347
330
 
348
- if existing_cors_policy == cors_policy_json
349
- logger.debug "=> CORS policy is already up to date for #{bucket_name}."
350
- return
351
- end
331
+ def terraform_state
332
+ tf_state_file = File.join(rack_dir, 'terraform.tfstate')
333
+ JSON.parse(File.read(tf_state_file))
334
+ end
335
+
336
+ def terraform_resource(resource_type, resource_name)
337
+ resource = terraform_state['resources'].find do |resource|
338
+ resource['type'] == resource_type && resource['name'] == resource_name
352
339
  end
340
+ return resource if resource
353
341
 
354
- begin
355
- logger.info "Setting CORS policy for #{bucket_name}..."
342
+ raise "Could not find #{resource_type} resource named #{resource_name} in terraform state!"
343
+ end
356
344
 
357
- File.open('cors-policy.json', 'w') { |f| f.puts cors_policy_string }
345
+ def s3_bucket_details
346
+ require_config(%i[s3_bucket_name])
358
347
 
359
- `AWS_ACCESS_KEY_ID=#{access_key_id} \
360
- AWS_SECRET_ACCESS_KEY=#{secret_access_key} \
361
- aws s3api put-bucket-cors \
362
- --bucket #{bucket_name} \
363
- --cors-configuration "file://cors-policy.json"`
364
- unless $CHILD_STATUS.success?
365
- raise 'Something went wrong while setting the S3 bucket CORS policy!'
366
- end
348
+ s3_bucket = terraform_resource('aws_s3_bucket', 'docs_s3_bucket')
349
+ bucket_attributes = s3_bucket['instances'][0]['attributes']
350
+ access_key = terraform_resource('aws_iam_access_key', 'docspring_user_access_key')
351
+ key_attributes = access_key['instances'][0]['attributes']
367
352
 
368
- logger.info "=> Successfully set CORS policy for #{bucket_name}."
369
- ensure
370
- FileUtils.rm_f 'cors-policy.json'
371
- end
353
+ {
354
+ access_key_id: key_attributes['id'],
355
+ secret_access_key: key_attributes['secret'],
356
+ name: bucket_attributes['bucket']
357
+ }
358
+ end
359
+
360
+ def rds_details
361
+ require_config(%i[database_username database_password])
362
+
363
+ database = terraform_resource('aws_db_instance', 'rds_database')
364
+ database_attributes = database['instances'][0]['attributes']
365
+
366
+ username = database_attributes['username']
367
+ password = database_attributes['password']
368
+ endpoint = database_attributes['endpoint']
369
+ postgres_url = "postgres://#{username}:#{password}@#{endpoint}/app"
370
+ {
371
+ postgres_url: postgres_url
372
+ }
373
+ end
374
+
375
+ def elasticache_details
376
+ require_config(%i[s3_bucket_name])
377
+
378
+ # Just ensure that the bucket exists in the state
379
+ cluster = terraform_resource('aws_elasticache_cluster', 'elasticache_cluster')
380
+ cluster_attributes = cluster['instances'][0]['attributes']
381
+ cache_node = cluster_attributes['cache_nodes'][0]
382
+ redis_url = "redis://#{cache_node['address']}:#{cache_node['port']}/0"
383
+
384
+ {
385
+ redis_url: redis_url
386
+ }
372
387
  end
373
388
 
374
389
  def add_docker_registry!
@@ -377,7 +392,7 @@ module Convox
377
392
  registry_url = config.fetch(:docker_registry_url)
378
393
 
379
394
  logger.debug 'Looking up existing Docker registries...'
380
- registries_response = `convox api get /registries`
395
+ registries_response = `convox api get /registries --rack #{config.fetch(:stack_name)}`
381
396
  unless $CHILD_STATUS.success?
382
397
  raise 'Something went wrong while fetching the list of registries!'
383
398
  end
@@ -391,36 +406,37 @@ module Convox
391
406
 
392
407
  logger.info "Adding Docker Registry: #{registry_url}..."
393
408
  logger.info '=> Documentation: ' \
394
- 'https://docs.convox.com/deployment/private-registries'
409
+ 'https://docs.convox.com/configuration/private-registries/'
395
410
 
396
411
  `convox registries add "#{registry_url}" \
397
412
  "#{config.fetch(:docker_registry_username)}" \
398
- "#{config.fetch(:docker_registry_password)}"`
413
+ "#{config.fetch(:docker_registry_password)}" \
414
+ --rack #{config.fetch(:stack_name)}`
399
415
  return if $CHILD_STATUS.success?
400
416
 
401
417
  raise "Something went wrong while adding the #{registry_url} registry!"
402
418
  end
403
419
 
404
420
  def default_service_domain_name
405
- require_config(%i[convox_app_name default_service])
406
-
407
- @default_service_domain_name ||= begin
408
- convox_domain = convox_rack_data['domain']
409
- elb_name_and_region = convox_domain[/([^.]*\.[^.]*)\..*/, 1]
410
- unless elb_name_and_region.present?
411
- raise 'Something went wrong while parsing the ELB name and region! ' \
412
- "(#{elb_name_and_region})"
413
- end
414
- app = config.fetch(:convox_app_name)
415
- service = config.fetch(:default_service)
421
+ require_config(%i[convox_app_name])
416
422
 
417
- # Need to return downcase host so that `config.hosts` works with Rails applications
418
- "#{app}-#{service}.#{elb_name_and_region}.convox.site".downcase
419
- end
423
+ app_name = config.fetch(:convox_app_name)
424
+ default_service = config[:default_service] || 'web'
425
+
426
+ convox_api_url = terraform_state['outputs']['api']['value']
427
+ convox_router_host = convox_api_url.split('@').last.sub(/^api\./, '')
428
+
429
+ [default_service, app_name, convox_router_host].join('.').downcase
420
430
  end
421
431
 
422
- def run_convox_command!(cmd, env = {})
432
+ def run_convox_command!(cmd, env = {}, rack_arg: true)
433
+ # Always include the rack as an argument, to
434
+ # make sure that 'convox switch' doesn't affect any commands
423
435
  command = "convox #{cmd}"
436
+ if rack_arg
437
+ command = "#{command} --rack #{config.fetch(:stack_name)}"
438
+ end
439
+ logger.debug "+ #{command}"
424
440
  system env, command
425
441
  raise "Error running: #{command}" unless $CHILD_STATUS.success?
426
442
  end
@@ -38,6 +38,12 @@ module ConvoxInstaller
38
38
  {
39
39
  key: :aws_secret_access_key,
40
40
  title: 'AWS Secret Access Key'
41
+ },
42
+ # Short random ID used to ensure that resources are always unique
43
+ {
44
+ key: :random_id,
45
+ value: -> { SecureRandom.hex(4) },
46
+ hidden: true
41
47
  }
42
48
  ].freeze
43
49
 
@@ -76,6 +82,8 @@ module ConvoxInstaller
76
82
 
77
83
  highline.say 'Please double check all of these configuration details.'
78
84
 
85
+ break if ENV['AUTOSTART_CONVOX_INSTALLATION']
86
+
79
87
  agree = highline.agree(
80
88
  'Would you like to start the Convox installation?' \
81
89
  " (press 'n' to correct any settings)"
@@ -34,6 +34,14 @@ module ConvoxInstaller
34
34
  }
35
35
  end
36
36
 
37
+ unless command_present? 'terraform'
38
+ @missing_packages << {
39
+ name: 'terraform',
40
+ brew: 'terraform',
41
+ docs: 'https://learn.hashicorp.com/tutorials/terraform/install-cli'
42
+ }
43
+ end
44
+
37
45
  if @missing_packages.any?
38
46
  logger.error 'This script requires the convox and AWS CLI tools.'
39
47
  if OS.mac?
@@ -49,12 +57,15 @@ module ConvoxInstaller
49
57
  end
50
58
 
51
59
  client = Convox::Client.new
52
- return if client.convox_2_cli?
60
+ if client.convox_3_cli?
61
+ logger.debug "=> Convox CLI is version 3.x.x (#{client.cli_version_string})"
62
+ return
63
+ end
53
64
 
54
- logger.error 'This script requires Convox CLI version 2.x.x. ' \
65
+ logger.error 'This script requires Convox CLI version 3.x.x. ' \
55
66
  "Your Convox CLI version is: #{client.cli_version_string}"
56
- logger.error 'Please follow the instructions here to downgrade your ' \
57
- 'Convox CLI version: https://docsv2.convox.com/introduction/installation'
67
+ logger.error "Please run 'brew update convox' or follow the instructions " \
68
+ 'at https://docs.convox.com/getting-started/introduction'
58
69
  quit!
59
70
  end
60
71
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConvoxInstaller
4
- VERSION = '2.0.0'
4
+ VERSION = '3.0.1'
5
5
  end
@@ -32,18 +32,24 @@ module ConvoxInstaller
32
32
  %w[
33
33
  backup_convox_host_and_rack
34
34
  install_convox
35
- validate_convox_auth_and_write_host!
36
- validate_convox_rack!
35
+ validate_convox_rack_and_write_current!
36
+ validate_convox_rack_api!
37
37
  convox_rack_data
38
38
  create_convox_app!
39
39
  set_default_app_for_directory!
40
- create_s3_bucket!
41
- set_s3_bucket_cors_policy
40
+ add_s3_bucket
41
+ add_rds_database
42
+ add_elasticache_cluster
43
+ apply_terraform_update!
44
+ terraform_state
42
45
  s3_bucket_details
46
+ elasticache_details
47
+ rds_details
43
48
  add_docker_registry!
44
49
  default_service_domain_name
45
50
  run_convox_command!
46
51
  logger
52
+ rack_already_installed?
47
53
  ].each do |method|
48
54
  define_method(method) do |*args|
49
55
  client.send(method, *args)
@@ -100,11 +100,11 @@ RSpec.describe Convox::Client do
100
100
  end
101
101
  end
102
102
 
103
- describe '#validate_convox_auth_and_write_host!' do
103
+ describe '#validate_convox_rack_and_write_current!' do
104
104
  it 'requires the correct config vars' do
105
105
  client = described_class.new
106
106
  expect do
107
- client.validate_convox_auth_and_write_host!
107
+ client.validate_convox_rack_and_write_current!
108
108
  end.to raise_error('aws_region is missing from the config!')
109
109
  end
110
110
 
@@ -120,7 +120,7 @@ RSpec.describe Convox::Client do
120
120
  ).and_return(false)
121
121
 
122
122
  expect do
123
- client.validate_convox_auth_and_write_host!
123
+ client.validate_convox_rack_and_write_current!
124
124
  end.to raise_error(/Could not find auth file at /)
125
125
  end
126
126
 
@@ -138,10 +138,10 @@ RSpec.describe Convox::Client do
138
138
  stack_name: 'convox-test'
139
139
  }
140
140
  )
141
- expect(client).to receive(:write_host).with(
141
+ expect(client).to receive(:write_current).with(
142
142
  'convox-test-697645520.us-west-2.elb.amazonaws.com'
143
143
  )
144
- expect(client.validate_convox_auth_and_write_host!).to(
144
+ expect(client.validate_convox_rack_and_write_current!).to(
145
145
  eq('convox-test-697645520.us-west-2.elb.amazonaws.com')
146
146
  )
147
147
  end
@@ -161,7 +161,7 @@ RSpec.describe Convox::Client do
161
161
  }
162
162
  )
163
163
  expect do
164
- client.validate_convox_auth_and_write_host!
164
+ client.validate_convox_rack_and_write_current!
165
165
  end.to raise_error('Could not find matching authentication for ' \
166
166
  'region: us-east-1, stack: convox-test')
167
167
  end
@@ -182,7 +182,7 @@ RSpec.describe Convox::Client do
182
182
  }
183
183
  )
184
184
  expect do
185
- client.validate_convox_auth_and_write_host!
185
+ client.validate_convox_rack_and_write_current!
186
186
  end.to raise_error('Found multiple matching hosts for ' \
187
187
  'region: us-west-2, stack: convox-test')
188
188
  end