Class: ElasticBeans::Application
- Inherits:
-
Object
- Object
- ElasticBeans::Application
- Defined in:
- lib/elastic_beans/application.rb
Overview
An Elastic Beanstalk application which should exist.
If the application does not exist, an error will be raised when attempting to access it.
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
-
#bucket_name ⇒ Object
Returns the name of the S3 bucket in which to store artifacts for this application.
-
#configuration_templates ⇒ Object
Returns an ElasticBeans::ConfigurationTemplate for each saved configuration of the Elastic Beanstalk application.
-
#deployed_version ⇒ Object
Returns an ElasticBeans::ApplicationVersion reflecting the deployed version of the application from the latest-updated environment.
-
#deregister_command(command) ⇒ Object
Removes command metadata created by #register_command.
-
#enqueue_command(command, delay_seconds: nil) ⇒ Object
Enqueues a one-off Exec::Command to be run on the application’s
exec
environment. -
#enqueued_commands ⇒ Object
Fetches up to 100 previously-enqueued commands that are running or scheduled to run.
-
#env_vars ⇒ Object
Returns the ElasticBeans::EnvVars for this application.
-
#environments ⇒ Object
Returns an ElasticBeans::Environment for each un-terminated environment in the Elastic Beanstalk application.
-
#exec_queue_url ⇒ Object
Fetches the
ExecQueueUrl
Output from the application CloudFormation stack. -
#initialize(name:, cloudformation:, elastic_beanstalk:, s3:, sqs: nil) ⇒ Application
constructor
A new instance of Application.
-
#kill_command(command_or_id) ⇒ Object
Schedules the given ElasticBeans::Exec::Command or
id
for termination. -
#register_command(command) ⇒ Object
Registers command metadata so that #enqueued_commands will find it.
-
#versions ⇒ Object
Returns an ElasticBeans::ApplicationVersion for each version of the Elastic Beanstalk application.
-
#worker_queue_url(queue) ⇒ Object
Returns the Worker{QUEUE}QueueUrl from the application CloudFormation stack.
-
#worker_queues ⇒ Object
Returns the name of each queue discovered in the application CloudFormation stack.
Constructor Details
#initialize(name:, cloudformation:, elastic_beanstalk:, s3:, sqs: nil) ⇒ Application
Returns a new instance of Application.
20 21 22 23 24 25 26 |
# File 'lib/elastic_beans/application.rb', line 20 def initialize(name:, cloudformation:, elastic_beanstalk:, s3:, sqs: nil) @name = name @elastic_beanstalk = elastic_beanstalk @s3 = s3 @sqs = sqs @stack = ElasticBeans::Aws::CloudformationStack.new(name, cloudformation: cloudformation) end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
18 19 20 |
# File 'lib/elastic_beans/application.rb', line 18 def name @name end |
Instance Method Details
#bucket_name ⇒ Object
Returns the name of the S3 bucket in which to store artifacts for this application. Looks for the default Elastic Beanstalk bucket, which is of the form elasticbeanstalk-REGION-ACCOUNT_ID
.
Raises an error if the bucket cannot be found.
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/elastic_beans/application.rb', line 98 def bucket_name return @bucket_name if @bucket_name bucket = s3.list_buckets.buckets.find { |bucket| bucket.name.start_with?("elasticbeanstalk-") } unless bucket raise MissingBucketError end @bucket_name = bucket.name rescue ::Aws::S3::Errors::AccessDenied raise AccessDeniedS3Error.new end |
#configuration_templates ⇒ Object
Returns an ElasticBeans::ConfigurationTemplate for each saved configuration of the Elastic Beanstalk application.
See ElasticBeans::ConfigurationTemplate::new_from_existing for details on determining appropriate types.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/elastic_beans/application.rb', line 47 def configuration_templates response = elastic_beanstalk.describe_applications(application_names: [name]) application = response.applications[0] unless application raise MissingApplicationError.new(application: self) end templates = application.configuration_templates templates.map { |template_name| ElasticBeans::ConfigurationTemplate.new_from_existing( template_name, application: self, elastic_beanstalk: elastic_beanstalk, ) } rescue ::Aws::ElasticBeanstalk::Errors::Throttling sleep 5 retry end |
#deployed_version ⇒ Object
Returns an ElasticBeans::ApplicationVersion reflecting the deployed version of the application from the latest-updated environment.
Ignores terminated or terminating environments.
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/elastic_beans/application.rb', line 32 def deployed_version response = elastic_beanstalk.describe_environments(application_name: name) live_environments = response.environments.select { |environment| environment.status !~ /Terminat/ } environment = live_environments.max_by(&:date_updated) if environment ElasticBeans::ApplicationVersion.new(environment.version_label, application: self, elastic_beanstalk: elastic_beanstalk) end rescue ::Aws::ElasticBeanstalk::Errors::Throttling sleep 5 retry end |
#deregister_command(command) ⇒ Object
Removes command metadata created by #register_command. Used by ‘beans exec –interactive` to clean up the interactive task metadata.
Raises an error if access is denied.
113 114 115 116 117 118 119 120 121 |
# File 'lib/elastic_beans/application.rb', line 113 def deregister_command(command) key = "#{command_key_prefix}#{command.id}.json" s3.delete_object( bucket: bucket_name, key: key, ) rescue ::Aws::S3::Errors::AccessDenied raise AccessDeniedS3Error.new(bucket: bucket_name, key: key) end |
#enqueue_command(command, delay_seconds: nil) ⇒ Object
Enqueues a one-off Exec::Command to be run on the application’s exec
environment. Does not wait for action to be taken, but returns immediately after enqueuing the command.
Raises an error if the exec environment or queue cannot be found, or if access is denied.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/elastic_beans/application.rb', line 127 def enqueue_command(command, delay_seconds: nil) if environments.none? { |environment| environment.is_a?(Environment::Exec) } raise MissingExecEnvironmentError.new(application: self) end if command.to_s == command command = Exec::Command.new(command_string: command) end register_command(command) = { queue_url: exec_queue_url, message_body: command.to_json, } [:delay_seconds] = delay_seconds if delay_seconds sqs.() end |
#enqueued_commands ⇒ Object
Fetches up to 100 previously-enqueued commands that are running or scheduled to run. Commands are deserialized from metadata files in a well-known location in S3. The metadata is created when the command is enqueued. The instances in the exec environment update the metadata when executing a command, and remove the metadata when they are done.
Raises an error if the application does not exist.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/elastic_beans/application.rb', line 151 def enqueued_commands unless exists? raise MissingApplicationError.new(application: self) end # Ignoring truncation for simplicity; >100 commands will just have to suffer. objects = s3.list_objects_v2( bucket: bucket_name, prefix: command_key_prefix, max_keys: 100, ).contents objects.each_with_object([]) do |object, commands| begin next unless object.key.end_with?('.json') begin s3.head_object(bucket: bucket_name, key: "#{object.key}.killed") next rescue ::Aws::S3::Errors::NotFound # not killed, move on end response = s3.get_object(bucket: bucket_name, key: object.key) commands << ElasticBeans::Exec::Command.from_json(response.body.read) # skip finished or invalid commands rescue ::Aws::S3::Errors::NoSuchKey rescue JSON::ParserError end end rescue ::Aws::S3::Errors::AccessDenied raise AccessDeniedS3Error.new(bucket: bucket_name, key: "#{command_key_prefix}*") end |
#env_vars ⇒ Object
Returns the ElasticBeans::EnvVars for this application.
68 69 70 71 72 73 74 |
# File 'lib/elastic_beans/application.rb', line 68 def env_vars unless exists? raise MissingApplicationError.new(application: self) end EnvVars.new(application: self, s3: s3) end |
#environments ⇒ Object
Returns an ElasticBeans::Environment for each un-terminated environment in the Elastic Beanstalk application.
See ElasticBeans::Environment::new_from_existing for details on determining appropriate types.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/elastic_beans/application.rb', line 79 def environments response = elastic_beanstalk.describe_environments(application_name: name) live_environments = response.environments.select { |environment| environment.status !~ /Terminat/ } live_environments.map { |environment| ElasticBeans::Environment.new_from_existing( environment, application: self, elastic_beanstalk: elastic_beanstalk, ) } rescue ::Aws::ElasticBeanstalk::Errors::Throttling sleep 5 retry end |
#exec_queue_url ⇒ Object
Fetches the ExecQueueUrl
Output from the application CloudFormation stack. The stack must have the same name as the application.
185 186 187 |
# File 'lib/elastic_beans/application.rb', line 185 def exec_queue_url stack.stack_output("ExecQueueUrl") end |
#kill_command(command_or_id) ⇒ Object
Schedules the given ElasticBeans::Exec::Command or id
for termination. Adds a special piece of metadata to kill the command and relies on the SQSConsumer to terminate it.
Raises an error if the application does not exist.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/elastic_beans/application.rb', line 193 def kill_command(command_or_id) unless exists? raise MissingApplicationError.new(application: self) end if command_or_id.is_a?(ElasticBeans::Exec::Command) command_id = command_or_id.id else command_id = command_or_id end key = "#{command_key_prefix}#{command_id}.json.killed" s3.put_object( bucket: bucket_name, key: key, ) rescue ::Aws::S3::Errors::AccessDenied raise AccessDeniedS3Error.new(bucket: bucket_name, key: key) end |
#register_command(command) ⇒ Object
Registers command metadata so that #enqueued_commands will find it. Adds :bucket
and :key
keys to the command’s ElasticBeans::Exec::Command#metadata. Used by beans exec –interactive“ so that beans ps+ displays interactive tasks that are not enqueued normally.
Raises an error if access is denied.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/elastic_beans/application.rb', line 218 def register_command(command) unless exists? raise MissingApplicationError.new(application: self) end command.[:bucket] = bucket_name command.[:key] = "#{command_key_prefix}#{command.id}.json" s3.put_object( bucket: bucket_name, key: command.[:key], body: command.to_json, ) rescue ::Aws::S3::Errors::AccessDenied raise AccessDeniedS3Error.new(bucket: bucket_name, key: command.[:key]) end |
#versions ⇒ Object
Returns an ElasticBeans::ApplicationVersion for each version of the Elastic Beanstalk application.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/elastic_beans/application.rb', line 235 def versions application_versions = [] next_token = nil loop do begin response = elastic_beanstalk.describe_application_versions(application_name: name, next_token: next_token) next_token = response.next_token application_versions += response.application_versions.map { |version| ElasticBeans::ApplicationVersion.new_from_existing(version, application: self, elastic_beanstalk: elastic_beanstalk) } break unless next_token rescue ::Aws::ElasticBeanstalk::Errors::Throttling sleep 5 retry end end application_versions end |
#worker_queue_url(queue) ⇒ Object
Returns the Worker{QUEUE}QueueUrl from the application CloudFormation stack.
255 256 257 258 259 |
# File 'lib/elastic_beans/application.rb', line 255 def worker_queue_url(queue) queue_attribute = queue.to_s.downcase queue_attribute[0] = queue_attribute[0].upcase stack.stack_output("Worker#{queue_attribute}QueueUrl") end |
#worker_queues ⇒ Object
Returns the name of each queue discovered in the application CloudFormation stack. Looks for outputs of the form Worker{QUEUE}QueueUrl.
263 264 265 266 267 268 269 270 |
# File 'lib/elastic_beans/application.rb', line 263 def worker_queues stack.stack_outputs.each_with_object([]) do |(output_key, _), acc| match = /\AWorker(?<queue>\w+)QueueUrl\z/.match(output_key) if match acc << match[:queue].downcase end end end |