elastic_beans 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +91 -16
  3. data/exe/beans +26 -20
  4. data/lib/elastic_beans/application.rb +33 -1
  5. data/lib/elastic_beans/application_version.rb +18 -3
  6. data/lib/elastic_beans/aws/cloudformation_stack.rb +2 -0
  7. data/lib/elastic_beans/command/configure.rb +12 -18
  8. data/lib/elastic_beans/command/create.rb +8 -4
  9. data/lib/elastic_beans/command/deploy.rb +3 -3
  10. data/lib/elastic_beans/command/exec.rb +4 -3
  11. data/lib/elastic_beans/command/scale.rb +2 -2
  12. data/lib/elastic_beans/command/set_env.rb +4 -3
  13. data/lib/elastic_beans/command/talk.rb +1 -0
  14. data/lib/elastic_beans/command/version.rb +1 -0
  15. data/lib/elastic_beans/command.rb +2 -0
  16. data/lib/elastic_beans/configuration_template/base.rb +12 -2
  17. data/lib/elastic_beans/configuration_template/exec.rb +6 -0
  18. data/lib/elastic_beans/configuration_template/scheduler.rb +4 -0
  19. data/lib/elastic_beans/configuration_template/webserver.rb +11 -4
  20. data/lib/elastic_beans/configuration_template/worker.rb +6 -0
  21. data/lib/elastic_beans/configuration_template.rb +32 -11
  22. data/lib/elastic_beans/dns_entry.rb +2 -0
  23. data/lib/elastic_beans/env_vars.rb +6 -0
  24. data/lib/elastic_beans/environment/exec.rb +13 -4
  25. data/lib/elastic_beans/environment/scheduler.rb +13 -4
  26. data/lib/elastic_beans/environment/webserver.rb +13 -4
  27. data/lib/elastic_beans/environment/worker.rb +15 -4
  28. data/lib/elastic_beans/environment.rb +74 -18
  29. data/lib/elastic_beans/error/environments_not_ready.rb +2 -0
  30. data/lib/elastic_beans/error.rb +1 -0
  31. data/lib/elastic_beans/exec/init.rb +2 -0
  32. data/lib/elastic_beans/exec/sqs_consumer.rb +2 -0
  33. data/lib/elastic_beans/network.rb +1 -0
  34. data/lib/elastic_beans/rack/exec.rb +5 -0
  35. data/lib/elastic_beans/ui.rb +2 -0
  36. data/lib/elastic_beans/version.rb +1 -1
  37. metadata +2 -2
@@ -8,14 +8,28 @@ require "elastic_beans/environment/worker"
8
8
  require "elastic_beans/error"
9
9
 
10
10
  module ElasticBeans
11
+ # An Elastic Beanstalk environment which may or may not exist.
12
+ #
13
+ # This is an abstract class; use the provided factories in this class or use a subclass (contained within this
14
+ # namespace) directly.
11
15
  class Environment
16
+ # :category: Internal
12
17
  TEMPLATE_NAME = "base"
18
+ # :category: Internal
13
19
  TIER_NAME = "Webserver"
20
+ # :category: Internal
14
21
  TIER_TYPE = "Standard"
22
+ # :category: Internal
15
23
  WORKER_TEMPLATE_NAME_PATTERN = /worker-(?<queue>\w+)/
16
24
 
17
25
  attr_reader :name
18
26
 
27
+ # Create a new environment of a particular +type+.
28
+ # See the particular subclass being created for details on arguments.
29
+ # The name of the environment will be the application name, joined with the +type+ (and the queue in the case of a
30
+ # worker).
31
+ #
32
+ # Raises an error if the +type+ is not recognized.
19
33
  def self.new_by_type(type, application:, **args)
20
34
  name = "#{application.name}-#{type}"
21
35
  case type
@@ -33,6 +47,12 @@ module ElasticBeans
33
47
  end
34
48
  end
35
49
 
50
+ # Create a representation of an existing environment.
51
+ # Uses the +environment+ to discover the appropriate type (and queue, in the case of a worker).
52
+ # If the +environment+ type is not recognized, the tier will be inspected. If the tier is worker, then the
53
+ # "default" queue will be assumed.
54
+ #
55
+ # Raises an error if the +environment+ type or tier is not recognized.
36
56
  def self.new_from_existing(environment, application:, **args)
37
57
  app_name_pattern = /#{Regexp.escape(application.name)}/
38
58
  case environment.environment_name
@@ -73,6 +93,11 @@ module ElasticBeans
73
93
  @elastic_beanstalk = elastic_beanstalk
74
94
  end
75
95
 
96
+ # Creates the environment in Elastic Beanstalk.
97
+ # Blocks until the environment is Ready.
98
+ #
99
+ # Raises an error if the configuration template for this environment does not exist.
100
+ # Raises an error if the environment is not healthy.
76
101
  def create(version:, tags: {})
77
102
  begin
78
103
  elastic_beanstalk.describe_configuration_settings(
@@ -104,6 +129,10 @@ module ElasticBeans
104
129
  )
105
130
  end
106
131
 
132
+ # Deploys the specified version label to the environment.
133
+ # Blocks until the environment is Ready.
134
+ #
135
+ # Raises an error if the environment is not healthy.
107
136
  def deploy_version(version_label)
108
137
  elastic_beanstalk.update_environment(
109
138
  environment_name: name,
@@ -118,6 +147,10 @@ module ElasticBeans
118
147
  raise UnhealthyEnvironmentError.new(environment_name: name, cause: e)
119
148
  end
120
149
 
150
+ # Restarts the environment application servers.
151
+ # Blocks until the environment is Ready.
152
+ #
153
+ # Raises an error if the environment is not healthy.
121
154
  def restart
122
155
  elastic_beanstalk.restart_app_server(environment_name: name)
123
156
  wait_environment(wait_status: "Updating", wait_health_status: "Info")
@@ -126,6 +159,10 @@ module ElasticBeans
126
159
  retry
127
160
  end
128
161
 
162
+ # Updates the environment configuration to change the minimum and maximum size of the autoscaling group.
163
+ # Blocks until the environment is Ready.
164
+ #
165
+ # Raises an error if the environment is not healthy.
129
166
  def scale(min_size:, max_size:)
130
167
  option_settings = [
131
168
  {namespace: "aws:autoscaling:asg", option_name: "MinSize", value: min_size},
@@ -137,12 +174,17 @@ module ElasticBeans
137
174
  )
138
175
  wait_environment(wait_status: "Updating", wait_health_status: "Info")
139
176
  rescue ::Aws::ElasticBeanstalk::Errors::InvalidParameterValue
140
- raise MissingEnvironmentError.new(environment_name: name)
177
+ raise MissingEnvironmentError.new(environment: self, application: application)
141
178
  rescue ::Aws::ElasticBeanstalk::Errors::Throttling
142
179
  sleep 5
143
180
  retry
144
181
  end
145
182
 
183
+ # Updates the environment configuration with its configuration template.
184
+ # Handy when the configuration template has been updated and you want those changes to take effect immediately.
185
+ # Blocks until the environment is Ready.
186
+ #
187
+ # Raises an error if the environment is not healthy.
146
188
  def update_configuration
147
189
  elastic_beanstalk.update_environment(
148
190
  environment_name: name,
@@ -151,31 +193,42 @@ module ElasticBeans
151
193
  )
152
194
  wait_environment(wait_status: "Updating", wait_health_status: "Info")
153
195
  rescue ::Aws::ElasticBeanstalk::Errors::InvalidParameterValue
154
- raise MissingEnvironmentError.new(environment_name: name)
196
+ raise MissingEnvironmentError.new(environment: self, application: application)
155
197
  rescue ::Aws::ElasticBeanstalk::Errors::Throttling
156
198
  sleep 5
157
199
  retry
158
200
  end
159
201
 
202
+ # Returns the Elastic Beanstalk CNAME, set for a webserver environment.
203
+ #
204
+ # Raises an error if the environment does not exist.
160
205
  def cname
161
206
  environment = environment_description
162
207
  unless environment
163
- raise MissingEnvironmentError.new(environment_name: name)
208
+ raise MissingEnvironmentError.new(environment: self, application: application)
164
209
  end
165
210
  environment.cname
166
211
  end
167
212
 
213
+ # Returns the status of the environment in Elastic Beanstalk.
214
+ #
215
+ # Raises an error if the environment does not exist.
168
216
  def status
169
217
  environment = environment_description
170
218
  unless environment
171
- raise MissingEnvironmentError.new(environment_name: name)
219
+ raise MissingEnvironmentError.new(environment: self, application: application)
172
220
  end
173
221
  environment.status
174
222
  end
175
223
 
176
224
  protected
177
225
 
178
- attr_reader :application, :version, :elastic_beanstalk
226
+ # :category: Internal
227
+ attr_reader :application
228
+ # :category: Internal
229
+ attr_reader :version
230
+ # :category: Internal
231
+ attr_reader :elastic_beanstalk
179
232
 
180
233
  def environment_description
181
234
  elastic_beanstalk.describe_environments(
@@ -245,38 +298,39 @@ module ElasticBeans
245
298
  )
246
299
  end
247
300
 
301
+ # :nodoc: all
302
+ # @!visibility private
248
303
  class MissingConfigurationError < ElasticBeans::Error
249
304
  def message
250
305
  require "elastic_beans/command/configure"
251
306
  <<-MESSAGE
252
- Some configuration must be set before creating an environment:
307
+ Some configuration is missing and must be set before creating an environment.
308
+ Please re-run `#{command_as_string "configure"}`.
253
309
 
254
- * keypair
255
- * SSL configuration
256
- * environment variables that Rails always requires
257
- * DATABASE_URL
258
- * SECRET_KEY_BASE
259
-
260
- #{$0} #{ElasticBeans::Command::Configure::USAGE}
310
+ #{`#{$0} help configure`}
261
311
  MESSAGE
262
312
  end
263
313
  end
264
314
 
315
+ # :nodoc: all
316
+ # @!visibility private
265
317
  class MissingEnvironmentError < ElasticBeans::Error
266
- def initialize(environment_name:)
267
- @environment_name = environment_name
318
+ def initialize(environment:, application:)
319
+ @environment = environment
320
+ @application = application
268
321
  end
269
322
 
270
323
  def message
271
324
  require "elastic_beans/command/create"
272
325
  <<-MESSAGE
273
- Environment `#{@environment_name}' does not exist. Try creating it!
274
-
275
- #{$0} #{ElasticBeans::Command::Create::USAGE}
326
+ Environment `#{@environment.name}' does not exist.
327
+ Please run `#{command_as_string "create #{@environment.type} -a #{@application.name}"}`.
276
328
  MESSAGE
277
329
  end
278
330
  end
279
331
 
332
+ # :nodoc: all
333
+ # @!visibility private
280
334
  class UnhealthyEnvironmentError < ElasticBeans::Error
281
335
  include Nesty::NestedError
282
336
 
@@ -296,6 +350,8 @@ Environment `#{@environment_name}' does not exist. Try creating it!
296
350
  end
297
351
  end
298
352
 
353
+ # :nodoc: all
354
+ # @!visibility private
299
355
  class UnknownEnvironmentType < ElasticBeans::Error
300
356
  def initialize(environment_type:)
301
357
  @environment_type = environment_type
@@ -1,5 +1,7 @@
1
1
  require "elastic_beans/error"
2
2
 
3
+ # :nodoc: all
4
+ # @!visibility private
3
5
  class EnvironmentsNotReady < ElasticBeans::Error
4
6
  def initialize(environments:)
5
7
  @environments = environments
@@ -1,6 +1,7 @@
1
1
  require "shellwords"
2
2
 
3
3
  module ElasticBeans
4
+ # The superclass for errors raised within ElasticBeans.
4
5
  class Error < StandardError
5
6
  protected
6
7
 
@@ -3,6 +3,8 @@ require "fileutils"
3
3
  require "net/http"
4
4
  require "uri"
5
5
 
6
+ # :nodoc: all
7
+ # @!visibility private
6
8
  class Init
7
9
  LOGFILE = "/var/log/elastic_beans_exec.log"
8
10
  PIDFILE = "/var/run/elastic_beans_exec.pid"
@@ -2,6 +2,8 @@ require "json"
2
2
  require "net/http"
3
3
  require "uri"
4
4
 
5
+ # :nodoc: all
6
+ # @!visibility private
5
7
  class SQSConsumer
6
8
  def initialize(logfile:, queue_url:, sqs:, logging_endpoint: nil)
7
9
  @logfile = logfile
@@ -1,6 +1,7 @@
1
1
  require "elastic_beans/aws/cloudformation_stack"
2
2
 
3
3
  module ElasticBeans
4
+ # The networking CloudFormation stack provided to configure.
4
5
  class Network
5
6
  APPLICATION_SECURITY_GROUP_KEY = "ApplicationSecurityGroup"
6
7
  APPLICATION_SUBNET_KEY = "ApplicationSubnet"
@@ -4,6 +4,11 @@ require "action_dispatch"
4
4
 
5
5
  module ElasticBeans
6
6
  module Rack
7
+ # A middleware that can convert specially-crafted paths into commands and enqueue them for execution using
8
+ # ElasticBeans::Application#enqueue_command.
9
+ # Load it in your Rails application so the "scheduler" environment enqueues commands for execution.
10
+ #
11
+ # Only accepts localhost requests from `aws-sqsd`.
7
12
  class Exec
8
13
  FAILURE = ['500', {'Content-type' => 'text/plain'}, [""]]
9
14
  SUCCESS = ['200', {'Content-type' => 'text/plain'}, [""]]
@@ -1,4 +1,6 @@
1
1
  module ElasticBeans
2
+ # :nodoc: all
3
+ # @!visibility private
2
4
  class UI
3
5
  attr_reader :stdout, :stderr
4
6
 
@@ -1,3 +1,3 @@
1
1
  module ElasticBeans
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.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.2.0
4
+ version: 0.3.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-12 00:00:00.000000000 Z
11
+ date: 2016-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk