aerosol 1.8.0 → 1.9.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 +4 -4
- data/lib/aerosol.rb +6 -3
- data/lib/aerosol/auto_scaling.rb +31 -5
- data/lib/aerosol/launch_template.rb +133 -0
- data/lib/aerosol/version.rb +1 -1
- data/spec/aerosol/launch_template_spec.rb +402 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c51be45f1098f15a79cbab049755110bf351bed1661bb5b28504ab34c613f01
|
|
4
|
+
data.tar.gz: 235972faf898d0cc796cdf0b7de74f05a6c3aa396dc13b9f0f8909fb1229cecb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5aa215e96061f829d5042d72c56495f0059cb716b12b89386ca84e7b5568b6993d39a18d07e216c90de2af96ba742d5ea588c733e0303d275ffdb16bfb7f8965
|
|
7
|
+
data.tar.gz: 890ced1dce45bcf8ab1de6d60834f78bd881490efd9d7473ada54ac92359a691c53f031959c9cb7e08fb1745c7d9ada0abb84b00913d83e5166cb661c252fdbd
|
data/lib/aerosol.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Aerosol
|
|
|
13
13
|
require 'aerosol/util'
|
|
14
14
|
require 'aerosol/aws_model'
|
|
15
15
|
require 'aerosol/launch_configuration'
|
|
16
|
+
require 'aerosol/launch_template'
|
|
16
17
|
require 'aerosol/auto_scaling'
|
|
17
18
|
require 'aerosol/instance'
|
|
18
19
|
require 'aerosol/connection'
|
|
@@ -61,6 +62,7 @@ module Aerosol
|
|
|
61
62
|
:auto_scalings => Aerosol::AutoScaling.instances,
|
|
62
63
|
:deploys => Aerosol::Deploy.instances,
|
|
63
64
|
:launch_configurations => Aerosol::LaunchConfiguration.instances,
|
|
65
|
+
:launch_templates => Aerosol::LaunchTemplate.instances,
|
|
64
66
|
:sshs => Aerosol::Connection.instances,
|
|
65
67
|
:envs => Aerosol::Env.instances
|
|
66
68
|
}
|
|
@@ -70,6 +72,7 @@ module Aerosol
|
|
|
70
72
|
:auto_scaling => Aerosol::AutoScaling,
|
|
71
73
|
:deploy => Aerosol::Deploy,
|
|
72
74
|
:launch_configuration => Aerosol::LaunchConfiguration,
|
|
75
|
+
:launch_template => Aerosol::LaunchTemplate,
|
|
73
76
|
:ssh => Aerosol::Connection,
|
|
74
77
|
:env => Aerosol::Env
|
|
75
78
|
}.each do |method, klass|
|
|
@@ -82,15 +85,15 @@ module Aerosol
|
|
|
82
85
|
end
|
|
83
86
|
end
|
|
84
87
|
|
|
85
|
-
[:auto_scalings, :deploys, :launch_configurations, :sshs, :envs].each do |method|
|
|
88
|
+
[:auto_scalings, :deploys, :launch_configurations, :launch_templates, :sshs, :envs].each do |method|
|
|
86
89
|
define_method(method) do
|
|
87
90
|
inst[method]
|
|
88
91
|
end
|
|
89
92
|
end
|
|
90
93
|
|
|
91
94
|
module_function :inst, :load_inst, :setup, :load_file, :load_file=,
|
|
92
|
-
:auto_scaling, :launch_configuration, :deploy, :ssh, :git_sha,
|
|
93
|
-
:auto_scalings, :launch_configurations, :deploys, :sshs,
|
|
95
|
+
:auto_scaling, :launch_configuration, :launch_template, :deploy, :ssh, :git_sha,
|
|
96
|
+
:auto_scalings, :launch_configurations, :launch_templates, :deploys, :sshs,
|
|
94
97
|
:namespace, :env, :envs, :region
|
|
95
98
|
end
|
|
96
99
|
|
data/lib/aerosol/auto_scaling.rb
CHANGED
|
@@ -7,6 +7,7 @@ class Aerosol::AutoScaling
|
|
|
7
7
|
:desired_capacity, :health_check_grace_period, :health_check_type, :load_balancer_names,
|
|
8
8
|
:placement_group, :tags, :created_time, :vpc_zone_identifier, :target_group_arns
|
|
9
9
|
aws_class_attribute :launch_configuration, Aerosol::LaunchConfiguration
|
|
10
|
+
aws_class_attribute :launch_template, Aerosol::LaunchTemplate
|
|
10
11
|
primary_key :auto_scaling_group_name
|
|
11
12
|
|
|
12
13
|
def initialize(options={}, &block)
|
|
@@ -38,21 +39,30 @@ class Aerosol::AutoScaling
|
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def create!
|
|
41
|
-
ensure_present! :
|
|
42
|
+
ensure_present! :max_size, :min_size
|
|
42
43
|
raise 'availability_zones or vpc_zone_identifier must be set' if [availability_zones, vpc_zone_identifier].none?
|
|
44
|
+
raise 'launch_configuration or launch_template must be set' if [launch_configuration, launch_template].none?
|
|
43
45
|
|
|
44
46
|
info "creating auto scaling group"
|
|
45
|
-
|
|
47
|
+
launch_details = create_launch_details
|
|
48
|
+
|
|
46
49
|
info self.inspect
|
|
47
50
|
|
|
48
51
|
conn.create_auto_scaling_group({
|
|
49
52
|
auto_scaling_group_name: auto_scaling_group_name,
|
|
50
53
|
availability_zones: [*availability_zones],
|
|
51
|
-
launch_configuration_name: launch_configuration.launch_configuration_name,
|
|
52
54
|
max_size: max_size,
|
|
53
55
|
min_size: min_size
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
+
}
|
|
57
|
+
.merge(create_options)
|
|
58
|
+
.merge(launch_details)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
conn.wait_until(:group_in_service, auto_scaling_group_names: [auto_scaling_group_name]) do |waiter|
|
|
62
|
+
waiter.before_wait do |attempt_count, _response|
|
|
63
|
+
info "Wait count #{attempt_count} of #{waiter.max_attempts} for #{auto_scaling_group_name} to be in service"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
56
66
|
end
|
|
57
67
|
|
|
58
68
|
def destroy!
|
|
@@ -147,6 +157,22 @@ private
|
|
|
147
157
|
Aerosol::AWS.auto_scaling
|
|
148
158
|
end
|
|
149
159
|
|
|
160
|
+
def create_launch_details
|
|
161
|
+
if launch_configuration
|
|
162
|
+
launch_configuration.create
|
|
163
|
+
{ launch_configuration_name: launch_configuration.launch_configuration_name }
|
|
164
|
+
elsif launch_template
|
|
165
|
+
launch_template.create
|
|
166
|
+
{
|
|
167
|
+
launch_template:
|
|
168
|
+
{
|
|
169
|
+
launch_template_name: launch_template.launch_template_name,
|
|
170
|
+
version: '$Latest'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
150
176
|
def create_options
|
|
151
177
|
{
|
|
152
178
|
default_cooldown: default_cooldown,
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
class Aerosol::LaunchTemplate
|
|
2
|
+
include Aerosol::AWSModel
|
|
3
|
+
include Dockly::Util::Logger::Mixin
|
|
4
|
+
|
|
5
|
+
logger_prefix '[aerosol launch_template]'
|
|
6
|
+
aws_attribute :launch_template_name, :image_id, :instance_type, :security_groups, :user_data,
|
|
7
|
+
:iam_instance_profile, :kernel_id, :key_name, :spot_price, :created_time,
|
|
8
|
+
:network_interfaces, :block_device_mappings, :ebs_optimized
|
|
9
|
+
dsl_attribute :meta_data
|
|
10
|
+
|
|
11
|
+
primary_key :launch_template_name
|
|
12
|
+
default_value(:security_groups) { [] }
|
|
13
|
+
default_value(:meta_data) { {} }
|
|
14
|
+
|
|
15
|
+
def launch_template_name(arg = nil)
|
|
16
|
+
if arg
|
|
17
|
+
raise "You cannot set the launch_template_name directly" unless from_aws
|
|
18
|
+
@launch_template_name = arg
|
|
19
|
+
else
|
|
20
|
+
@launch_template_name || default_identifier
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def exists?
|
|
25
|
+
info "launch_template: needed?: #{launch_template_name}: " +
|
|
26
|
+
"checking for launch template: #{launch_template_name}"
|
|
27
|
+
exists = super
|
|
28
|
+
info "launch template: needed?: #{launch_template_name}: " +
|
|
29
|
+
"#{exists ? 'found' : 'did not find'} launch template: #{launch_template_name}"
|
|
30
|
+
exists
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def security_group(group)
|
|
34
|
+
security_groups << group
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def create!
|
|
38
|
+
ensure_present! :image_id, :instance_type
|
|
39
|
+
|
|
40
|
+
info "creating launch template"
|
|
41
|
+
conn.create_launch_template(
|
|
42
|
+
launch_template_name: launch_template_name,
|
|
43
|
+
launch_template_data: {
|
|
44
|
+
image_id: image_id,
|
|
45
|
+
instance_type: instance_type,
|
|
46
|
+
monitoring: {
|
|
47
|
+
enabled: true
|
|
48
|
+
},
|
|
49
|
+
}.merge(create_options)
|
|
50
|
+
)
|
|
51
|
+
info self.inspect
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def destroy!
|
|
55
|
+
info self.to_s
|
|
56
|
+
raise StandardError.new('No launch_template_name found') unless launch_template_name
|
|
57
|
+
conn.delete_launch_template(launch_template_name: launch_template_name)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def all_instances
|
|
61
|
+
Aerosol::Instance.all.select { |instance|
|
|
62
|
+
!instance.launch_template.nil? &&
|
|
63
|
+
(instance.launch_template.launch_template == launch_template_name)
|
|
64
|
+
}.each(&:description)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.request_all_for_token(next_token)
|
|
68
|
+
options = next_token.nil? ? {} : { next_token: next_token }
|
|
69
|
+
Aerosol::AWS.compute.describe_launch_templates(options)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.request_all
|
|
73
|
+
next_token = nil
|
|
74
|
+
lts = []
|
|
75
|
+
|
|
76
|
+
begin
|
|
77
|
+
new_lts = request_all_for_token(next_token)
|
|
78
|
+
lts.concat(new_lts.launch_templates)
|
|
79
|
+
next_token = new_lts.next_token
|
|
80
|
+
end until next_token.nil?
|
|
81
|
+
|
|
82
|
+
lts
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def to_s
|
|
86
|
+
%{Aerosol::LaunchTemplate { \
|
|
87
|
+
"launch_template_name" => "#{launch_template_name}", \
|
|
88
|
+
"image_id" => "#{image_id}", \
|
|
89
|
+
"instance_type" => "#{instance_type}", \
|
|
90
|
+
"security_group_ids" => #{security_groups.to_s}, \
|
|
91
|
+
"user_data" => "#{user_data}", \
|
|
92
|
+
"iam_instance_profile" => "#{iam_instance_profile}", \
|
|
93
|
+
"kernel_id" => "#{kernel_id}", \
|
|
94
|
+
"key_name" => "#{key_name}", \
|
|
95
|
+
"spot_price" => "#{spot_price}", \
|
|
96
|
+
"created_time" => "#{created_time}", \
|
|
97
|
+
"block_device_mappings" => #{block_device_mappings}", \
|
|
98
|
+
"ebs_optimized" => #{ebs_optimized} \
|
|
99
|
+
}}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def corrected_user_data
|
|
103
|
+
realized_user_data = user_data.is_a?(Proc) ? user_data.call : user_data
|
|
104
|
+
|
|
105
|
+
Base64.encode64(Aerosol::Util.strip_heredoc(realized_user_data || ''))
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
def create_options
|
|
110
|
+
instance_market_options = {
|
|
111
|
+
market_type: 'spot',
|
|
112
|
+
spot_options: {
|
|
113
|
+
max_price: spot_price
|
|
114
|
+
}
|
|
115
|
+
} if spot_price
|
|
116
|
+
|
|
117
|
+
{
|
|
118
|
+
iam_instance_profile: { name: iam_instance_profile },
|
|
119
|
+
kernel_id: kernel_id,
|
|
120
|
+
key_name: key_name,
|
|
121
|
+
security_group_ids: security_groups,
|
|
122
|
+
instance_market_options: instance_market_options,
|
|
123
|
+
user_data: corrected_user_data,
|
|
124
|
+
network_interfaces: network_interfaces,
|
|
125
|
+
block_device_mappings: block_device_mappings,
|
|
126
|
+
ebs_optimized: ebs_optimized,
|
|
127
|
+
}.reject { |k, v| v.nil? }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def conn
|
|
131
|
+
Aerosol::AWS.compute
|
|
132
|
+
end
|
|
133
|
+
end
|
data/lib/aerosol/version.rb
CHANGED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Aerosol::LaunchTemplate do
|
|
4
|
+
subject do
|
|
5
|
+
described_class.new do
|
|
6
|
+
name :my_launch_template
|
|
7
|
+
image_id 'ami-123'
|
|
8
|
+
instance_type 'super-cool-instance-type'
|
|
9
|
+
user_data <<-END_OF_STRING
|
|
10
|
+
#!/bin/bash
|
|
11
|
+
rm -rf /
|
|
12
|
+
END_OF_STRING
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
before { subject.stub(:sleep) }
|
|
16
|
+
|
|
17
|
+
describe "#launch_template_name" do
|
|
18
|
+
context "with no namespace set" do
|
|
19
|
+
let(:identifier) { "my_launch_template-#{Aerosol::Util.git_sha}" }
|
|
20
|
+
it "returns a normal identifier" do
|
|
21
|
+
expect(subject.launch_template_name).to eq(identifier)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "with a namespace set" do
|
|
26
|
+
let(:namespace) { "test" }
|
|
27
|
+
let(:identifier) { "#{namespace}-my_launch_template-#{Aerosol::Util.git_sha}" }
|
|
28
|
+
|
|
29
|
+
before { Aerosol.namespace namespace }
|
|
30
|
+
after { Aerosol.instance_variable_set(:"@namespace", nil) }
|
|
31
|
+
|
|
32
|
+
it "returns a namespaced identifier" do
|
|
33
|
+
expect(subject.launch_template_name).to eq(identifier)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '#security_group' do
|
|
39
|
+
subject { described_class.new!(:name => 'conf-conf-conf') }
|
|
40
|
+
|
|
41
|
+
it 'adds the argument to the list of security groups' do
|
|
42
|
+
expect { subject.security_group 'my group' }
|
|
43
|
+
.to change { subject.security_groups.length }
|
|
44
|
+
.by 1
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'does not the default security group' do
|
|
48
|
+
expect { subject.security_group 'other test' }
|
|
49
|
+
.to_not change { described_class.default_values[:security_groups] }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '#create!' do
|
|
54
|
+
context 'when some required fields are nil' do
|
|
55
|
+
before { subject.instance_variable_set(:@image_id, nil) }
|
|
56
|
+
|
|
57
|
+
it 'raises an error' do
|
|
58
|
+
expect { subject.create! }.to raise_error
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'when everything is present' do
|
|
63
|
+
context 'and the launch template already exists' do
|
|
64
|
+
it 'raises an error' do
|
|
65
|
+
Aerosol::AWS.compute.stub_responses(
|
|
66
|
+
:create_launch_template,
|
|
67
|
+
Aws::EC2::Errors::AlreadyExists
|
|
68
|
+
)
|
|
69
|
+
expect { subject.create! }.to raise_error
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'and the launch template does not exist yet' do
|
|
74
|
+
after { subject.destroy! rescue nil }
|
|
75
|
+
|
|
76
|
+
it 'creates the launch template group' do
|
|
77
|
+
Aerosol::AWS.compute.stub_responses(:create_launch_template, [])
|
|
78
|
+
expect { subject.create! }.to_not raise_error
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe '#destroy!' do
|
|
85
|
+
context 'when the launch_template_name is nil' do
|
|
86
|
+
|
|
87
|
+
it 'raises an error' do
|
|
88
|
+
allow(subject).to receive(:launch_template_name).and_return(nil)
|
|
89
|
+
Aerosol::AWS.compute.stub_responses(:delete_launch_template, [])
|
|
90
|
+
expect { subject.destroy! }.to raise_error
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context 'when the launch_template_name is present' do
|
|
95
|
+
context 'but the launch template does not exist' do
|
|
96
|
+
it 'raises an error' do
|
|
97
|
+
Aerosol::AWS.compute.stub_responses(
|
|
98
|
+
:delete_launch_template,
|
|
99
|
+
Aws::EC2::Errors::ValidationError
|
|
100
|
+
)
|
|
101
|
+
expect { subject.destroy! }.to raise_error
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context 'and the launch template exists' do
|
|
106
|
+
it 'deletes the launch template' do
|
|
107
|
+
Aerosol::AWS.compute.stub_responses(:delete_launch_template, [])
|
|
108
|
+
expect { subject.destroy! }.to_not raise_error
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe '#create' do
|
|
115
|
+
context 'when the launch_template_name is nil' do
|
|
116
|
+
subject do
|
|
117
|
+
described_class.new! do
|
|
118
|
+
name :random_test_name
|
|
119
|
+
image_id 'test-ami-who-even-cares-really'
|
|
120
|
+
instance_type 'm1.large'
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'raises an error' do
|
|
125
|
+
allow(subject).to receive(:launch_template_name).and_return(nil)
|
|
126
|
+
Aerosol::AWS.compute.stub_responses(:create_launch_template, [])
|
|
127
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
128
|
+
launch_templates: [], next_token: nil
|
|
129
|
+
})
|
|
130
|
+
expect { subject.create }.to raise_error
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context 'when the launch_template_name is present' do
|
|
135
|
+
subject do
|
|
136
|
+
described_class.new! do
|
|
137
|
+
name :random_test_name_2
|
|
138
|
+
image_id 'test-ami-who-even-cares-really'
|
|
139
|
+
instance_type 'm1.large'
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context 'but the launch template already exists' do
|
|
144
|
+
it 'does not call #create!' do
|
|
145
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
146
|
+
launch_templates: [{
|
|
147
|
+
launch_template_name: subject.launch_template_name,
|
|
148
|
+
}],
|
|
149
|
+
next_token: nil
|
|
150
|
+
})
|
|
151
|
+
expect(subject).to_not receive(:create!)
|
|
152
|
+
subject.create
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context 'and the launch template does not yet exist' do
|
|
157
|
+
it 'creates it' do
|
|
158
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
159
|
+
launch_templates: [],
|
|
160
|
+
next_token: nil
|
|
161
|
+
})
|
|
162
|
+
subject.should_receive(:create!)
|
|
163
|
+
subject.create
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe '#destroy' do
|
|
170
|
+
subject do
|
|
171
|
+
described_class.new! do
|
|
172
|
+
name :random_test_name_3
|
|
173
|
+
image_id 'awesome-ami'
|
|
174
|
+
instance_type 'm1.large'
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context 'when the launch_template_name is nil' do
|
|
179
|
+
it 'raises an error' do
|
|
180
|
+
allow(subject).to receive(:launch_template_name).and_return(nil)
|
|
181
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
182
|
+
launch_templates: [],
|
|
183
|
+
next_token: nil
|
|
184
|
+
})
|
|
185
|
+
expect { subject.create }.to raise_error(ArgumentError)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context 'when the launch_template_name is present' do
|
|
190
|
+
context 'and the launch template already exists' do
|
|
191
|
+
|
|
192
|
+
it 'calls #destroy!' do
|
|
193
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
194
|
+
launch_templates: [{
|
|
195
|
+
launch_template_name: subject.launch_template_name
|
|
196
|
+
}],
|
|
197
|
+
next_token: nil
|
|
198
|
+
})
|
|
199
|
+
subject.should_receive(:destroy!)
|
|
200
|
+
subject.destroy
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
context 'but the launch template does not yet exist' do
|
|
205
|
+
it 'does not call #destroy!' do
|
|
206
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
207
|
+
launch_templates: [],
|
|
208
|
+
next_token: nil
|
|
209
|
+
})
|
|
210
|
+
subject.should_not_receive(:destroy!)
|
|
211
|
+
subject.destroy
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
describe '.exists?' do
|
|
218
|
+
subject { described_class }
|
|
219
|
+
let(:instance) do
|
|
220
|
+
subject.new! do
|
|
221
|
+
name :exists_test_name
|
|
222
|
+
image_id 'ami123'
|
|
223
|
+
instance_type 'm1.large'
|
|
224
|
+
stub(:sleep)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
context 'when the argument exists' do
|
|
229
|
+
it 'returns true' do
|
|
230
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
231
|
+
launch_templates: [{
|
|
232
|
+
launch_template_name: instance.launch_template_name,
|
|
233
|
+
}],
|
|
234
|
+
next_token: nil
|
|
235
|
+
})
|
|
236
|
+
subject.exists?(instance.launch_template_name).should be_true
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
context 'when the argument does not exist' do
|
|
241
|
+
let(:instance) { described_class.new! }
|
|
242
|
+
|
|
243
|
+
it 'returns false' do
|
|
244
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
245
|
+
launch_templates: [],
|
|
246
|
+
next_token: nil
|
|
247
|
+
})
|
|
248
|
+
subject.exists?(instance.launch_template_name).should be_false
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe '.request_all' do
|
|
254
|
+
describe 'repeats until no NextToken' do
|
|
255
|
+
it 'should include both autoscaling groups lists' do
|
|
256
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, [
|
|
257
|
+
{
|
|
258
|
+
launch_templates: [
|
|
259
|
+
{ launch_template_name: '1' },
|
|
260
|
+
{ launch_template_name: '4' }
|
|
261
|
+
],
|
|
262
|
+
next_token: 'yes'
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
launch_templates: [
|
|
266
|
+
{ launch_template_name: '2' },
|
|
267
|
+
{ launch_template_name: '3' }
|
|
268
|
+
],
|
|
269
|
+
next_token: nil
|
|
270
|
+
}
|
|
271
|
+
])
|
|
272
|
+
expect(Aerosol::LaunchTemplate.request_all.map(&:launch_template_name)).to eq(['1','4','2','3'])
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
describe '.all' do
|
|
278
|
+
subject { described_class }
|
|
279
|
+
|
|
280
|
+
context 'when there are no launch templates' do
|
|
281
|
+
before do
|
|
282
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, [
|
|
283
|
+
{ launch_templates: [], next_token: nil }
|
|
284
|
+
])
|
|
285
|
+
end
|
|
286
|
+
its(:all) { should be_empty }
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context 'when there are launch templates' do
|
|
290
|
+
let(:insts) {
|
|
291
|
+
[
|
|
292
|
+
{ launch_template_name: 'test' },
|
|
293
|
+
{ launch_template_name: 'test2' }
|
|
294
|
+
]
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
it 'returns each of them' do
|
|
298
|
+
Aerosol::AWS.compute.stub_responses(:describe_launch_templates, {
|
|
299
|
+
launch_templates: insts,
|
|
300
|
+
next_token: nil
|
|
301
|
+
})
|
|
302
|
+
subject.all.map(&:launch_template_name).should == %w[test test2]
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe '.from_hash' do
|
|
308
|
+
context 'when the launch template has not been initialized' do
|
|
309
|
+
subject { described_class.from_hash(hash) }
|
|
310
|
+
let(:hash) do
|
|
311
|
+
{
|
|
312
|
+
launch_template_name: '~test-launch-config~',
|
|
313
|
+
image_id: 'ami-123',
|
|
314
|
+
instance_type: 'm1.large',
|
|
315
|
+
security_groups: [],
|
|
316
|
+
user_data: 'echo hi',
|
|
317
|
+
iam_instance_profile: nil,
|
|
318
|
+
kernel_id: 'kernel-id',
|
|
319
|
+
key_name: 'key-name',
|
|
320
|
+
spot_price: '0.04',
|
|
321
|
+
}
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'creates a new launch template with the specified values' do
|
|
325
|
+
subject.launch_template_name.should == '~test-launch-config~'
|
|
326
|
+
subject.image_id.should == 'ami-123'
|
|
327
|
+
subject.instance_type.should == 'm1.large'
|
|
328
|
+
subject.security_groups.should be_empty
|
|
329
|
+
subject.user_data.should == 'echo hi'
|
|
330
|
+
subject.iam_instance_profile.should be_nil
|
|
331
|
+
subject.kernel_id.should == 'kernel-id'
|
|
332
|
+
subject.spot_price.should == '0.04'
|
|
333
|
+
subject.from_aws = true
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it 'generates a name' do
|
|
337
|
+
subject.name.to_s.should start_with 'LaunchTemplate_'
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
context 'when the launch template has already been initialized' do
|
|
342
|
+
let(:old_hash) do
|
|
343
|
+
{
|
|
344
|
+
launch_template_name: 'this-aws-id-abc-123',
|
|
345
|
+
image_id: 'ami-456',
|
|
346
|
+
}
|
|
347
|
+
end
|
|
348
|
+
let(:new_hash) { old_hash.merge(instance_type: 'm1.large') }
|
|
349
|
+
let!(:existing) { described_class.from_hash(old_hash) }
|
|
350
|
+
let(:new) { described_class.from_hash(new_hash) }
|
|
351
|
+
|
|
352
|
+
it 'makes a new instance' do
|
|
353
|
+
expect { new }.to change { described_class.instances.length }.by(1)
|
|
354
|
+
new.launch_template_name.should == 'this-aws-id-abc-123'
|
|
355
|
+
new.image_id.should == 'ami-456'
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
describe '#corrected_user_data' do
|
|
361
|
+
let(:encoded_user_data_string) { Base64.encode64('test') }
|
|
362
|
+
|
|
363
|
+
context 'when the user_data is a String' do
|
|
364
|
+
subject do
|
|
365
|
+
described_class.new do
|
|
366
|
+
name :corrected_user_data
|
|
367
|
+
user_data 'test'
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it 'correctly encodes to base64' do
|
|
372
|
+
expect(subject.corrected_user_data).to eq(encoded_user_data_string)
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
context 'when the user_data is a Proc' do
|
|
377
|
+
subject do
|
|
378
|
+
described_class.new do
|
|
379
|
+
name :corrected_user_data_2
|
|
380
|
+
user_data { 'test' }
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it 'correctly encodes to base64' do
|
|
385
|
+
expect(subject.corrected_user_data).to eq(encoded_user_data_string)
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
describe '#meta_data' do
|
|
391
|
+
subject do
|
|
392
|
+
described_class.new do
|
|
393
|
+
name :my_launch_template
|
|
394
|
+
meta_data('Test' => '1')
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it 'returns the hash' do
|
|
399
|
+
expect(subject.meta_data['Test']).to eq('1')
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aerosol
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Swipely, Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-02-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -280,6 +280,7 @@ files:
|
|
|
280
280
|
- lib/aerosol/env.rb
|
|
281
281
|
- lib/aerosol/instance.rb
|
|
282
282
|
- lib/aerosol/launch_configuration.rb
|
|
283
|
+
- lib/aerosol/launch_template.rb
|
|
283
284
|
- lib/aerosol/rake_task.rb
|
|
284
285
|
- lib/aerosol/runner.rb
|
|
285
286
|
- lib/aerosol/util.rb
|
|
@@ -292,6 +293,7 @@ files:
|
|
|
292
293
|
- spec/aerosol/env_spec.rb
|
|
293
294
|
- spec/aerosol/instance_spec.rb
|
|
294
295
|
- spec/aerosol/launch_configuration_spec.rb
|
|
296
|
+
- spec/aerosol/launch_template_spec.rb
|
|
295
297
|
- spec/aerosol/rake_task_spec.rb
|
|
296
298
|
- spec/aerosol/runner_spec.rb
|
|
297
299
|
- spec/aerosol_spec.rb
|
|
@@ -329,6 +331,7 @@ test_files:
|
|
|
329
331
|
- spec/aerosol/env_spec.rb
|
|
330
332
|
- spec/aerosol/instance_spec.rb
|
|
331
333
|
- spec/aerosol/launch_configuration_spec.rb
|
|
334
|
+
- spec/aerosol/launch_template_spec.rb
|
|
332
335
|
- spec/aerosol/rake_task_spec.rb
|
|
333
336
|
- spec/aerosol/runner_spec.rb
|
|
334
337
|
- spec/aerosol_spec.rb
|