convox_installer 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea8a81c025b1a5046d3145beeee5cba92f8448cc8751182d911f3548b289c31a
4
- data.tar.gz: 8eb61f167e06eb67bcd86eada0196d138995b3e61b237ce04f11891f6eb1426c
3
+ metadata.gz: c08b32666153594de1c3464ab4c8ea4f324952115facc72fc159d75de7d1a85e
4
+ data.tar.gz: 2f162d039ab30ebea6ecd8086bc88b30da9c50234c614594c43725036f75f2cb
5
5
  SHA512:
6
- metadata.gz: db7f9e671230b4054a888397461056af9f8ee2d631e0d05fb4eda32a138ae947e7f7fdee8706ea3b9b695254d9fa8b5c2971222a68d8ba4ad8a1326917357f65
7
- data.tar.gz: 8dd7d82786491eca18253d6dc405675fbe6c188c0276878ed352e3f9c17770aca9a4906b8819d061dd6940a203832e0808e9f1aa8427bddc9505d89974f39c69
6
+ metadata.gz: cdaf7159e5bebdde39ffed648fab4be85c5d2a556818b30ec8587ba52e920de44c09434edd654e894501ecb8a68c756c1c64e9de8939412d320dc753ab156163
7
+ data.tar.gz: 219b697d883f91bd173e214402af2d3f5ec988881a025e894f4e3aafef1970af61a1bb2905b886fac437788a18812f9dbbc1e6307aa2d80f1997fdc0d800f0be
data/README.md CHANGED
@@ -8,7 +8,6 @@ This gem provides a DSL so that you can write a script that walks your users thr
8
8
 
9
9
  - MacOS
10
10
  - Convox v3 CLI
11
- - Runtime integration installed in your AWS account. See: https://docs.convox.com/getting-started/introduction/
12
11
 
13
12
  _Please let us know if you need to run this script on Linux. Linux support should not be too difficult to implement, but unfortunately we probably won't be able to support Windows._
14
13
 
@@ -27,10 +26,12 @@ We have successfully set up a number of test and production deployments using th
27
26
  - Idempotent. If this script crashes, you can restart it and it will pick up
28
27
  where it left off. Every step looks up the existing state, and only makes a change
29
28
  if things are not yet set up (or out of sync).
30
- - Ensures that the `convox` and `aws` CLI tools are installed
29
+ - Ensures that the `convox` and `terraform` CLI tools are installed
31
30
  - Wraps the `convox` CLI and parses JSON output from API calls
32
- - Add n Docker Repository (e.g. ECR registry)
31
+ - Add a Docker Repository (e.g. ECR registry)
33
32
  - Set up an S3 bucket with an optional CORS policy
33
+ - Set up an RDS database (Postgres)
34
+ - Set up an Elasticache cluster (Redis)
34
35
 
35
36
  ## Introduction
36
37
 
@@ -147,7 +148,7 @@ Shows a heading and optional details.
147
148
 
148
149
  #### `ensure_requirements!`
149
150
 
150
- Makes sure that the `convox` and `aws` CLI tools are installed on this system. If not, shows installation instructions and exits.
151
+ Makes sure that the `convox` and `terraform` CLI tools are installed on this system. If not, shows installation instructions and exits.
151
152
 
152
153
  #### `prompt_for_config`
153
154
 
@@ -256,20 +257,17 @@ Adds an RDS database to your Terraform config.
256
257
  - `database_instance_class` _(default: 'db.t3.medium')_
257
258
  - `database_multi_az` _(default: true)_
258
259
 
259
- #### `add_add_elasticache_cluster`
260
+ #### `add_elasticache_cluster`
260
261
 
261
262
  Adds an Elasticache cluster to your Terraform config.
262
263
 
263
264
  - **Optional Config:**
264
265
  - `engine` _(default: 'redis')_
265
- - `engine_version` _(default: '6.2.5')_
266
- - `node_type` _(default: 'cache.m3.medium')_
267
- - `database_instance_class` _(default: 'db.t3.medium')_
266
+ - `engine_version` _(default: '6.x')_
267
+ - `node_type` _(default: 'cache.t3.medium')_
268
268
  - `num_cache_nodes` _(default: 1)_
269
269
  - `port` _(default: 6379)_
270
270
 
271
- _IMPORTANT: Make sure you specify a full version string (e.g. `6.2.5`), and not a partial version (e.g. `6.2`.) A partial version will cause Terraform to delete and recreate the cluster on every run._
272
-
273
271
  #### `apply_terraform_update!`
274
272
 
275
273
  Runs `terraform apply -auto-approve` to apply any changes to your Terraform configuration (add new resources, etc.)
@@ -9,6 +9,7 @@
9
9
  # gem "convox_installer"
10
10
  # end
11
11
 
12
+ require 'English'
12
13
  $LOAD_PATH << File.expand_path('../lib', __dir__)
13
14
  require 'pry-byebug'
14
15
 
@@ -99,54 +100,138 @@ config = prompt_for_config
99
100
 
100
101
  backup_convox_host_and_rack
101
102
  install_convox
102
-
103
- validate_convox_auth_and_write_host!
103
+ validate_convox_rack_and_write_current!
104
104
  validate_convox_rack_api!
105
105
 
106
106
  create_convox_app!
107
107
  set_default_app_for_directory!
108
108
  add_docker_registry!
109
- create_s3_bucket!
110
109
 
111
- puts '=> Generating secret keys for authentication sessions and encryption...'
112
- secret_key_base = SecureRandom.hex(64)
113
- data_encryption_key = SecureRandom.hex(32)
110
+ add_s3_bucket
111
+ add_rds_database
112
+ add_elasticache_cluster
113
+
114
+ apply_terraform_update!
115
+
116
+ unless config[:sidekiq_cloudwatch_iam_credentials]
117
+ logger.info "Looking up IAM user for Sidekiq CloudWatch metrics (#{config.fetch(:sidekiq_cloudwatch_iam_username)})..."
118
+
119
+ aws_cli_credentials = "AWS_ACCESS_KEY_ID=#{config.fetch(:aws_access_key_id)} " \
120
+ "AWS_SECRET_ACCESS_KEY=#{config.fetch(:aws_secret_access_key)}"
121
+ `#{aws_cli_credentials} aws iam get-user \
122
+ --user-name #{config.fetch(:sidekiq_cloudwatch_iam_username)} 2>/dev/null`
123
+ unless $CHILD_STATUS.success?
124
+ logger.info "Creating IAM user: #{config.fetch(:sidekiq_cloudwatch_iam_username)} with CloudWatchAgentServerPolicy..."
125
+ # IAM user needs the CloudWatchAgentServerPolicy policy
126
+ `#{aws_cli_credentials} aws iam create-user \
127
+ --user-name #{config.fetch(:sidekiq_cloudwatch_iam_username)}`
128
+ unless $CHILD_STATUS.success?
129
+ raise "Sorry, something went wrong while creating the #{config.fetch(:sidekiq_cloudwatch_iam_username)} IAM user!"
130
+ end
131
+
132
+ logger.info 'Attaching CloudWatchAgentServerPolicy...'
133
+ `#{aws_cli_credentials} aws iam attach-user-policy \
134
+ --user-name #{config.fetch(:sidekiq_cloudwatch_iam_username)} \
135
+ --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy`
136
+ unless $CHILD_STATUS.success?
137
+ raise 'Sorry, something went wrong while attaching the CloudWatchAgentServerPolicy policy!'
138
+ end
139
+ end
140
+ logger.info "Creating IAM access token for #{config.fetch(:sidekiq_cloudwatch_iam_username)}..."
141
+
142
+ create_access_key_output_json = `#{aws_cli_credentials} aws iam create-access-key \
143
+ --user-name #{config.fetch(:sidekiq_cloudwatch_iam_username)}`
144
+ unless $CHILD_STATUS.success?
145
+ raise "Sorry, something went wrong while creating the access token for #{config.fetch(:sidekiq_cloudwatch_iam_username)}!"
146
+ end
147
+
148
+ config[:sidekiq_cloudwatch_iam_credentials] =
149
+ JSON.parse(create_access_key_output_json)['AccessKey']
114
150
 
115
- puts "======> Default domain: #{default_service_domain_name}"
116
- puts ' You can use this as a CNAME record after configuring a domain in convox.yml'
117
- puts ' (Note: SSL will be configured automatically.)'
151
+ # Save credentials in the cached config file
152
+ File.open('./.installer_config.json', 'w') do |f|
153
+ f.puts(JSON.pretty_generate(config: config))
154
+ end
155
+ end
118
156
 
119
- puts '=> Setting environment variables to configure the application...'
157
+ logger.info "======> Default domain: #{default_service_domain_name}"
158
+ logger.info ' You can use this as a CNAME record after configuring a domain in convox.yml'
159
+ logger.info ' (Note: SSL will be configured automatically.)'
120
160
 
121
- env = {
122
- 'HEALTH_CHECK_PATH' => MINIMAL_HEALTH_CHECK_PATH,
123
- 'DOMAIN_NAME' => default_service_domain_name,
161
+ logger.info 'Checking convox env...'
162
+ convox_env_output = `convox env --rack #{config.fetch(:stack_name)}`
163
+ raise 'Error running convox env' unless $CHILD_STATUS.success?
164
+
165
+ convox_env = begin
166
+ convox_env_output.split("\n").map { |s| s.split('=', 2) }.to_h
167
+ rescue StandardError
168
+ {}
169
+ end
170
+
171
+ # Add database and redis
172
+ desired_env = {
173
+ 'DATABASE_URL' => rds_details[:postgres_url],
174
+ 'REDIS_URL' => elasticache_details[:redis_url],
124
175
  'AWS_ACCESS_KEY_ID' => s3_bucket_details.fetch(:access_key_id),
125
176
  'AWS_ACCESS_KEY_SECRET' => s3_bucket_details.fetch(:secret_access_key),
126
177
  'AWS_UPLOADS_S3_BUCKET' => s3_bucket_details.fetch(:name),
127
178
  'AWS_UPLOADS_S3_REGION' => config.fetch(:aws_region),
128
- 'SECRET_KEY_BASE' => secret_key_base,
129
- 'DATA_ENCRYPTION_KEY' => data_encryption_key,
179
+ 'SECRET_KEY_BASE' => config.fetch(:secret_key_base),
180
+ 'SUBMISSION_DATA_ENCRYPTION_KEY' => config.fetch(:data_encryption_key),
130
181
  'ADMIN_NAME' => 'Admin',
131
182
  'ADMIN_EMAIL' => config.fetch(:admin_email),
132
- 'ADMIN_PASSWORD' => config.fetch(:admin_password)
183
+ 'ADMIN_PASSWORD' => config.fetch(:admin_password),
184
+ 'DOCSPRING_LICENSE' => config.fetch(:docspring_license),
185
+ 'DISABLE_EMAILS' => 'true'
133
186
  }
134
187
 
135
- env_command_params = env.map { |k, v| "#{k}=\"#{v}\"" }.join(' ')
136
- run_convox_command! "env set #{env_command_params}"
188
+ # Only set health check path and domain if it's not already present.
189
+ desired_env['HEALTH_CHECK_PATH'] = MINIMAL_HEALTH_CHECK_PATH if convox_env['HEALTH_CHECK_PATH'].nil?
190
+ desired_env['DOMAIN_NAME'] = default_service_domain_name if convox_env['DOMAIN_NAME'].nil?
191
+
192
+ updated_keys = []
193
+ desired_env.each_key do |key|
194
+ updated_keys << key if convox_env[key] != desired_env[key]
195
+ end
196
+
197
+ if updated_keys.none?
198
+ logger.info '=> Convox env has already been configured.'
199
+ logger.info ' You can update this by running: convox env set ...'
200
+ else
201
+ logger.info "=> Setting environment variables to configure DocSpring: #{updated_keys.join(', ')}"
202
+ env_command_params = desired_env.map { |k, v| "#{k}=\"#{v}\"" }.join(' ')
203
+ run_convox_command! "env set #{env_command_params}"
204
+ end
205
+
206
+ # If we are already using the complete health check path, then we can skip the rest.
207
+ if convox_env['HEALTH_CHECK_PATH'] == COMPLETE_HEALTH_CHECK_PATH
208
+ logger.info 'DocSpring is already set up and running.'
209
+ else
210
+ logger.info 'Checking convox processes...'
211
+ convox_processes = `convox ps --rack #{config.fetch(:stack_name)}`
212
+ if convox_processes.include?('web') && convox_processes.include?('worker')
213
+ logger.info '=> Initial deploy for DocSpring Enterprise is already done.'
214
+ else
215
+ logger.info '=> Initial deploy for DocSpring Enterprise...'
216
+ logger.info '-----> Documentation: https://docs.convox.com/deployment/deploying-changes/'
217
+ run_convox_command! 'deploy'
218
+ end
219
+
220
+ logger.info '=> Ensuring the DocSpring application container can boot successfully...'
221
+ run_convox_command! 'run command ./bin/smoke_test'
137
222
 
138
- puts '=> Initial deploy...'
139
- puts '-----> Documentation: https://docs.convox.com/deployment/deploying-changes/'
140
- run_convox_command! 'deploy --wait'
223
+ logger.info '=> Setting up the DocSpring database...'
224
+ run_convox_command! 'run command rake db:create db:migrate db:seed'
141
225
 
142
- puts '=> Setting up the database...'
143
- run_convox_command! 'run web rake db:create db:migrate db:seed'
226
+ logger.info '=> Checking Postgres, Redis, Rails cache, S3 uploads, Sidekiq job processing...'
227
+ run_convox_command! 'run command rake tests:health_check'
144
228
 
145
- puts '=> Updating the health check path to include database tests...'
146
- run_convox_command! "env set --promote --wait HEALTH_CHECK_PATH=#{COMPLETE_HEALTH_CHECK_PATH}"
229
+ logger.info '=> Updating the health check path to include database tests...'
230
+ run_convox_command! "env set --promote HEALTH_CHECK_PATH=#{COMPLETE_HEALTH_CHECK_PATH}"
231
+ end
147
232
 
148
233
  puts
149
- puts 'All done!'
234
+ logger.info 'All done!'
150
235
  puts
151
236
  puts "You can now visit #{default_service_domain_name} and sign in with:"
152
237
  puts
@@ -166,24 +251,26 @@ puts
166
251
  puts 'To learn more about the convox CLI, run: convox --help'
167
252
  puts
168
253
  puts ' * View the Convox documentation: https://docs.convox.com/'
254
+ puts ' * View the DocSpring documentation: https://docspring.com/docs/'
169
255
  puts
170
256
  puts
171
- puts 'To completely uninstall Convox from your AWS account,'
257
+ puts 'To completely uninstall Convox and DocSpring from your AWS account,'
172
258
  puts 'run the following steps (in this order):'
173
259
  puts
174
260
  puts ' 1) Disable "Termination Protection" for any resource where it was enabled.'
175
261
  puts
176
- puts " 2) Delete all files from the #{config.fetch(:s3_bucket_name)} S3 bucket:"
262
+ puts " 2) Delete all files from the #{s3_bucket_details.fetch(:name)} S3 bucket:"
177
263
  puts
178
264
  puts " export AWS_ACCESS_KEY_ID=#{config.fetch(:aws_access_key_id)}"
179
265
  puts " export AWS_SECRET_ACCESS_KEY=#{config.fetch(:aws_secret_access_key)}"
180
266
  puts " aws s3 rm s3://#{s3_bucket_details.fetch(:name)} --recursive"
181
267
  puts
182
- puts " 3) Delete the #{config.fetch(:s3_bucket_name)} S3 bucket:"
268
+ puts ' 3) Uninstall Convox (deletes all AWS resources via Terraform):'
183
269
  puts
184
- puts " convox rack resources delete #{config.fetch(:s3_bucket_name)} --wait"
270
+ puts " convox rack uninstall #{config.fetch(:stack_name)}"
185
271
  puts
186
- puts ' 4) Uninstall Convox (deletes all CloudFormation stacks and AWS resources):'
187
272
  puts
188
- puts " convox rack uninstall aws #{config.fetch(:stack_name)}"
273
+ puts '------------------------------------------------------------------------------------'
274
+ puts 'Thank you for using DocSpring! Please contact support@docspring.com if you need any help.'
275
+ puts '------------------------------------------------------------------------------------'
189
276
  puts
data/lib/convox/client.rb CHANGED
@@ -112,9 +112,11 @@ module Convox
112
112
  'AWS_ACCESS_KEY_ID' => config.fetch(:aws_access_key_id),
113
113
  'AWS_SECRET_ACCESS_KEY' => config.fetch(:aws_secret_access_key)
114
114
  }
115
+ # Set proxy_protocol=true by default to forward client IPs
115
116
  command = %(rack install aws \
116
117
  "#{config.fetch(:stack_name)}" \
117
118
  "node_type=#{config.fetch(:instance_type)}" \
119
+ "proxy_protocol=true" \
118
120
  "region=#{config.fetch(:aws_region)}")
119
121
  # us-east constantly has problems with the us-east-1c AZ:
120
122
  # "Cannot create cluster 'ds-enterprise-cx3' because us-east-1c, the targeted
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConvoxInstaller
4
- VERSION = '3.0.0'
4
+ VERSION = '3.0.1'
5
5
  end
@@ -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
 
@@ -141,7 +141,7 @@ RSpec.describe Convox::Client do
141
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
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: convox_installer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Form Applications Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-04 00:00:00.000000000 Z
11
+ date: 2022-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
132
  - !ruby/object:Gem::Version
133
133
  version: '0'
134
134
  requirements: []
135
- rubygems_version: 3.2.11
135
+ rubygems_version: 3.3.7
136
136
  signing_key:
137
137
  specification_version: 4
138
138
  summary: Build a Convox installation workflow