sumomo 0.8.9 → 0.8.13
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/README.md +12 -11
- data/data/sumomo/custom_resources/{USEastCertificate.js → ACMCertificate.js} +8 -3
- data/data/sumomo/custom_resources/{USEastCertificateWaiter.js → ACMCertificateWaiter.js} +3 -1
- data/data/sumomo/custom_resources/AMILookup.js +378 -150
- data/data/sumomo/custom_resources/SelectSpot.js +376 -142
- data/exe/sumomo +12 -2
- data/lib/sumomo/api.rb +120 -9
- data/lib/sumomo/ec2.rb +9 -6
- data/lib/sumomo/stack.rb +1 -1
- data/lib/sumomo/version.rb +1 -1
- data/lib/sumomo.rb +33 -5
- data/sumomo.gemspec +6 -4
- data/update-spec.rb +381 -0
- metadata +51 -22
data/exe/sumomo
CHANGED
@@ -30,7 +30,7 @@ cmd_opts = case cmd
|
|
30
30
|
when 'delete'
|
31
31
|
Sumomo.delete_stack(name: ARGV[0], region: global_opts[:region])
|
32
32
|
|
33
|
-
when 'create'
|
33
|
+
when 'create'
|
34
34
|
local_opts = Trollop.options do
|
35
35
|
opt :filename, 'File that describes the stack', type: :string, default: 'Sumomofile'
|
36
36
|
end
|
@@ -39,6 +39,16 @@ cmd_opts = case cmd
|
|
39
39
|
eval File.read(local_opts[:filename]), proc.binding, local_opts[:filename]
|
40
40
|
end
|
41
41
|
|
42
|
+
when 'update'
|
43
|
+
local_opts = Trollop.options do
|
44
|
+
opt :filename, 'File that describes the stack', type: :string, default: 'Sumomofile'
|
45
|
+
opt :changeset, 'Create a changeset instead of directly update', type: :boolean, default: false
|
46
|
+
end
|
47
|
+
Sumomo.update_stack(name: ARGV[0], changeset: !!local_opts[:changeset], region: global_opts[:region]) do
|
48
|
+
proc = proc {}
|
49
|
+
eval File.read(local_opts[:filename]), proc.binding, local_opts[:filename]
|
50
|
+
end
|
51
|
+
|
42
52
|
when 'outputs'
|
43
53
|
puts "Outputs for stack #{ARGV[0]}"
|
44
54
|
puts Sumomo.get_stack_outputs(name: ARGV[0], region: global_opts[:region]).to_yaml
|
@@ -49,7 +59,7 @@ cmd_opts = case cmd
|
|
49
59
|
key = JSON.parse(File.read('x.txt'))['value']
|
50
60
|
File.write('key.pem', key)
|
51
61
|
`chmod 0600 key.pem`
|
52
|
-
exec "ssh -i 'key.pem' ec2-user@#{ARGV[1]}"
|
62
|
+
exec "ssh -i 'key.pem' ec2-user@#{ARGV[1]} #{ARGV[2]}"
|
53
63
|
|
54
64
|
when 'testapi'
|
55
65
|
local_opts = Trollop.options do
|
data/lib/sumomo/api.rb
CHANGED
@@ -159,9 +159,45 @@ module Sumomo
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
-
def make_api(
|
162
|
+
def make_api(
|
163
|
+
domain_name,
|
164
|
+
name:,
|
165
|
+
script: nil,
|
166
|
+
dns: nil,
|
167
|
+
cert: nil,
|
168
|
+
mtls_truststore: nil,
|
169
|
+
logging: true,
|
170
|
+
with_statements: [], &block)
|
171
|
+
|
163
172
|
api = make 'AWS::ApiGateway::RestApi', name: name do
|
164
173
|
Name name
|
174
|
+
DisableExecuteApiEndpoint true
|
175
|
+
end
|
176
|
+
|
177
|
+
if logging
|
178
|
+
cloudwatchRole = make 'AWS::IAM::Role', name: "#{name}LoggingRole" do
|
179
|
+
AssumeRolePolicyDocument do
|
180
|
+
Version "2012-10-17"
|
181
|
+
Statement [
|
182
|
+
{
|
183
|
+
"Effect" => "Allow",
|
184
|
+
"Principal" => {
|
185
|
+
"Service" => [
|
186
|
+
"apigateway.amazonaws.com"
|
187
|
+
]
|
188
|
+
},
|
189
|
+
"Action" => "sts:AssumeRole"
|
190
|
+
}
|
191
|
+
]
|
192
|
+
end
|
193
|
+
Path '/'
|
194
|
+
ManagedPolicyArns [ "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" ]
|
195
|
+
end
|
196
|
+
|
197
|
+
make 'AWS::ApiGateway::Account' do
|
198
|
+
depends_on api
|
199
|
+
CloudWatchRoleArn cloudwatchRole.Arn
|
200
|
+
end
|
165
201
|
end
|
166
202
|
|
167
203
|
script ||= File.read(File.join(Gem.loaded_specs['sumomo'].full_gem_path, 'data', 'sumomo', 'api_modules', 'real_script.js'))
|
@@ -183,7 +219,10 @@ module Sumomo
|
|
183
219
|
|
184
220
|
files += [{ name: 'index.js', code: script }]
|
185
221
|
|
186
|
-
fun = make_lambda(
|
222
|
+
fun = make_lambda(
|
223
|
+
name: "#{name}Lambda#{@version_number}",
|
224
|
+
files: files,
|
225
|
+
role: custom_resource_exec_role(with_statements: with_statements) )
|
187
226
|
|
188
227
|
resource = make 'AWS::ApiGateway::Resource', name: "#{name}Resource" do
|
189
228
|
ParentId api.RootResourceId
|
@@ -230,18 +269,79 @@ module Sumomo
|
|
230
269
|
stage = make 'AWS::ApiGateway::Stage', name: "#{name}Stage" do
|
231
270
|
RestApiId api
|
232
271
|
DeploymentId deployment
|
233
|
-
|
272
|
+
|
273
|
+
if logging
|
274
|
+
MethodSettings [
|
275
|
+
{
|
276
|
+
"ResourcePath" => "/*",
|
277
|
+
"HttpMethod" => "*",
|
278
|
+
"DataTraceEnabled" => true,
|
279
|
+
"LoggingLevel" => 'INFO'
|
280
|
+
}
|
281
|
+
]
|
282
|
+
end
|
234
283
|
end
|
235
284
|
|
236
285
|
root_name = /(?<root_name>[^.]+\.[^.]+)$/.match(domain_name)[:root_name]
|
237
286
|
|
238
|
-
|
239
|
-
|
287
|
+
certificate_completion = cert
|
288
|
+
|
289
|
+
bucket_name = @bucket_name
|
290
|
+
mtls = nil
|
291
|
+
if mtls_truststore
|
292
|
+
filename = "#{domain_name}.truststore.pem"
|
293
|
+
upload_file(filename, mtls_truststore)
|
294
|
+
truststore_uri = "s3://#{bucket_name}/uploads/#{filename}"
|
295
|
+
mtls = {
|
296
|
+
"TruststoreUri" => truststore_uri
|
297
|
+
}
|
240
298
|
end
|
241
299
|
|
242
|
-
|
300
|
+
if cert.nil?
|
301
|
+
cert = make 'Custom::ACMCertificate', name: "#{name}Certificate" do
|
302
|
+
DomainName domain_name
|
303
|
+
ValidationMethod 'DNS' if dns[:type] == :route53
|
304
|
+
RegionOverride 'us-east-1' if !mtls
|
305
|
+
end
|
306
|
+
|
307
|
+
certificate_completion = cert
|
308
|
+
|
309
|
+
if dns[:type] == :route53
|
310
|
+
make 'AWS::Route53::RecordSet', name: "#{name}CertificateRoute53Entry" do
|
311
|
+
HostedZoneId dns[:hosted_zone]
|
312
|
+
Name cert.RecordName
|
313
|
+
Type cert.RecordType
|
314
|
+
TTL 60
|
315
|
+
ResourceRecords [cert.RecordValue]
|
316
|
+
end
|
317
|
+
|
318
|
+
cert_waiter = make 'Custom::ACMCertificateWaiter', name: "#{name}CertificateWaiter" do
|
319
|
+
Certificate cert
|
320
|
+
RegionOverride 'us-east-1' if !mtls
|
321
|
+
end
|
322
|
+
|
323
|
+
certificate_completion = cert_waiter
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
domain = make 'AWS::ApiGateway::DomainName', name: "#{name}DomainName" do
|
328
|
+
depends_on certificate_completion
|
329
|
+
|
243
330
|
DomainName domain_name
|
244
|
-
|
331
|
+
|
332
|
+
if mtls != nil
|
333
|
+
RegionalCertificateArn cert
|
334
|
+
MutualTlsAuthentication mtls
|
335
|
+
SecurityPolicy 'TLS_1_2'
|
336
|
+
EndpointConfiguration do
|
337
|
+
Types [ 'REGIONAL' ]
|
338
|
+
end
|
339
|
+
else
|
340
|
+
CertificateArn cert
|
341
|
+
EndpointConfiguration do
|
342
|
+
Types [ 'EDGE' ]
|
343
|
+
end
|
344
|
+
end
|
245
345
|
end
|
246
346
|
|
247
347
|
make 'AWS::ApiGateway::BasePathMapping', name: "#{name}BasePathMapping" do
|
@@ -264,8 +364,19 @@ module Sumomo
|
|
264
364
|
make 'AWS::Route53::RecordSet', name: "#{name}Route53Entry" do
|
265
365
|
HostedZoneId dns[:hosted_zone]
|
266
366
|
Name domain_name
|
267
|
-
|
268
|
-
|
367
|
+
|
368
|
+
if mtls != nil
|
369
|
+
Type 'A'
|
370
|
+
AliasTarget do
|
371
|
+
DNSName domain.RegionalDomainName
|
372
|
+
HostedZoneId domain.RegionalHostedZoneId
|
373
|
+
end
|
374
|
+
else
|
375
|
+
Type 'A'
|
376
|
+
AliasTarget do
|
377
|
+
DNSName domain.DistributionDomainName
|
378
|
+
HostedZoneId domain.DistributionHostedZoneId
|
379
|
+
end end
|
269
380
|
end
|
270
381
|
domain_name
|
271
382
|
else
|
data/lib/sumomo/ec2.rb
CHANGED
@@ -254,6 +254,7 @@ module Sumomo
|
|
254
254
|
has_public_ips: true,
|
255
255
|
ingress: nil,
|
256
256
|
egress: nil,
|
257
|
+
security_groups: [],
|
257
258
|
machine_tag: nil,
|
258
259
|
ec2_sns_arn: nil,
|
259
260
|
ami_name: nil,
|
@@ -297,10 +298,12 @@ module Sumomo
|
|
297
298
|
|
298
299
|
bucket_name = @bucket_name
|
299
300
|
|
300
|
-
|
301
|
+
script_arr = [script]
|
302
|
+
|
303
|
+
script_arr << task_script
|
301
304
|
|
302
305
|
if ecs_cluster
|
303
|
-
|
306
|
+
script_arr << <<~ECS_START
|
304
307
|
|
305
308
|
yum update
|
306
309
|
yum groupinstall "Development Tools"
|
@@ -318,12 +321,12 @@ module Sumomo
|
|
318
321
|
end
|
319
322
|
|
320
323
|
if eip
|
321
|
-
|
324
|
+
script_arr << <<~EIP_ALLOCATE
|
322
325
|
aws ec2 associate-address --region `cat /etc/aws_region` --instance-id `curl http://169.254.169.254/latest/meta-data/instance-id` --allocation-id `cat /etc/eip_allocation_id`
|
323
326
|
EIP_ALLOCATE
|
324
327
|
end
|
325
328
|
|
326
|
-
|
329
|
+
script_arr << "service spot-watcher start" if(spot_price && ec2_sns_arn)
|
327
330
|
|
328
331
|
unless ingress.is_a? Array
|
329
332
|
raise 'ec2: ingress option needs to be an array'
|
@@ -339,7 +342,7 @@ module Sumomo
|
|
339
342
|
|
340
343
|
wait_handle = make 'AWS::CloudFormation::WaitConditionHandle'
|
341
344
|
|
342
|
-
user_data = initscript(wait_handle, name,
|
345
|
+
user_data = initscript(wait_handle, name, call('Fn::Join', "\n", script_arr))
|
343
346
|
|
344
347
|
role_policy_doc = {
|
345
348
|
'Version' => '2012-10-17',
|
@@ -407,7 +410,7 @@ module Sumomo
|
|
407
410
|
launch_config = make 'AWS::AutoScaling::LaunchConfiguration' do
|
408
411
|
AssociatePublicIpAddress has_public_ips
|
409
412
|
KeyName keypair
|
410
|
-
SecurityGroups [web_sec_group]
|
413
|
+
SecurityGroups [web_sec_group] + security_groups
|
411
414
|
ImageId ami_name
|
412
415
|
UserData user_data
|
413
416
|
InstanceType type
|
data/lib/sumomo/stack.rb
CHANGED
data/lib/sumomo/version.rb
CHANGED
data/lib/sumomo.rb
CHANGED
@@ -26,7 +26,17 @@ module Sumomo
|
|
26
26
|
"cloudformation/#{make_master_key_name(name: name)}.pem"
|
27
27
|
end
|
28
28
|
|
29
|
-
def self.
|
29
|
+
def self.create_stack(name:, region:, sns_arn: nil, &block)
|
30
|
+
cf = Aws::CloudFormation::Client.new(region: region)
|
31
|
+
begin
|
32
|
+
cf.describe_stacks(stack_name: name)
|
33
|
+
raise "There is already a stack named '#{name}'"
|
34
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
35
|
+
update_stack(name: name, region: region, sns_arn: sns_arn, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.update_stack(name:, region:, sns_arn: nil, changeset: false, &block)
|
30
40
|
cf = Aws::CloudFormation::Client.new(region: region)
|
31
41
|
s3 = Aws::S3::Client.new(region: region)
|
32
42
|
ec2 = Aws::EC2::Client.new(region: region)
|
@@ -107,11 +117,20 @@ module Sumomo
|
|
107
117
|
stack_name: name,
|
108
118
|
template_url: store.url('cloudformation/template'),
|
109
119
|
parameters: hidden_values,
|
120
|
+
disable_rollback: true,
|
110
121
|
capabilities: ['CAPABILITY_IAM']
|
111
122
|
}
|
112
123
|
|
113
124
|
begin
|
114
|
-
|
125
|
+
if changeset
|
126
|
+
cf.create_change_set(
|
127
|
+
**update_options,
|
128
|
+
change_set_name: "Change#{curtimestr}"
|
129
|
+
)
|
130
|
+
else
|
131
|
+
cf.update_stack(update_options)
|
132
|
+
end
|
133
|
+
|
115
134
|
rescue StandardError => e
|
116
135
|
if e.message.end_with? 'does not exist'
|
117
136
|
update_options[:timeout_in_minutes] = @timeout if @timeout
|
@@ -124,6 +143,10 @@ module Sumomo
|
|
124
143
|
end
|
125
144
|
end
|
126
145
|
|
146
|
+
def self.curtimestr
|
147
|
+
Time.now.strftime('%Y%m%d%H%M%S')
|
148
|
+
end
|
149
|
+
|
127
150
|
def self.wait_for_stack(name:, region:)
|
128
151
|
cf = Aws::CloudFormation::Client.new(region: region)
|
129
152
|
|
@@ -187,7 +210,14 @@ module Sumomo
|
|
187
210
|
instance_eval(&block)
|
188
211
|
end
|
189
212
|
|
190
|
-
def make_api(_domain_name,
|
213
|
+
def make_api(_domain_name,
|
214
|
+
name:, script: nil,
|
215
|
+
dns: nil,
|
216
|
+
mtls_truststore: nil,
|
217
|
+
cert: nil,
|
218
|
+
with_statements: [], &block)
|
219
|
+
|
220
|
+
# we ignore mtls_truststore here
|
191
221
|
@apis[name] = block
|
192
222
|
end
|
193
223
|
|
@@ -249,6 +279,4 @@ module Sumomo
|
|
249
279
|
|
250
280
|
map
|
251
281
|
end
|
252
|
-
|
253
|
-
singleton_class.send(:alias_method, :create_stack, :update_stack)
|
254
282
|
end
|
data/sumomo.gemspec
CHANGED
@@ -27,15 +27,17 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
|
-
spec.add_development_dependency 'bundler'
|
31
|
-
spec.add_development_dependency 'rake'
|
32
|
-
spec.add_development_dependency 'rspec'
|
30
|
+
spec.add_development_dependency 'bundler'
|
31
|
+
spec.add_development_dependency 'rake'
|
32
|
+
spec.add_development_dependency 'rspec'
|
33
33
|
|
34
34
|
spec.add_dependency 'activesupport'
|
35
|
-
spec.add_dependency 'aws-sdk', '~>
|
35
|
+
spec.add_dependency 'aws-sdk', '~> 3'
|
36
|
+
spec.add_dependency 'ox'
|
36
37
|
spec.add_dependency 'hashie'
|
37
38
|
spec.add_dependency 'momo', '0.4.1'
|
38
39
|
spec.add_dependency 'rubyzip'
|
39
40
|
spec.add_dependency 's3cabinet'
|
40
41
|
spec.add_dependency 'trollop'
|
42
|
+
spec.add_dependency 'webrick'
|
41
43
|
end
|