elastic_beans 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/Gemfile +9 -0
- data/LICENSE.md +21 -0
- data/README.md +184 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +20 -0
- data/elastic_beans.gemspec +31 -0
- data/exe/beans +198 -0
- data/lib/elastic_beans/application.rb +127 -0
- data/lib/elastic_beans/application_version.rb +202 -0
- data/lib/elastic_beans/aws/cloudformation_stack.rb +66 -0
- data/lib/elastic_beans/command/configure.rb +184 -0
- data/lib/elastic_beans/command/create.rb +150 -0
- data/lib/elastic_beans/command/deploy.rb +77 -0
- data/lib/elastic_beans/command/exec.rb +37 -0
- data/lib/elastic_beans/command/set_env.rb +77 -0
- data/lib/elastic_beans/command/talk.rb +74 -0
- data/lib/elastic_beans/command/version.rb +17 -0
- data/lib/elastic_beans/command.rb +12 -0
- data/lib/elastic_beans/configuration_template/base.rb +114 -0
- data/lib/elastic_beans/configuration_template/exec.rb +50 -0
- data/lib/elastic_beans/configuration_template/scheduler.rb +20 -0
- data/lib/elastic_beans/configuration_template/webserver.rb +49 -0
- data/lib/elastic_beans/configuration_template/worker.rb +27 -0
- data/lib/elastic_beans/configuration_template.rb +197 -0
- data/lib/elastic_beans/dns_entry.rb +127 -0
- data/lib/elastic_beans/environment/exec.rb +23 -0
- data/lib/elastic_beans/environment/scheduler.rb +23 -0
- data/lib/elastic_beans/environment/webserver.rb +23 -0
- data/lib/elastic_beans/environment/worker.rb +29 -0
- data/lib/elastic_beans/environment.rb +300 -0
- data/lib/elastic_beans/error/environments_not_ready.rb +15 -0
- data/lib/elastic_beans/error.rb +15 -0
- data/lib/elastic_beans/exec/ebextension.yml +10 -0
- data/lib/elastic_beans/exec/elastic_beans_exec.conf +15 -0
- data/lib/elastic_beans/exec/init.rb +50 -0
- data/lib/elastic_beans/exec/run_command.sh +13 -0
- data/lib/elastic_beans/exec/sqs_consumer.rb +75 -0
- data/lib/elastic_beans/network.rb +44 -0
- data/lib/elastic_beans/rack/exec.rb +63 -0
- data/lib/elastic_beans/scheduler/ebextension.yml +4 -0
- data/lib/elastic_beans/ui.rb +31 -0
- data/lib/elastic_beans/version.rb +3 -0
- data/lib/elastic_beans.rb +9 -0
- metadata +218 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
require "elastic_beans/error"
|
2
|
+
|
3
|
+
module ElasticBeans
|
4
|
+
class ConfigurationTemplate
|
5
|
+
class Base < ElasticBeans::ConfigurationTemplate
|
6
|
+
SOLUTION_STACK_NAME = "64bit Amazon Linux 2016.09 v2.2.0 running Ruby 2.3 (Puma)"
|
7
|
+
|
8
|
+
def initialize(**args)
|
9
|
+
super(name: "base", **args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def upsert(**args)
|
13
|
+
@option_settings = build_option_settings(**args)
|
14
|
+
if configuration_settings_description
|
15
|
+
elastic_beanstalk.update_configuration_template(
|
16
|
+
application_name: application.name,
|
17
|
+
template_name: name,
|
18
|
+
option_settings: option_settings,
|
19
|
+
)
|
20
|
+
else
|
21
|
+
elastic_beanstalk.create_configuration_template(
|
22
|
+
application_name: application.name,
|
23
|
+
template_name: name,
|
24
|
+
solution_stack_name: SOLUTION_STACK_NAME,
|
25
|
+
option_settings: option_settings,
|
26
|
+
)
|
27
|
+
end
|
28
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
29
|
+
sleep 5
|
30
|
+
retry
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def build_option_settings(
|
36
|
+
network:,
|
37
|
+
database_url: nil,
|
38
|
+
secret_key_base: nil,
|
39
|
+
image_id: nil,
|
40
|
+
instance_type: nil,
|
41
|
+
keypair: nil,
|
42
|
+
iam:,
|
43
|
+
**_
|
44
|
+
)
|
45
|
+
instance_profile_setting = template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "IamInstanceProfile", override: instance_profile(iam))
|
46
|
+
if instance_profile_setting[:value].nil?
|
47
|
+
raise MissingInstanceProfileError
|
48
|
+
end
|
49
|
+
|
50
|
+
keypair_setting = template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "EC2KeyName", override: keypair)
|
51
|
+
database_url_setting = template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DATABASE_URL", override: database_url)
|
52
|
+
secret_key_base_setting = template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "SECRET_KEY_BASE", override: secret_key_base)
|
53
|
+
if database_url_setting[:value].nil? || secret_key_base_setting[:value].nil? || keypair_setting[:value].nil?
|
54
|
+
raise MissingConfigurationError
|
55
|
+
end
|
56
|
+
|
57
|
+
security_groups = [network.ssh_security_group] + network.application_security_groups
|
58
|
+
settings = [
|
59
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:command", option_name: "BatchSize", default: "1"),
|
60
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:command", option_name: "BatchSizeType", default: "Fixed"),
|
61
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:command", option_name: "DeploymentPolicy", default: "Rolling"),
|
62
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", default: "true"),
|
63
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:environment", option_name: "ServiceRole", default: "aws-elasticbeanstalk-service-role"),
|
64
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:healthreporting:system", option_name: "SystemType", default: "enhanced"),
|
65
|
+
template_option_setting(namespace: "aws:ec2:vpc", option_name: "AssociatePublicIpAddress", default: "false"),
|
66
|
+
template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "InstanceType", default: "c4.large", override: instance_type),
|
67
|
+
template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "SSHSourceRestriction", default: "tcp, 22, 22, 0.0.0.0/32"),
|
68
|
+
template_option_setting(namespace: "aws:autoscaling:updatepolicy:rollingupdate", option_name: "RollingUpdateType", default: "Health"),
|
69
|
+
template_option_setting(namespace: "aws:autoscaling:updatepolicy:rollingupdate", option_name: "RollingUpdateEnabled", default: "true"),
|
70
|
+
template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "SecurityGroups", override: security_groups.join(",")),
|
71
|
+
template_option_setting(namespace: "aws:ec2:vpc", option_name: "ELBSubnets", override: network.elb_subnets.join(",")),
|
72
|
+
template_option_setting(namespace: "aws:ec2:vpc", option_name: "Subnets", override: network.application_subnets.join(",")),
|
73
|
+
template_option_setting(namespace: "aws:ec2:vpc", option_name: "VPCId", override: network.vpc),
|
74
|
+
instance_profile_setting,
|
75
|
+
keypair_setting,
|
76
|
+
database_url_setting,
|
77
|
+
secret_key_base_setting,
|
78
|
+
]
|
79
|
+
if image_id
|
80
|
+
settings << template_option_setting(namespace: "aws:autoscaling:launchconfiguration", option_name: "ImageId", override: image_id)
|
81
|
+
end
|
82
|
+
settings
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def instance_profile(iam)
|
88
|
+
return @instance_profile if @instance_profile
|
89
|
+
marker = nil
|
90
|
+
loop do
|
91
|
+
response = iam.list_instance_profiles(marker: marker)
|
92
|
+
profile = response.instance_profiles.find { |profile|
|
93
|
+
profile.instance_profile_name == "aws-elasticbeanstalk-ec2-role"
|
94
|
+
}
|
95
|
+
if profile
|
96
|
+
@instance_profile = profile.arn
|
97
|
+
return @instance_profile
|
98
|
+
end
|
99
|
+
break unless response.is_truncated
|
100
|
+
marker = response.marker
|
101
|
+
end
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
class MissingInstanceProfileError < ElasticBeans::Error
|
106
|
+
def message
|
107
|
+
"Could not find Elastic Beanstalk instance profile." \
|
108
|
+
" Please create the default instance profile named \"aws-elasticbeanstalk-ec2-role\":" \
|
109
|
+
" http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.iam.html"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "uri"
|
2
|
+
require "elastic_beans/error"
|
3
|
+
|
4
|
+
module ElasticBeans
|
5
|
+
class ConfigurationTemplate
|
6
|
+
class Exec < ElasticBeans::ConfigurationTemplate::Base
|
7
|
+
def initialize(**args)
|
8
|
+
super(name: "exec", **args)
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def build_option_settings(logging_endpoint: nil, **_)
|
14
|
+
if logging_endpoint
|
15
|
+
begin
|
16
|
+
if URI(logging_endpoint).scheme != "https"
|
17
|
+
raise InvalidLoggingEndpointError.new(logging_endpoint: logging_endpoint)
|
18
|
+
end
|
19
|
+
rescue URI::InvalidURIError
|
20
|
+
raise InvalidLoggingEndpointError.new(logging_endpoint: logging_endpoint)
|
21
|
+
end
|
22
|
+
|
23
|
+
logging_endpoint_setting = template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_EXEC_LOGGING_ENDPOINT", override: logging_endpoint)
|
24
|
+
end
|
25
|
+
|
26
|
+
settings = [
|
27
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
28
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
29
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "ELASTIC_BEANS_EXEC_QUEUE_URL", override: application.exec_queue_url),
|
30
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "true"),
|
31
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
32
|
+
]
|
33
|
+
if logging_endpoint
|
34
|
+
settings << logging_endpoint_setting
|
35
|
+
end
|
36
|
+
super + settings
|
37
|
+
end
|
38
|
+
|
39
|
+
class InvalidLoggingEndpointError < ElasticBeans::Error
|
40
|
+
def initialize(logging_endpoint:)
|
41
|
+
@logging_endpoint = logging_endpoint
|
42
|
+
end
|
43
|
+
|
44
|
+
def message
|
45
|
+
"Logging endpoint `#{@logging_endpoint}' must be a valid HTTPS URL."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ElasticBeans
|
2
|
+
class ConfigurationTemplate
|
3
|
+
class Scheduler < ElasticBeans::ConfigurationTemplate::Base
|
4
|
+
def initialize(**args)
|
5
|
+
super(name: "scheduler", **args)
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def build_option_settings(**_)
|
11
|
+
super + [
|
12
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
13
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
14
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "true"),
|
15
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "elastic_beans/error"
|
2
|
+
|
3
|
+
module ElasticBeans
|
4
|
+
class ConfigurationTemplate
|
5
|
+
class Webserver < ElasticBeans::ConfigurationTemplate::Base
|
6
|
+
def initialize(**args)
|
7
|
+
super(name: "webserver", **args)
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def build_option_settings(network:, public_key:, ssl_certificate_id:, **_)
|
13
|
+
public_key_policy_names_setting = template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "PublicKeyPolicyNames", default: "backendkey")
|
14
|
+
public_key_setting = template_option_setting(namespace: "aws:elb:policies:#{public_key_policy_names_setting[:value]}", option_name: "PublicKey", override: public_key)
|
15
|
+
ssl_certificate_setting = template_option_setting(namespace: "aws:elb:listener:443", option_name: "SSLCertificateId", override: ssl_certificate_id)
|
16
|
+
if public_key_setting[:value].nil? || ssl_certificate_setting[:value].nil?
|
17
|
+
raise NoEncryptionSettingsError
|
18
|
+
end
|
19
|
+
|
20
|
+
super + [
|
21
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTPS:443/"),
|
22
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "false"),
|
23
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "false"),
|
24
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstancePort", default: "443"),
|
25
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "InstanceProtocol", default: "HTTPS"),
|
26
|
+
template_option_setting(namespace: "aws:elb:listener:443", option_name: "ListenerProtocol", default: "HTTPS"),
|
27
|
+
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "ManagedSecurityGroup", override: network.elb_security_groups[0]),
|
28
|
+
template_option_setting(namespace: "aws:elb:loadbalancer", option_name: "SecurityGroups", override: network.elb_security_groups.join(",")),
|
29
|
+
template_option_setting(namespace: "aws:elb:policies", option_name: "ConnectionDrainingEnabled", default: "true"),
|
30
|
+
template_option_setting(namespace: "aws:elb:policies:backendencryption", option_name: "InstancePorts", default: "443"),
|
31
|
+
public_key_policy_names_setting,
|
32
|
+
public_key_setting,
|
33
|
+
ssl_certificate_setting,
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
class NoEncryptionSettingsError < ElasticBeans::Error
|
38
|
+
def message
|
39
|
+
require "elastic_beans/command/configure"
|
40
|
+
<<-MESSAGE
|
41
|
+
Missing required end-to-end encryption settings. Make sure to specify SSL certificate ID and public key.
|
42
|
+
|
43
|
+
#{$0} #{ElasticBeans::Command::Configure::USAGE}
|
44
|
+
MESSAGE
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ElasticBeans
|
2
|
+
class ConfigurationTemplate
|
3
|
+
class Worker < ElasticBeans::ConfigurationTemplate::Base
|
4
|
+
attr_reader :queue
|
5
|
+
|
6
|
+
def initialize(queue:, **args)
|
7
|
+
@queue = queue
|
8
|
+
super(name: "worker-#{queue}", **args)
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def build_option_settings(**_)
|
14
|
+
super + [
|
15
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application", option_name: "Application Healthcheck URL", default: "HTTP:80/"),
|
16
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "DISABLE_SQS_CONSUMER", override: "false"),
|
17
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_ASSET_COMPILATION", default: "true"),
|
18
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:application:environment", option_name: "RAILS_SKIP_MIGRATIONS", default: "true"),
|
19
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "InactivityTimeout", default: "1800"),
|
20
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "MaxRetries", default: "10"),
|
21
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "VisibilityTimeout", default: "1800"),
|
22
|
+
template_option_setting(namespace: "aws:elasticbeanstalk:sqsd", option_name: "WorkerQueueURL", override: application.worker_queue_url(queue)),
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require "elastic_beans/configuration_template/base"
|
2
|
+
require "elastic_beans/configuration_template/exec"
|
3
|
+
require "elastic_beans/configuration_template/scheduler"
|
4
|
+
require "elastic_beans/configuration_template/webserver"
|
5
|
+
require "elastic_beans/configuration_template/worker"
|
6
|
+
|
7
|
+
module ElasticBeans
|
8
|
+
class ConfigurationTemplate
|
9
|
+
WORKER_TEMPLATE_NAME_PATTERN = /\Aworker-(?<queue>\w+)\z/
|
10
|
+
|
11
|
+
attr_reader :name
|
12
|
+
|
13
|
+
def self.new_by_type(type, **args)
|
14
|
+
case type
|
15
|
+
when "base"
|
16
|
+
ElasticBeans::ConfigurationTemplate::Base.new(**args)
|
17
|
+
when "exec"
|
18
|
+
ElasticBeans::ConfigurationTemplate::Exec.new(**args)
|
19
|
+
when "scheduler"
|
20
|
+
ElasticBeans::ConfigurationTemplate::Scheduler.new(**args)
|
21
|
+
when "webserver"
|
22
|
+
ElasticBeans::ConfigurationTemplate::Webserver.new(**args)
|
23
|
+
when "worker"
|
24
|
+
ElasticBeans::ConfigurationTemplate::Worker.new(**args)
|
25
|
+
else
|
26
|
+
raise UnknownConfigurationType.new(type: type)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.new_from_existing(template_name, **args)
|
31
|
+
case template_name
|
32
|
+
when "base"
|
33
|
+
ElasticBeans::ConfigurationTemplate::Base.new(**args)
|
34
|
+
when "exec"
|
35
|
+
ElasticBeans::ConfigurationTemplate::Exec.new(**args)
|
36
|
+
when "scheduler"
|
37
|
+
ElasticBeans::ConfigurationTemplate::Scheduler.new(**args)
|
38
|
+
when "webserver"
|
39
|
+
ElasticBeans::ConfigurationTemplate::Webserver.new(**args)
|
40
|
+
when WORKER_TEMPLATE_NAME_PATTERN
|
41
|
+
match = WORKER_TEMPLATE_NAME_PATTERN.match(template_name)
|
42
|
+
ElasticBeans::ConfigurationTemplate::Worker.new(queue: match[:queue], **args)
|
43
|
+
else
|
44
|
+
raise UnknownConfigurationType.new(type: template_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(
|
49
|
+
name:,
|
50
|
+
application:,
|
51
|
+
elastic_beanstalk:,
|
52
|
+
**_
|
53
|
+
)
|
54
|
+
@name = name
|
55
|
+
@application = application
|
56
|
+
@elastic_beanstalk = elastic_beanstalk
|
57
|
+
end
|
58
|
+
|
59
|
+
def option_settings
|
60
|
+
# do not fetch option settings from Elastic Beanstalk, because those cannot be naively used.
|
61
|
+
# the set built in #build_option_settings is what we care about.
|
62
|
+
return @option_settings if @option_settings
|
63
|
+
raise MissingConfigurationError
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_environment(env_vars)
|
67
|
+
new_env_settings = env_vars.map { |k, v|
|
68
|
+
{namespace: "aws:elasticbeanstalk:application:environment", option_name: k, value: v}
|
69
|
+
}
|
70
|
+
elastic_beanstalk.update_configuration_template(
|
71
|
+
application_name: application.name,
|
72
|
+
template_name: name,
|
73
|
+
option_settings: new_env_settings,
|
74
|
+
)
|
75
|
+
rescue ::Aws::ElasticBeanstalk::Errors::ConfigurationValidationException => e
|
76
|
+
raise InvalidConfigurationError.new(cause: e)
|
77
|
+
rescue ::Aws::ElasticBeanstalk::Errors::InvalidParameterValue => e
|
78
|
+
raise MissingConfigurationError.new(cause: e)
|
79
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
80
|
+
sleep 5
|
81
|
+
retry
|
82
|
+
end
|
83
|
+
|
84
|
+
def upsert(**args)
|
85
|
+
@option_settings = build_option_settings(**args)
|
86
|
+
if configuration_settings_description
|
87
|
+
elastic_beanstalk.update_configuration_template(
|
88
|
+
application_name: application.name,
|
89
|
+
template_name: name,
|
90
|
+
option_settings: option_settings,
|
91
|
+
)
|
92
|
+
else
|
93
|
+
elastic_beanstalk.create_configuration_template(
|
94
|
+
application_name: application.name,
|
95
|
+
template_name: name,
|
96
|
+
source_configuration: {application_name: application.name, template_name: "base"},
|
97
|
+
option_settings: option_settings,
|
98
|
+
)
|
99
|
+
end
|
100
|
+
rescue ::Aws::ElasticBeanstalk::Errors::Throttling
|
101
|
+
sleep 5
|
102
|
+
retry
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
attr_reader :application, :elastic_beanstalk
|
108
|
+
|
109
|
+
def build_option_settings(**_)
|
110
|
+
[]
|
111
|
+
end
|
112
|
+
|
113
|
+
def configuration_settings_description
|
114
|
+
@configuration_template ||= elastic_beanstalk.describe_configuration_settings(
|
115
|
+
application_name: application.name,
|
116
|
+
template_name: name,
|
117
|
+
).configuration_settings[0]
|
118
|
+
rescue ::Aws::ElasticBeanstalk::Errors::InvalidParameterValue => e
|
119
|
+
if e.message =~ /\bconfiguration template\b/i
|
120
|
+
return nil
|
121
|
+
end
|
122
|
+
raise MissingConfigurationError.new(cause: e)
|
123
|
+
end
|
124
|
+
|
125
|
+
def template_option_setting(template: configuration_settings_description, namespace:, option_name:, default: nil, override: nil)
|
126
|
+
option_setting = {namespace: namespace, option_name: option_name, value: default}
|
127
|
+
if override
|
128
|
+
return option_setting.merge!(value: override)
|
129
|
+
end
|
130
|
+
|
131
|
+
if template.nil?
|
132
|
+
return option_setting
|
133
|
+
end
|
134
|
+
setting = template.to_h[:option_settings].find { |setting|
|
135
|
+
setting[:namespace] == namespace && setting[:option_name] == option_name
|
136
|
+
}
|
137
|
+
if setting.nil?
|
138
|
+
return option_setting
|
139
|
+
end
|
140
|
+
|
141
|
+
option_setting.merge!(value: setting[:value])
|
142
|
+
end
|
143
|
+
|
144
|
+
class InvalidConfigurationError < ElasticBeans::Error
|
145
|
+
include Nesty::NestedError
|
146
|
+
|
147
|
+
def initialize(cause: nil)
|
148
|
+
@nested = cause
|
149
|
+
end
|
150
|
+
|
151
|
+
def message
|
152
|
+
msg = "Configuration was rejected by Elastic Beanstalk. Check for too much configuration or the use of reserved words."
|
153
|
+
if nested
|
154
|
+
msg << "The error from AWS was \"#{nested.message}\""
|
155
|
+
end
|
156
|
+
msg
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class MissingConfigurationError < ElasticBeans::Error
|
161
|
+
include Nesty::NestedError
|
162
|
+
|
163
|
+
def initialize(cause: nil)
|
164
|
+
@nested = cause
|
165
|
+
end
|
166
|
+
|
167
|
+
def message
|
168
|
+
require "elastic_beans/command/configure"
|
169
|
+
msg = <<-MESSAGE
|
170
|
+
Some configuration must be set before creating an environment:
|
171
|
+
|
172
|
+
* keypair
|
173
|
+
* SSL configuration
|
174
|
+
* environment variables that Rails always requires
|
175
|
+
* DATABASE_URL
|
176
|
+
* SECRET_KEY_BASE
|
177
|
+
|
178
|
+
#{$0} #{ElasticBeans::Command::Configure::USAGE}
|
179
|
+
MESSAGE
|
180
|
+
if nested
|
181
|
+
msg = "The error from AWS was \"#{nested.message}\"\n#{msg}"
|
182
|
+
end
|
183
|
+
msg
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class UnknownConfigurationType < ElasticBeans::Error
|
188
|
+
def initialize(type:)
|
189
|
+
@type = type
|
190
|
+
end
|
191
|
+
|
192
|
+
def message
|
193
|
+
"Unknown configuration type `#{@type}'"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|