lambda_wrap 1.0.2 → 1.0.3
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 +5 -5
- data/lib/lambda_wrap/api_gateway_manager.rb +26 -22
- data/lib/lambda_wrap/dynamo_db_manager.rb +31 -18
- data/lib/lambda_wrap/lambda_manager.rb +43 -39
- data/lib/lambda_wrap/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: dcab068ec4b93c5c11e66bdd0686aad997b52e48573e5e581f8363c56dbc96f0
|
4
|
+
data.tar.gz: 267570d242c1343f5c1d9197272eecdce1f9ce658cf73c960791c4a83afb8674
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78708a6551a1ff4296d156b941489e5782163e01f79ba96ffca23cbc1af9abc609ae8fc9c835b8de01908a6d7ad54247bf4df1e103361f4af79ab69bc1186a2a
|
7
|
+
data.tar.gz: 1d5c73b0c6054339e74f6566937a2e18064443c23f68085ab900d505a2ecd820f6a43167ef9eea3546729581e7fa0b54378879ac50aade775eb72e768d2a3c2e
|
@@ -39,20 +39,20 @@ module LambdaWrap
|
|
39
39
|
api_id = get_id_for_api(@api_name)
|
40
40
|
service_response =
|
41
41
|
if api_id
|
42
|
-
|
42
|
+
options = {
|
43
43
|
fail_on_warnings: false, mode: @import_mode, rest_api_id:
|
44
|
-
api_id, body: File.
|
45
|
-
|
44
|
+
api_id, body: File.binread(@path_to_swagger_file)
|
45
|
+
}
|
46
|
+
@client.put_rest_api(options)
|
46
47
|
else
|
47
|
-
|
48
|
+
options = {
|
48
49
|
fail_on_warnings: false,
|
49
|
-
body: File.
|
50
|
-
|
50
|
+
body: File.binread(@path_to_swagger_file)
|
51
|
+
}
|
52
|
+
@client.import_rest_api(options)
|
51
53
|
end
|
52
54
|
|
53
|
-
if service_response.nil? || service_response.id.nil?
|
54
|
-
raise "Failed to create API gateway with name #{@api_name}"
|
55
|
-
end
|
55
|
+
raise "Failed to create API gateway with name #{@api_name}" if service_response.nil? || service_response.id.nil?
|
56
56
|
|
57
57
|
if api_id
|
58
58
|
"Created API Gateway Object: #{@api_name} having id #{service_response.id}"
|
@@ -92,7 +92,10 @@ module LambdaWrap
|
|
92
92
|
super
|
93
93
|
api_id = get_id_for_api(@api_name)
|
94
94
|
if api_id
|
95
|
-
|
95
|
+
options = {
|
96
|
+
rest_api_id: api_id
|
97
|
+
}
|
98
|
+
@client.delete_rest_api(options)
|
96
99
|
puts "Deleted API: #{@api_name} ID:#{api_id}"
|
97
100
|
else
|
98
101
|
puts "API Gateway Object #{@api_name} not found. Nothing to delete."
|
@@ -108,7 +111,10 @@ module LambdaWrap
|
|
108
111
|
private
|
109
112
|
|
110
113
|
def delete_stage(api_id, env)
|
111
|
-
|
114
|
+
options = {
|
115
|
+
rest_api_id: api_id, stage_name: env
|
116
|
+
}
|
117
|
+
@client.delete_stage(options)
|
112
118
|
puts 'Deleted API gateway stage ' + env
|
113
119
|
rescue Aws::APIGateway::Errors::NotFoundException
|
114
120
|
puts "API Gateway stage #{env} does not exist. Nothing to delete."
|
@@ -118,17 +124,16 @@ module LambdaWrap
|
|
118
124
|
deployment_description = "Deploying API #{@api_name} v#{@api_version}\
|
119
125
|
to Environment:#{environment_options.name}"
|
120
126
|
stage_description = "#{environment_options.name} - #{environment_options.description}"
|
121
|
-
|
127
|
+
options = {
|
122
128
|
rest_api_id: api_id, stage_name: environment_options.name,
|
123
129
|
stage_description: stage_description, description: deployment_description,
|
124
130
|
cache_cluster_enabled: false, variables: environment_options.variables
|
125
|
-
|
131
|
+
}
|
132
|
+
@client.create_deployment(options)
|
126
133
|
end
|
127
134
|
|
128
135
|
def extract_specification(file_path)
|
129
|
-
unless File.exist?(file_path)
|
130
|
-
raise ArgumentError, "Open API Spec (Swagger) File does not exist: #{file_path}!"
|
131
|
-
end
|
136
|
+
raise ArgumentError, "Open API Spec (Swagger) File does not exist: #{file_path}!" unless File.exist?(file_path)
|
132
137
|
spec = Psych.load_file(file_path)
|
133
138
|
raise ArgumentError, 'LambdaWrap only supports swagger v2.0' unless spec['swagger'] == '2.0'
|
134
139
|
raise ArgumentError, 'Invalid Title field in the OAPISpec' unless spec['info']['title'] =~ /[A-Za-z0-9]{1,1024}/
|
@@ -138,12 +143,11 @@ module LambdaWrap
|
|
138
143
|
def get_id_for_api(api_name)
|
139
144
|
response = nil
|
140
145
|
loop do
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
146
|
+
options = {
|
147
|
+
limit: 500
|
148
|
+
}
|
149
|
+
options[:position] = response.position unless !response || response.position.nil?
|
150
|
+
response = @client.get_rest_apis(options)
|
147
151
|
api = response.items.detect { |item| item.name == api_name }
|
148
152
|
return api.id if api
|
149
153
|
return if response.items.empty? || response.position.nil? || response.position.empty?
|
@@ -213,7 +213,10 @@ module LambdaWrap
|
|
213
213
|
def retrieve_table_details(full_table_name)
|
214
214
|
table_details = nil
|
215
215
|
begin
|
216
|
-
|
216
|
+
options = {
|
217
|
+
table_name: full_table_name
|
218
|
+
}
|
219
|
+
table_details = @client.describe_table(options).table
|
217
220
|
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
218
221
|
puts "Table #{full_table_name} does not exist."
|
219
222
|
end
|
@@ -309,11 +312,12 @@ module LambdaWrap
|
|
309
312
|
puts "Updating Provisioned Throughtput for #{full_table_name}"
|
310
313
|
puts "Setting Read Capacity Units From: #{old_read} To: #{@read_capacity_units}"
|
311
314
|
puts "Setting Write Capacty Units From: #{old_write} To: #{@write_capacity_units}"
|
312
|
-
|
315
|
+
options = {
|
313
316
|
table_name: full_table_name,
|
314
317
|
provisioned_throughput: { read_capacity_units: @read_capacity_units,
|
315
318
|
write_capacity_units: @write_capacity_units }
|
316
|
-
|
319
|
+
}
|
320
|
+
@client.update_table(options)
|
317
321
|
end
|
318
322
|
|
319
323
|
def build_global_index_deletes_array(current_global_indexes)
|
@@ -325,10 +329,11 @@ module LambdaWrap
|
|
325
329
|
|
326
330
|
def delete_global_index(full_table_name, index_to_delete)
|
327
331
|
puts "Deleting Global Secondary Index: #{index_to_delete} from Table: #{full_table_name}"
|
328
|
-
|
332
|
+
options = {
|
329
333
|
table_name: full_table_name,
|
330
334
|
global_secondary_index_updates: [{ delete: { index_name: index_to_delete } }]
|
331
|
-
|
335
|
+
}
|
336
|
+
@client.update_table(options)
|
332
337
|
end
|
333
338
|
|
334
339
|
# Looks through the list current of Global Secondary Indexes and builds an array if the Provisioned Throughput
|
@@ -363,10 +368,12 @@ module LambdaWrap
|
|
363
368
|
end
|
364
369
|
)
|
365
370
|
|
366
|
-
|
371
|
+
options = {
|
367
372
|
table_name: full_table_name,
|
368
373
|
global_secondary_index_updates: global_secondary_index_updates.map { |index| { update: index } }
|
369
|
-
|
374
|
+
}
|
375
|
+
|
376
|
+
@client.update_table(options)
|
370
377
|
end
|
371
378
|
|
372
379
|
def build_new_global_indexes_array(current_global_indexes)
|
@@ -383,22 +390,24 @@ module LambdaWrap
|
|
383
390
|
def create_global_indexes(full_table_name, new_global_secondary_indexes)
|
384
391
|
puts "Creating new Global Indexes for Table: #{full_table_name}"
|
385
392
|
puts(new_global_secondary_indexes.map { |index| index[:index_name].to_s })
|
386
|
-
|
393
|
+
options = {
|
387
394
|
table_name: full_table_name,
|
388
395
|
global_secondary_index_updates: new_global_secondary_indexes.map { |index| { create: index } }
|
389
|
-
|
396
|
+
}
|
397
|
+
@client.update_table(options)
|
390
398
|
end
|
391
399
|
|
392
400
|
def create_table(full_table_name)
|
393
401
|
puts "Creating table #{full_table_name}..."
|
394
|
-
|
402
|
+
options = {
|
395
403
|
table_name: full_table_name, attribute_definitions: @attribute_definitions,
|
396
404
|
key_schema: @key_schema,
|
397
405
|
provisioned_throughput: { read_capacity_units: @read_capacity_units,
|
398
406
|
write_capacity_units: @write_capacity_units },
|
399
407
|
local_secondary_indexes: @local_secondary_indexes,
|
400
408
|
global_secondary_indexes: @global_secondary_indexes
|
401
|
-
|
409
|
+
}
|
410
|
+
@client.create_table(options)
|
402
411
|
# Wait 60 seconds because "DescribeTable uses an eventually consistent query"
|
403
412
|
puts 'Sleeping for 60 seconds...'
|
404
413
|
Kernel.sleep(60)
|
@@ -415,7 +424,10 @@ module LambdaWrap
|
|
415
424
|
else
|
416
425
|
# Wait up to 30m
|
417
426
|
wait_until_table_available(full_table_name, 5, 360) if table_details.table_status != 'ACTIVE'
|
418
|
-
|
427
|
+
options = {
|
428
|
+
table_name: full_table_name
|
429
|
+
}
|
430
|
+
@client.delete_table(options)
|
419
431
|
end
|
420
432
|
end
|
421
433
|
|
@@ -427,12 +439,13 @@ module LambdaWrap
|
|
427
439
|
tables = []
|
428
440
|
response = nil
|
429
441
|
loop do
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
442
|
+
options = {
|
443
|
+
limit: 100
|
444
|
+
}
|
445
|
+
unless !response || response.last_evaluated_table_name.nil? || response.last_evaluated_table_name.empty?
|
446
|
+
options[:exclusive_start_table_name] = response.last_evaluated_table_name
|
447
|
+
end
|
448
|
+
response = @client.list_tables(options)
|
436
449
|
tables.concat(response.table_names)
|
437
450
|
if response.table_names.empty? || response.last_evaluated_table_name.nil? ||
|
438
451
|
response.last_evaluated_table_name.empty?
|
@@ -24,7 +24,7 @@ module LambdaWrap
|
|
24
24
|
# @option options [Integer] :timeout (30) The function execution time at which Lambda should terminate the function.
|
25
25
|
# @option options [Integer] :memory_size (128) The amount of memory, in MB, your Lambda function is given. Lambda
|
26
26
|
# uses this memory size to infer the amount of CPU and memory allocated to your function. The value must be a
|
27
|
-
# multiple of 64MB. Minimum: 128, Maximum:
|
27
|
+
# multiple of 64MB. Minimum: 128, Maximum: 3008.
|
28
28
|
# @option options [Array<String>] :subnet_ids ([]) If your Lambda function accesses resources in a VPC, you provide
|
29
29
|
# this parameter identifying the list of subnet IDs. These must belong to the same VPC. You must provide at least
|
30
30
|
# one security group and one subnet ID to configure VPC access.
|
@@ -79,7 +79,7 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
79
79
|
@timeout = options_with_defaults[:timeout]
|
80
80
|
|
81
81
|
unless (options_with_defaults[:memory_size] % 64).zero? && (options_with_defaults[:memory_size] >= 128) &&
|
82
|
-
(options_with_defaults[:memory_size] <=
|
82
|
+
(options_with_defaults[:memory_size] <= 3008)
|
83
83
|
raise ArgumentError, 'Invalid Memory Size.'
|
84
84
|
end
|
85
85
|
@memory_size = options_with_defaults[:memory_size]
|
@@ -156,7 +156,8 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
156
156
|
if lambda_details.nil?
|
157
157
|
puts 'No Lambda to delete.'
|
158
158
|
else
|
159
|
-
|
159
|
+
options = { function_name: @lambda_name }
|
160
|
+
@client.delete_function(options)
|
160
161
|
puts "Lambda #{@lambda_name} and all Versions & Aliases have been deleted."
|
161
162
|
end
|
162
163
|
true
|
@@ -172,7 +173,8 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
172
173
|
def retrieve_lambda_details
|
173
174
|
lambda_details = nil
|
174
175
|
begin
|
175
|
-
|
176
|
+
options = { function_name: @lambda_name }
|
177
|
+
lambda_details = @client.get_function(options).configuration
|
176
178
|
rescue Aws::Lambda::Errors::ResourceNotFoundException, Aws::Lambda::Errors::NotFound
|
177
179
|
puts "Lambda #{@lambda_name} does not exist."
|
178
180
|
end
|
@@ -182,12 +184,12 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
182
184
|
def create_lambda
|
183
185
|
puts "Creating New Lambda Function: #{@lambda_name}...."
|
184
186
|
puts "Runtime Engine: #{@runtime}, Timeout: #{@timeout}, Memory Size: #{@memory_size}."
|
185
|
-
|
186
|
-
lambda_version = @client.create_function(
|
187
|
+
options = {
|
187
188
|
function_name: @lambda_name, runtime: @runtime, role: @role_arn, handler: @handler,
|
188
|
-
code: { zip_file: File.
|
189
|
+
code: { zip_file: File.binread(@path_to_zip_file) }, description: @description, timeout: @timeout,
|
189
190
|
memory_size: @memory_size, vpc_config: @vpc_configuration, publish: true
|
190
|
-
|
191
|
+
}
|
192
|
+
lambda_version = @client.create_function(options).version
|
191
193
|
puts "Successfully created Lambda: #{@lambda_name}!"
|
192
194
|
lambda_version
|
193
195
|
end
|
@@ -200,45 +202,47 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
200
202
|
#{@vpc_configuration[:security_group_ids]}"
|
201
203
|
end
|
202
204
|
|
203
|
-
|
205
|
+
options = {
|
204
206
|
function_name: @lambda_name, role: @role_arn, handler: @handler, description: @description, timeout: @timeout,
|
205
207
|
memory_size: @memory_size, vpc_config: @vpc_configuration, runtime: @runtime
|
206
|
-
|
208
|
+
}
|
209
|
+
|
210
|
+
@client.update_function_configuration(options)
|
207
211
|
|
208
212
|
puts "Successfully updated Lambda configuration for #{@lambda_name}"
|
209
213
|
end
|
210
214
|
|
211
215
|
def update_lambda_code
|
212
216
|
puts "Updating Lambda Code for #{@lambda_name}...."
|
213
|
-
|
214
|
-
response = @client.update_function_code(
|
217
|
+
options = {
|
215
218
|
function_name: @lambda_name,
|
216
|
-
zip_file: File.
|
219
|
+
zip_file: File.binread(@path_to_zip_file),
|
217
220
|
publish: true
|
218
|
-
|
221
|
+
}
|
222
|
+
|
223
|
+
response = @client.update_function_code(options)
|
219
224
|
|
220
225
|
puts "Successully updated Lambda #{@lambda_name} code to version: #{response.version}"
|
221
226
|
response.version
|
222
227
|
end
|
223
228
|
|
224
229
|
def create_alias(func_version, alias_name, alias_description)
|
230
|
+
options = {
|
231
|
+
function_name: @lambda_name, name: alias_name, function_version: func_version,
|
232
|
+
description: alias_description || 'Alias managed by LambdaWrap'
|
233
|
+
}
|
225
234
|
if alias_exist?(alias_name)
|
226
|
-
@client.update_alias(
|
227
|
-
function_name: @lambda_name, name: alias_name, function_version: func_version,
|
228
|
-
description: alias_description || 'Alias managed by LambdaWrap'
|
229
|
-
)
|
235
|
+
@client.update_alias(options)
|
230
236
|
else
|
231
|
-
@client.create_alias(
|
232
|
-
function_name: @lambda_name, name: alias_name, function_version: func_version,
|
233
|
-
description: alias_description || 'Alias managed by LambdaWrap'
|
234
|
-
)
|
237
|
+
@client.create_alias(options)
|
235
238
|
end
|
236
239
|
puts "Created Alias: #{alias_name} for Lambda: #{@lambda_name} v#{func_version}."
|
237
240
|
end
|
238
241
|
|
239
242
|
def remove_alias(alias_name)
|
240
243
|
puts "Deleting Alias: #{alias_name} for #{@lambda_name}"
|
241
|
-
|
244
|
+
options = { function_name: @lambda_name, name: alias_name }
|
245
|
+
@client.delete_alias(options)
|
242
246
|
end
|
243
247
|
|
244
248
|
def cleanup_unused_versions
|
@@ -250,7 +254,8 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
250
254
|
|
251
255
|
function_versions_to_be_deleted.each do |version|
|
252
256
|
puts "Deleting function version: #{version}."
|
253
|
-
|
257
|
+
options = { function_name: @lambda_name, qualifier: version }
|
258
|
+
@client.delete_function(options)
|
254
259
|
end
|
255
260
|
|
256
261
|
puts "Cleaned up #{function_versions_to_be_deleted.length} unused versions."
|
@@ -260,12 +265,13 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
260
265
|
function_versions = []
|
261
266
|
response = nil
|
262
267
|
loop do
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
268
|
+
options = {
|
269
|
+
function_name: @lambda_name
|
270
|
+
}
|
271
|
+
unless !response || response.next_marker.nil? || response.next_marker.empty?
|
272
|
+
options[:marker] = response.next_marker
|
273
|
+
end
|
274
|
+
response = @client.list_versions_by_function(options)
|
269
275
|
function_versions.concat(response.versions.map(&:version))
|
270
276
|
if response.next_marker.nil? || response.next_marker.empty?
|
271
277
|
return function_versions.reject { |v| v == '$LATEST' }
|
@@ -277,7 +283,13 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
277
283
|
aliases = []
|
278
284
|
response = nil
|
279
285
|
loop do
|
280
|
-
|
286
|
+
options = {
|
287
|
+
function_name: @lambda_name
|
288
|
+
}
|
289
|
+
unless !response || response.next_marker.nil? || response.next_marker.empty?
|
290
|
+
options[:marker] = response.next_marker
|
291
|
+
end
|
292
|
+
response = @client.list_aliases(options)
|
281
293
|
aliases.concat(response.aliases)
|
282
294
|
return aliases if response.aliases.empty? || response.next_marker.nil? || response.next_marker.empty?
|
283
295
|
end
|
@@ -291,13 +303,5 @@ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-
|
|
291
303
|
def alias_exist?(alias_name)
|
292
304
|
retrieve_all_aliases.detect { |a| a.name == alias_name }
|
293
305
|
end
|
294
|
-
|
295
|
-
def invoke_client_method_with_optional_marker(response, method_symbol)
|
296
|
-
if !response || response.next_marker.nil? || response.next_marker.empty?
|
297
|
-
@client.send(method_symbol, function_name: @lambda_name)
|
298
|
-
else
|
299
|
-
@client.send(method_symbol, function_name: @lambda_name, marker: response.next_marker)
|
300
|
-
end
|
301
|
-
end
|
302
306
|
end
|
303
307
|
end
|
data/lib/lambda_wrap/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lambda_wrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Thurner
|
@@ -10,36 +10,36 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-12-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: activesupport
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '4'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '
|
28
|
+
version: '4'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: aws-sdk
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '2'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '2'
|
43
43
|
description: |-
|
44
44
|
This gem wraps the AWS SDK to simplify deployment of AWS \
|
45
45
|
Lambda functions backed by API Gateway and DynamoDB.
|
@@ -69,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
69
|
requirements:
|
70
70
|
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: 1
|
72
|
+
version: '2.1'
|
73
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
75
|
- - ">="
|
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
77
|
version: '0'
|
78
78
|
requirements: []
|
79
79
|
rubyforge_project:
|
80
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.7.3
|
81
81
|
signing_key:
|
82
82
|
specification_version: 4
|
83
83
|
summary: Easy deployment of AWS Lambda functions and dependencies.
|