elastic_beans 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b231170798c366604081d7d0800c0c332a386d6
4
- data.tar.gz: 661c9aca9b2ae4fdc6402cd02c5b3d37c4f62d76
3
+ metadata.gz: 661efbe2cb8fd10a68a49a3ebc7899ec3b30b61a
4
+ data.tar.gz: 6dee6beefb1f0dcd55f5cf7c8f7f73898c9e1432
5
5
  SHA512:
6
- metadata.gz: 71da843ae45cfac1cf6fa2061df76383849d16cdb359c1ff7145975c25042ca8985d7501b2e57d09d2968d4b8b0246cf40f89ef73d98b6a165b4cb15ae17f8fa
7
- data.tar.gz: 928d9e71798950eb693d0a9ad4a9ac720ca48e56de71b8cf074d0fd409e2c957119d2dd83fcc6dd8b757ef122e08bda185ff25fad6dacddedcf5db7d327bbfb0
6
+ metadata.gz: 63dc0a28f1482b67a2d96fa6edefd65f768acbbe377357acec498bc7b34dafe9242f7ef4c365c82c15d24c80ea6e81a5d6c41cc92e85d3c39002cc969e2f04fc
7
+ data.tar.gz: ca7b8ffd98f6218a0bb935aea9bfce0cf3d3e804467a709e20d9d0adf83f313ba606ff9057aebffdb2e7dbf80d42e360f2689f0bdc6cc07f8ac5f0ddc6e2de84
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /.elasticbeanstalk
data/README.md CHANGED
@@ -67,8 +67,7 @@ AWS SDK clients must be passed into Elastic Beans constructors.
67
67
  ### Periodic tasks
68
68
 
69
69
  Elastic Beanstalk [supports periodic tasks][periodic] by sending a POST request to an endpoint of your application.
70
- Elastic Beans includes a middleware that can convert specially-crafted paths into commands and enqueue them for execution.
71
- The middleware only accepts localhost requests from `aws-sqsd`.
70
+ Elastic Beans includes a middleware that can convert specially-crafted paths into commands and enqueue them for execution. "Specially-crafted" meaning with /exec at the front, as the cron.yaml section below explains. The middleware only accepts localhost requests from `aws-sqsd`.
72
71
 
73
72
  [periodic]: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-tiers.html#worker-periodictasks
74
73
 
data/exe/beans CHANGED
@@ -1,228 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "aws-sdk"
4
- require "thor"
5
- require "elastic_beans"
6
- require "elastic_beans/error"
7
- require "elastic_beans/command"
8
- require "elastic_beans/ui"
9
-
10
- class ElasticBeans::CLI < Thor
11
- APPLICATION_DESC = "The name of the Elastic Beanstalk application and CloudFormation stack that contains application settings"
12
-
13
- class_option :verbose, type: :boolean, aliases: %w(-v)
14
-
15
- desc ElasticBeans::Command::Configure::USAGE, ElasticBeans::Command::Configure::DESC
16
- long_desc ElasticBeans::Command::Configure::LONG_DESC
17
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
18
- option :network, aliases: %w(-n), required: true, desc: "The name of the CloudFormation stack that contains networking settings"
19
- option :database_url, aliases: %w(-d), desc: "The DATABASE_URL for the Rails application"
20
- option :image_id, aliases: %w(-i), desc: "A custom AMI to use instead of the default Ruby Elastic Beanstalk AMI"
21
- option :instance_type, aliases: %w(-t), desc: "A default instance type to use for all environments instead of c4.large"
22
- option :keypair, aliases: %w(-k), desc: "Required on first run. The EC2 keypair to use for Elastic Beanstalk instances"
23
- option :logging_endpoint, aliases: %w(-l), desc: "An HTTP endpoint that can receive logs from one-off commands"
24
- option :public_key, aliases: %w(-p), desc: "For end-to-end encryption. The public key of the SSL certificate the ELB will verify to communicate with your Rails app"
25
- option :secret_key_base, aliases: %w(-b), desc: "The SECRET_KEY_BASE for the Rails application"
26
- option :ssl_certificate_arn, aliases: %w(-s), desc: "The ARN of the SSL server certificate stored in IAM to attach to the ELB"
27
- def configure
28
- @verbose = options[:verbose]
29
- ElasticBeans::Command::Configure.new(
30
- database_url: options[:database_url],
31
- image_id: options[:image_id],
32
- instance_type: options[:instance_type],
33
- keypair: options[:keypair],
34
- logging_endpoint: options[:logging_endpoint],
35
- public_key: options[:public_key],
36
- secret_key_base: options[:secret_key_base],
37
- ssl_certificate_arn: options[:ssl_certificate_arn],
38
- application: application(name: options[:application]),
39
- network: network(stack_name: options[:network]),
40
- elastic_beanstalk: elastic_beanstalk_client,
41
- iam: iam_client,
42
- ui: ui,
43
- ).run
44
- rescue StandardError => e
45
- error(e)
46
- end
47
-
48
- desc ElasticBeans::Command::Create::USAGE, ElasticBeans::Command::Create::DESC
49
- long_desc ElasticBeans::Command::Create::LONG_DESC
50
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
51
- option :dns, aliases: %w(-d), desc: "A Route53 DNS entry to create or update for a new webserver environment"
52
- option :queue, aliases: %w(-q), desc: "The name of the queue a new worker environment should listen to, e.g. `default`"
53
- option :tags, type: :hash, default: {}, desc: "EC2 tags to apply to the new environment as a Hash, e.g. `--tags=Environment:development Team:mine`"
54
- def create(environment_type)
55
- @verbose = options[:verbose]
56
- ElasticBeans::Command::Create.new(
57
- environment_type: environment_type,
58
- dns: options[:dns],
59
- queue: options[:queue],
60
- tags: options[:tags],
61
- application: application(name: options[:application]),
62
- elastic_beanstalk: elastic_beanstalk_client,
63
- route53: route53_client,
64
- s3: s3_client,
65
- ui: ui,
66
- ).run
67
- rescue StandardError => e
68
- error(e)
69
- end
70
-
71
- desc ElasticBeans::Command::Deploy::USAGE, ElasticBeans::Command::Deploy::DESC
72
- long_desc ElasticBeans::Command::Deploy::LONG_DESC
73
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
74
- def deploy
75
- @verbose = options[:verbose]
76
- ElasticBeans::Command::Deploy.new(
77
- application: application(
78
- name: options[:application],
79
- ),
80
- elastic_beanstalk: elastic_beanstalk_client,
81
- s3: s3_client,
82
- ui: ui,
83
- ).run
84
- rescue StandardError => e
85
- error(e)
86
- end
87
-
88
- desc ElasticBeans::Command::Exec::USAGE, ElasticBeans::Command::Exec::DESC
89
- long_desc ElasticBeans::Command::Exec::LONG_DESC
90
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
91
- def exec(*command_parts)
92
- @verbose = options[:verbose]
93
- ElasticBeans::Command::Exec.new(
94
- application: application(
95
- name: options[:application],
96
- ),
97
- sqs: sqs_client,
98
- ui: ui,
99
- ).run(*command_parts)
100
- rescue StandardError => e
101
- error(e)
102
- end
103
-
104
- desc ElasticBeans::Command::Scale::USAGE, ElasticBeans::Command::Scale::DESC
105
- long_desc ElasticBeans::Command::Scale::LONG_DESC
106
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
107
- option :minimum, aliases: %w(-i --min), required: true, desc: "The minimum number of healthy instances to keep"
108
- option :maximum, aliases: %w(-m --max), required: true, desc: "The maximum number of healthy instances to keep"
109
- option :queue, aliases: %w(-q), desc: "The name of the queue to identify the worker environment to scale, e.g. `default`"
110
- def scale(environment_type)
111
- @verbose = options[:verbose]
112
- ElasticBeans::Command::Scale.new(
113
- application: application(
114
- name: options[:application],
115
- ),
116
- minimum: options[:minimum],
117
- maximum: options[:maximum],
118
- queue: options[:queue],
119
- elastic_beanstalk: elastic_beanstalk_client,
120
- ui: ui,
121
- ).run(environment_type)
122
- rescue StandardError => e
123
- error(e)
124
- end
125
-
126
- desc ElasticBeans::Command::SetEnv::USAGE, ElasticBeans::Command::SetEnv::DESC
127
- long_desc ElasticBeans::Command::SetEnv::LONG_DESC
128
- option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
129
- def setenv(*env_pairs)
130
- @verbose = options[:verbose]
131
- ElasticBeans::Command::SetEnv.new(
132
- application: application(
133
- name: options[:application],
134
- ),
135
- ui: ui,
136
- ).run(*env_pairs)
137
- rescue StandardError => e
138
- error(e)
139
- end
140
-
141
- desc "talk", ""
142
- def talk
143
- ElasticBeans::Command::Talk.new(ui: ui).run
144
- end
145
-
146
- map %w[--version] => :__print_version
147
- desc "--version", "Print the version and exit"
148
- def __print_version
149
- ElasticBeans::Command::Version.new(ui: ui).run
150
- end
151
-
152
- private
153
-
154
- def application(
155
- name:,
156
- cloudformation: cloudformation_client,
157
- elastic_beanstalk: elastic_beanstalk_client,
158
- s3: s3_client
159
- )
160
- @application ||= ElasticBeans::Application.new(
161
- name: name,
162
- cloudformation: cloudformation,
163
- elastic_beanstalk: elastic_beanstalk,
164
- s3: s3,
165
- )
166
- end
167
-
168
- def cloudformation_client
169
- ::Aws::CloudFormation::Client.new
170
- end
171
-
172
- def elastic_beanstalk_client
173
- ::Aws::ElasticBeanstalk::Client.new
174
- end
175
-
176
- def error(e)
177
- ui.debug { e.inspect }
178
- ui.debug { e.backtrace }
179
-
180
- case e
181
- when ElasticBeans::Error
182
- ui.error(e.message)
183
- when ::Aws::Errors::MissingCredentialsError
184
- ui.error("Missing AWS credentials, please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and try again.")
185
- else
186
- raise e
187
- end
188
-
189
- exit 1
190
- end
191
-
192
- def iam_client
193
- ::Aws::IAM::Client.new
194
- end
195
-
196
- def network(stack_name:, cloudformation: cloudformation_client)
197
- @network ||= ElasticBeans::Network.new(
198
- stack_name: stack_name,
199
- cloudformation: cloudformation,
200
- )
201
- end
202
-
203
- def route53_client
204
- ::Aws::Route53::Client.new
205
- end
206
-
207
- def s3_client
208
- ::Aws::S3::Client.new
209
- end
210
-
211
- def sqs_client
212
- ::Aws::SQS::Client.new
213
- end
214
-
215
- def ui
216
- ElasticBeans::UI.new(verbose: verbose?)
217
- end
218
-
219
- def verbose?
220
- @verbose
221
- end
222
-
223
- def self.exit_on_failure?
224
- true
225
- end
226
- end
3
+ require "elastic_beans/cli"
227
4
 
228
5
  ElasticBeans::CLI.start(ARGV)
@@ -0,0 +1,226 @@
1
+ require "aws-sdk"
2
+ require "thor"
3
+ require "elastic_beans"
4
+ require "elastic_beans/error"
5
+ require "elastic_beans/command"
6
+ require "elastic_beans/ui"
7
+
8
+ # :nodoc: all
9
+ # @!visibility private
10
+ class ElasticBeans::CLI < Thor
11
+ APPLICATION_DESC = "The name of the Elastic Beanstalk application and CloudFormation stack that contains application settings"
12
+
13
+ class_option :verbose, type: :boolean, aliases: %w(-v)
14
+
15
+ desc ElasticBeans::Command::Configure::USAGE, ElasticBeans::Command::Configure::DESC
16
+ long_desc ElasticBeans::Command::Configure::LONG_DESC
17
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
18
+ option :network, aliases: %w(-n), required: true, desc: "The name of the CloudFormation stack that contains networking settings"
19
+ option :database_url, aliases: %w(-d), desc: "The DATABASE_URL for the Rails application"
20
+ option :image_id, aliases: %w(-i), desc: "A custom AMI to use instead of the default Ruby Elastic Beanstalk AMI"
21
+ option :instance_type, aliases: %w(-t), desc: "A default instance type to use for all environments instead of c4.large"
22
+ option :keypair, aliases: %w(-k), desc: "Required on first run. The EC2 keypair to use for Elastic Beanstalk instances"
23
+ option :logging_endpoint, aliases: %w(-l), desc: "An HTTP endpoint that can receive logs from one-off commands"
24
+ option :public_key, aliases: %w(-p), desc: "For end-to-end encryption. The public key of the SSL certificate the ELB will verify to communicate with your Rails app"
25
+ option :secret_key_base, aliases: %w(-b), desc: "The SECRET_KEY_BASE for the Rails application"
26
+ option :ssl_certificate_arn, aliases: %w(-s), desc: "The ARN of the SSL server certificate stored in IAM to attach to the ELB"
27
+ def configure
28
+ @verbose = options[:verbose]
29
+ ElasticBeans::Command::Configure.new(
30
+ database_url: options[:database_url],
31
+ image_id: options[:image_id],
32
+ instance_type: options[:instance_type],
33
+ keypair: options[:keypair],
34
+ logging_endpoint: options[:logging_endpoint],
35
+ public_key: options[:public_key],
36
+ secret_key_base: options[:secret_key_base],
37
+ ssl_certificate_arn: options[:ssl_certificate_arn],
38
+ application: application(name: options[:application]),
39
+ network: network(stack_name: options[:network]),
40
+ elastic_beanstalk: elastic_beanstalk_client,
41
+ iam: iam_client,
42
+ ui: ui,
43
+ ).run
44
+ rescue StandardError => e
45
+ error(e)
46
+ end
47
+
48
+ desc ElasticBeans::Command::Create::USAGE, ElasticBeans::Command::Create::DESC
49
+ long_desc ElasticBeans::Command::Create::LONG_DESC
50
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
51
+ option :dns, aliases: %w(-d), desc: "A Route53 DNS entry to create or update for a new webserver environment"
52
+ option :queue, aliases: %w(-q), desc: "The name of the queue a new worker environment should listen to, e.g. `default`"
53
+ option :tags, type: :hash, default: {}, desc: "EC2 tags to apply to the new environment as a Hash, e.g. `--tags=Environment:development Team:mine`"
54
+ def create(environment_type)
55
+ @verbose = options[:verbose]
56
+ ElasticBeans::Command::Create.new(
57
+ environment_type: environment_type,
58
+ dns: options[:dns],
59
+ queue: options[:queue],
60
+ tags: options[:tags],
61
+ application: application(name: options[:application]),
62
+ elastic_beanstalk: elastic_beanstalk_client,
63
+ route53: route53_client,
64
+ s3: s3_client,
65
+ ui: ui,
66
+ ).run
67
+ rescue StandardError => e
68
+ error(e)
69
+ end
70
+
71
+ desc ElasticBeans::Command::Deploy::USAGE, ElasticBeans::Command::Deploy::DESC
72
+ long_desc ElasticBeans::Command::Deploy::LONG_DESC
73
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
74
+ def deploy
75
+ @verbose = options[:verbose]
76
+ ElasticBeans::Command::Deploy.new(
77
+ application: application(
78
+ name: options[:application],
79
+ ),
80
+ elastic_beanstalk: elastic_beanstalk_client,
81
+ s3: s3_client,
82
+ ui: ui,
83
+ ).run
84
+ rescue StandardError => e
85
+ error(e)
86
+ end
87
+
88
+ desc ElasticBeans::Command::Exec::USAGE, ElasticBeans::Command::Exec::DESC
89
+ long_desc ElasticBeans::Command::Exec::LONG_DESC
90
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
91
+ def exec(*command_parts)
92
+ @verbose = options[:verbose]
93
+ ElasticBeans::Command::Exec.new(
94
+ application: application(
95
+ name: options[:application],
96
+ ),
97
+ sqs: sqs_client,
98
+ ui: ui,
99
+ ).run(*command_parts)
100
+ rescue StandardError => e
101
+ error(e)
102
+ end
103
+
104
+ desc ElasticBeans::Command::Scale::USAGE, ElasticBeans::Command::Scale::DESC
105
+ long_desc ElasticBeans::Command::Scale::LONG_DESC
106
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
107
+ option :minimum, aliases: %w(-i --min), required: true, desc: "The minimum number of healthy instances to keep"
108
+ option :maximum, aliases: %w(-m --max), required: true, desc: "The maximum number of healthy instances to keep"
109
+ option :queue, aliases: %w(-q), desc: "The name of the queue to identify the worker environment to scale, e.g. `default`"
110
+ def scale(environment_type)
111
+ @verbose = options[:verbose]
112
+ ElasticBeans::Command::Scale.new(
113
+ application: application(
114
+ name: options[:application],
115
+ ),
116
+ minimum: options[:minimum],
117
+ maximum: options[:maximum],
118
+ queue: options[:queue],
119
+ elastic_beanstalk: elastic_beanstalk_client,
120
+ ui: ui,
121
+ ).run(environment_type)
122
+ rescue StandardError => e
123
+ error(e)
124
+ end
125
+
126
+ desc ElasticBeans::Command::SetEnv::USAGE, ElasticBeans::Command::SetEnv::DESC
127
+ long_desc ElasticBeans::Command::SetEnv::LONG_DESC
128
+ option :application, aliases: %w(-a), required: true, desc: APPLICATION_DESC
129
+ def setenv(*env_pairs)
130
+ @verbose = options[:verbose]
131
+ ElasticBeans::Command::SetEnv.new(
132
+ application: application(
133
+ name: options[:application],
134
+ ),
135
+ ui: ui,
136
+ ).run(*env_pairs)
137
+ rescue StandardError => e
138
+ error(e)
139
+ end
140
+
141
+ desc "talk", ""
142
+ def talk
143
+ ElasticBeans::Command::Talk.new(ui: ui).run
144
+ end
145
+
146
+ map %w[--version] => :__print_version
147
+ desc "--version", "Print the version and exit"
148
+ def __print_version
149
+ ElasticBeans::Command::Version.new(ui: ui).run
150
+ end
151
+
152
+ private
153
+
154
+ def application(
155
+ name:,
156
+ cloudformation: cloudformation_client,
157
+ elastic_beanstalk: elastic_beanstalk_client,
158
+ s3: s3_client
159
+ )
160
+ @application ||= ElasticBeans::Application.new(
161
+ name: name,
162
+ cloudformation: cloudformation,
163
+ elastic_beanstalk: elastic_beanstalk,
164
+ s3: s3,
165
+ )
166
+ end
167
+
168
+ def cloudformation_client
169
+ ::Aws::CloudFormation::Client.new
170
+ end
171
+
172
+ def elastic_beanstalk_client
173
+ ::Aws::ElasticBeanstalk::Client.new
174
+ end
175
+
176
+ def error(e)
177
+ ui.debug { e.inspect }
178
+ ui.debug { e.backtrace }
179
+
180
+ case e
181
+ when ElasticBeans::Error
182
+ ui.error(e.message)
183
+ when ::Aws::Errors::MissingCredentialsError
184
+ ui.error("Missing AWS credentials, please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and try again.")
185
+ else
186
+ raise e
187
+ end
188
+
189
+ exit 1
190
+ end
191
+
192
+ def iam_client
193
+ ::Aws::IAM::Client.new
194
+ end
195
+
196
+ def network(stack_name:, cloudformation: cloudformation_client)
197
+ @network ||= ElasticBeans::Network.new(
198
+ stack_name: stack_name,
199
+ cloudformation: cloudformation,
200
+ )
201
+ end
202
+
203
+ def route53_client
204
+ ::Aws::Route53::Client.new
205
+ end
206
+
207
+ def s3_client
208
+ ::Aws::S3::Client.new
209
+ end
210
+
211
+ def sqs_client
212
+ ::Aws::SQS::Client.new
213
+ end
214
+
215
+ def ui
216
+ ElasticBeans::UI.new(verbose: verbose?)
217
+ end
218
+
219
+ def verbose?
220
+ @verbose
221
+ end
222
+
223
+ def self.exit_on_failure?
224
+ true
225
+ end
226
+ end
@@ -0,0 +1,14 @@
1
+ require "stringio"
2
+ require "elastic_beans/cli"
3
+
4
+ # :nodoc: all
5
+ # @!visibility private
6
+ class ElasticBeans::CLI::StringShell < Thor::Shell::Basic
7
+ attr_reader :stdout, :stderr
8
+
9
+ def initialize(*args, stdout: StringIO.new, stderr: StringIO.new)
10
+ super(*args)
11
+ @stdout = stdout
12
+ @stderr = stderr
13
+ end
14
+ end
@@ -52,7 +52,8 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
52
52
  raise EnvironmentsNotReady.new(environments: unready_environments)
53
53
  end
54
54
 
55
- progressbar = ProgressBar.create(title: "Configuring", total: nil, output: ui.stdout)
55
+ config_templates = 4 + application.worker_queues.size
56
+ progressbar = ProgressBar.create(title: "Configuring", total: config_templates, output: ui.stdout)
56
57
  progressbar.log("Updating configuration templates in #{application.name}...")
57
58
  progressbar.log("Updating base configuration template...")
58
59
  base_config = ElasticBeans::ConfigurationTemplate::Base.new(
@@ -135,26 +136,30 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
135
136
  )
136
137
  progressbar.increment
137
138
  end
139
+ progressbar.finish
138
140
 
139
- threads = environments.map { |environment|
140
- progressbar.log("Updating `#{environment.name}'...")
141
- thread = Thread.new do
142
- environment.update_configuration
143
- end
144
- progressbar.increment
145
- thread
146
- }
141
+ if environments.any?
142
+ progressbar = ProgressBar.create(title: "Updating", total: nil, output: ui.stdout)
143
+ threads = environments.map { |environment|
144
+ progressbar.log("Updating `#{environment.name}'...")
145
+ thread = Thread.new do
146
+ environment.update_configuration
147
+ end
148
+ progressbar.increment
149
+ thread
150
+ }
147
151
 
148
- loop do
149
- sleep 1
150
- progressbar.increment
151
- if threads.none?(&:alive?)
152
- progressbar.total = progressbar.progress
153
- break
152
+ loop do
153
+ sleep 0.5
154
+ progressbar.increment
155
+ if threads.none?(&:alive?)
156
+ progressbar.total = progressbar.progress
157
+ break
158
+ end
154
159
  end
155
- end
156
160
 
157
- threads.each(&:join)
161
+ threads.each(&:join)
162
+ end
158
163
  end
159
164
 
160
165
  private
@@ -76,7 +76,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
76
76
  end
77
77
 
78
78
  loop do
79
- sleep 1
79
+ sleep 0.5
80
80
  progressbar.increment
81
81
  if !environment_thread.alive? && !dns_thread.alive?
82
82
  progressbar.total = progressbar.progress
@@ -28,7 +28,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
28
28
  end
29
29
 
30
30
  ui.debug { "Creating application version from code at #{Dir.pwd}..." }
31
- progressbar = ProgressBar.create(title: "Deploying", total: nil, output: ui.stdout)
31
+ progressbar = ProgressBar.create(title: "Uploading", total: nil, output: ui.stdout)
32
32
  version = nil
33
33
  version_thread = Thread.new do
34
34
  version = ElasticBeans::ApplicationVersion.create(
@@ -40,7 +40,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
40
40
  end
41
41
 
42
42
  loop do
43
- sleep 1
43
+ sleep 0.5
44
44
  progressbar.increment
45
45
  if !version_thread.alive?
46
46
  break
@@ -49,6 +49,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
49
49
  version_thread.join
50
50
 
51
51
  progressbar.log("Deploying version #{version} to #{application.name}...")
52
+ progressbar.title = "Deploying"
52
53
  deploy_threads = environments.map { |environment|
53
54
  progressbar.log("Deploying version '#{version}' to environment `#{environment.name}'...")
54
55
  thread = Thread.new do
@@ -59,7 +60,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
59
60
  }
60
61
 
61
62
  loop do
62
- sleep 1
63
+ sleep 0.5
63
64
  progressbar.increment
64
65
  if deploy_threads.none?(&:alive?)
65
66
  progressbar.total = progressbar.progress
@@ -48,7 +48,7 @@ Requires AWS credentials to be set in the environment, i.e. AWS_ACCESS_KEY_ID an
48
48
  }
49
49
 
50
50
  loop do
51
- sleep 1
51
+ sleep 0.5
52
52
  progressbar.increment
53
53
  if threads.none?(&:alive?)
54
54
  progressbar.total = progressbar.progress
@@ -172,14 +172,19 @@ module ElasticBeans
172
172
  end
173
173
 
174
174
  def message
175
- require "elastic_beans/command/configure"
175
+ require "elastic_beans/cli"
176
+ require "elastic_beans/cli/string_shell"
176
177
  msg = <<-MESSAGE
177
178
  Some configuration is missing and must be set before creating or updating an environment.
178
179
  MESSAGE
179
180
  if nested
180
181
  msg << "The error from AWS was \"#{nested.message}\"\n#{msg}\n"
181
182
  else
182
- msg << "Please re-run `#{command_as_string "configure"}`.\n\n#{`#{$0} help configure`}"
183
+ msg << <<-MESSAGE
184
+ Please re-run `#{command_as_string "configure"}`.
185
+
186
+ #{command_help "configure"}"
187
+ MESSAGE
183
188
  end
184
189
  msg
185
190
  end
@@ -61,7 +61,11 @@ module ElasticBeans
61
61
  database_url_setting = template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DATABASE_URL", override: database_url)
62
62
  secret_key_base_setting = template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "SECRET_KEY_BASE", override: secret_key_base)
63
63
  if database_url_setting[:value].nil? || secret_key_base_setting[:value].nil? || keypair_setting[:value].nil?
64
- raise MissingConfigurationError
64
+ raise MissingOptionsError.new(
65
+ database_url: database_url_setting[:value],
66
+ secret_key_base: secret_key_base_setting[:value],
67
+ keypair: keypair_setting[:value],
68
+ )
65
69
  end
66
70
 
67
71
  config_path = "#{application.bucket_name}/#{application.env_vars.s3_key}"
@@ -143,6 +147,38 @@ module ElasticBeans
143
147
  " http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.iam.html"
144
148
  end
145
149
  end
150
+
151
+ # :nodoc: all
152
+ # @!visibility private
153
+ class MissingOptionsError < ElasticBeans::Error
154
+ def initialize(database_url:, secret_key_base:, keypair:)
155
+ @database_url = database_url
156
+ @secret_key_base = secret_key_base
157
+ @keypair = keypair
158
+ end
159
+
160
+ def message
161
+ require "elastic_beans/cli"
162
+ require "elastic_beans/cli/string_shell"
163
+ msg = "Some required options are missing and must be set when configuring an application:\n\n"
164
+ if @database_url.nil?
165
+ msg << "--database-url DATABASE_URL must point to a valid database, and is required for running a Rails application\n"
166
+ end
167
+ if @keypair.nil?
168
+ msg << "--keypair KEYPAIR must be a valid EC2 key pair, and will be used on Elastic Beanstalk instances\n"
169
+ end
170
+ if @secret_key_base.nil?
171
+ msg << "--secret-key-base SECRET_KEY_BASE can be any value, and is required for running a Rails application\n"
172
+ end
173
+ msg << <<-MESSAGE
174
+
175
+ Please re-run `#{command_as_string "configure"}` with these options.
176
+
177
+ #{command_help "configure"}
178
+ MESSAGE
179
+ msg
180
+ end
181
+ end
146
182
  end
147
183
  end
148
184
  end
@@ -50,12 +50,13 @@ module ElasticBeans
50
50
  # @!visibility private
51
51
  class NoEncryptionSettingsError < ElasticBeans::Error
52
52
  def message
53
- require "elastic_beans/command/configure"
53
+ require "elastic_beans/cli"
54
+ require "elastic_beans/cli/string_shell"
54
55
  <<-MESSAGE
55
56
  Missing required end-to-end encryption settings.
56
57
  Please re-run `#{command_as_string "configure"}` and make sure to specify SSL certificate ARN and internal public key.
57
58
 
58
- #{`#{$0} help configure`}
59
+ #{command_help "configure"}
59
60
  MESSAGE
60
61
  end
61
62
  end
@@ -260,7 +260,7 @@ module ElasticBeans
260
260
  status = wait_status[0]
261
261
  health = "Grey"
262
262
  health_status = wait_health_status[0]
263
- Timeout.timeout(1800) do
263
+ Timeout.timeout(3600) do
264
264
  while wait_status.include?(status) || wait_health_status.include?(health_status)
265
265
  sleep 5
266
266
  environment = environment_description
@@ -302,12 +302,13 @@ module ElasticBeans
302
302
  # @!visibility private
303
303
  class MissingConfigurationError < ElasticBeans::Error
304
304
  def message
305
- require "elastic_beans/command/configure"
305
+ require "elastic_beans/cli"
306
+ require "elastic_beans/cli/string_shell"
306
307
  <<-MESSAGE
307
308
  Some configuration is missing and must be set before creating an environment.
308
309
  Please re-run `#{command_as_string "configure"}`.
309
310
 
310
- #{`#{$0} help configure`}
311
+ #{command_help "configure"}
311
312
  MESSAGE
312
313
  end
313
314
  end
@@ -12,5 +12,14 @@ module ElasticBeans
12
12
 
13
13
  "beans #{args}"
14
14
  end
15
+
16
+ def command_help(command)
17
+ require "elastic_beans/cli"
18
+ require "elastic_beans/cli/string_shell"
19
+
20
+ shell = ElasticBeans::CLI::StringShell.new
21
+ ElasticBeans::CLI.command_help(shell, command)
22
+ shell.stdout.string
23
+ end
15
24
  end
16
25
  end
@@ -14,7 +14,7 @@ class Init
14
14
  def self.run(command)
15
15
  init = new
16
16
  unless init.respond_to?(command)
17
- abort "Usage: $0 {start}"
17
+ abort "Usage: #{$0} {start}"
18
18
  end
19
19
  init.send(command)
20
20
  end
@@ -1,3 +1,3 @@
1
1
  module ElasticBeans
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_beans
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Stegman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-15 00:00:00.000000000 Z
11
+ date: 2016-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -160,6 +160,8 @@ files:
160
160
  - lib/elastic_beans/application.rb
161
161
  - lib/elastic_beans/application_version.rb
162
162
  - lib/elastic_beans/aws/cloudformation_stack.rb
163
+ - lib/elastic_beans/cli.rb
164
+ - lib/elastic_beans/cli/string_shell.rb
163
165
  - lib/elastic_beans/command.rb
164
166
  - lib/elastic_beans/command/configure.rb
165
167
  - lib/elastic_beans/command/create.rb