lambda_wrap 0.26.0 → 0.26.6
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/lambda_wrap/api_gateway_manager.rb +180 -180
- data/lib/lambda_wrap/dynamo_db_manager.rb +181 -176
- data/lib/lambda_wrap/lambda_manager.rb +208 -196
- data/lib/lambda_wrap/s3_bucket_manager.rb +5 -8
- data/lib/lambda_wrap/version.rb +3 -0
- data/lib/lambda_wrap/zip_file_generator.rb +67 -67
- data/lib/lambda_wrap.rb +5 -5
- metadata +9 -6
@@ -1,176 +1,181 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
|
3
|
-
module LambdaWrap
|
4
|
-
# The DynamoDBManager simplifies setting up and destroying a DynamoDB database.
|
5
|
-
#
|
6
|
-
# Note: In case an environment specific DynamoDB tablename such as +<baseTableName>-production+ should be used, then
|
7
|
-
# it has to be injected directly to the methods since not all environments necessarily need separated databases.
|
8
|
-
class DynamoDbManager
|
9
|
-
##
|
10
|
-
# The constructor does some basic setup
|
11
|
-
# * Validating basic AWS configuration
|
12
|
-
# * Creating the underlying client to interact with the AWS SDK.
|
13
|
-
def initialize
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# [
|
36
|
-
# [
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
puts "Table: #{table_name} not updated.
|
48
|
-
|
49
|
-
|
50
|
-
puts "
|
51
|
-
Current
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# it
|
72
|
-
# capacities upwards (it doesn't downgrade them to avoid a production environment being impacted with
|
73
|
-
# a default setting of an automated script).
|
74
|
-
#
|
75
|
-
# *Arguments*
|
76
|
-
# [table_name]
|
77
|
-
# [attribute_definitions] The dynamoDB attribute definitions to be used when the table is created.
|
78
|
-
# [key_schema]
|
79
|
-
# [read_capacity]
|
80
|
-
# [write_capacity]
|
81
|
-
# [local_secondary_indexes]
|
82
|
-
# [global_secondary_indexes]
|
83
|
-
def publish_database(
|
84
|
-
table_name, attribute_definitions, key_schema, read_capacity, write_capacity, local_secondary_indexes = nil,
|
85
|
-
global_secondary_indexes = nil
|
86
|
-
)
|
87
|
-
has_updates = false
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
table_details
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
params =
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module LambdaWrap
|
4
|
+
# The DynamoDBManager simplifies setting up and destroying a DynamoDB database.
|
5
|
+
#
|
6
|
+
# Note: In case an environment specific DynamoDB tablename such as +<baseTableName>-production+ should be used, then
|
7
|
+
# it has to be injected directly to the methods since not all environments necessarily need separated databases.
|
8
|
+
class DynamoDbManager
|
9
|
+
##
|
10
|
+
# The constructor does some basic setup
|
11
|
+
# * Validating basic AWS configuration
|
12
|
+
# * Creating the underlying client to interact with the AWS SDK.
|
13
|
+
def initialize
|
14
|
+
@client = Aws::DynamoDB::Client.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_table_capacity(table_name, read_capacity, write_capacity)
|
18
|
+
puts "Updating new read/write capacity for table #{table_name}.
|
19
|
+
Read #{table_details.provisioned_throughput.read_capacity_units} ==> #{read_capacity}.
|
20
|
+
Write #{table_details.provisioned_throughput.write_capacity_units} ==> #{write_capacity}."
|
21
|
+
@client.update_table(
|
22
|
+
table_name: table_name,
|
23
|
+
provisioned_throughput: { read_capacity_units: read_capacity, write_capacity_units: write_capacity }
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Updates the provisioned throughput read and write capacity of the requested table.
|
29
|
+
# If the table does not exist an error message is displayed. If current read/write capacity
|
30
|
+
# is equals to requested read/write capacity or the requested read/write capacity is 0 or less than 0
|
31
|
+
# no table updation is performed.
|
32
|
+
#
|
33
|
+
# *Arguments*
|
34
|
+
# [table_name] The table name of the dynamoDB to be updated.
|
35
|
+
# [read_capacity] The read capacity the table should be updated with.
|
36
|
+
# [write_capacity] The write capacity the table should be updated with.
|
37
|
+
def update_table_capacity(table_name, read_capacity, write_capacity)
|
38
|
+
table_details = get_table_details(table_name)
|
39
|
+
raise "Update cannot be performed. Table #{table_name} does not exists." if table_details.nil?
|
40
|
+
|
41
|
+
wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'
|
42
|
+
|
43
|
+
if read_capacity <= 0 || write_capacity <= 0
|
44
|
+
puts "Table: #{table_name} not updated. Read/Write capacity should be greater than or equal to 1."
|
45
|
+
elsif read_capacity == table_details.provisioned_throughput.read_capacity_units ||
|
46
|
+
write_capacity == table_details.provisioned_throughput.write_capacity_units
|
47
|
+
puts "Table: #{table_name} not updated. Current and requested reads/writes are same."
|
48
|
+
puts 'Current ReadCapacityUnits provisioned for the table: ' \
|
49
|
+
"#{table_details.provisioned_throughput.read_capacity_units}."
|
50
|
+
puts "Requested ReadCapacityUnits: #{read_capacity}."
|
51
|
+
puts 'Current WriteCapacityUnits provisioned for the table: ' \
|
52
|
+
"#{table_details.provisioned_throughput.write_capacity_units}."
|
53
|
+
puts "Requested WriteCapacityUnits: #{write_capacity}."
|
54
|
+
else
|
55
|
+
response = @client.update_table(
|
56
|
+
table_name: table_name,
|
57
|
+
provisioned_throughput: { read_capacity_units: read_capacity, write_capacity_units: write_capacity }
|
58
|
+
)
|
59
|
+
|
60
|
+
if response.table_description.table_status == 'UPDATING'
|
61
|
+
puts "Updated new read/write capacity for table #{table_name}.
|
62
|
+
Read capacity updated to: #{read_capacity}.
|
63
|
+
Write capacity updated to: #{write_capacity}."
|
64
|
+
else
|
65
|
+
raise "Read and writes capacities was not updated for table: #{table_name}."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Publishes the database and awaits until it is fully available. If the table already exists, it only adjusts the
|
72
|
+
# read and write capacities upwards (it doesn't downgrade them to avoid a production environment being impacted with
|
73
|
+
# a default setting of an automated script).
|
74
|
+
#
|
75
|
+
# *Arguments*
|
76
|
+
# [table_name] The table name of the dynamoDB to be created.
|
77
|
+
# [attribute_definitions] The dynamoDB attribute definitions to be used when the table is created.
|
78
|
+
# [key_schema] The dynamoDB key definitions to be used when the table is created.
|
79
|
+
# [read_capacity] The read capacity to configure for the dynamoDB table.
|
80
|
+
# [write_capacity] The write capacity to configure for the dynamoDB table.
|
81
|
+
# [local_secondary_indexes] The local secondary indexes to be created.
|
82
|
+
# [global_secondary_indexes] The global secondary indexes to be created.
|
83
|
+
def publish_database(
|
84
|
+
table_name, attribute_definitions, key_schema, read_capacity, write_capacity, local_secondary_indexes = nil,
|
85
|
+
global_secondary_indexes = nil
|
86
|
+
)
|
87
|
+
has_updates = false
|
88
|
+
|
89
|
+
table_details = get_table_details(table_name)
|
90
|
+
|
91
|
+
if !table_details.nil?
|
92
|
+
wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'
|
93
|
+
|
94
|
+
if read_capacity > table_details.provisioned_throughput.read_capacity_units ||
|
95
|
+
write_capacity > table_details.provisioned_throughput.write_capacity_units
|
96
|
+
set_table_capacity(read_capacity, write_capacity)
|
97
|
+
has_updates = true
|
98
|
+
else
|
99
|
+
puts "Table #{table_name} already exists and the desired read capacity of #{read_capacity} and " \
|
100
|
+
"write capacity of #{write_capacity} has at least been configured. Downgrading capacity units is not " \
|
101
|
+
'supported. No changes were applied.'
|
102
|
+
end
|
103
|
+
else
|
104
|
+
puts "Creating table #{table_name}."
|
105
|
+
ad = attribute_definitions || [{ attribute_name: 'Id', attribute_type: 'S' }]
|
106
|
+
ks = key_schema || [{ attribute_name: 'Id', key_type: 'HASH' }]
|
107
|
+
|
108
|
+
params = {
|
109
|
+
table_name: table_name, key_schema: ks, attribute_definitions: ad,
|
110
|
+
provisioned_throughput: {
|
111
|
+
read_capacity_units: read_capacity, write_capacity_units: write_capacity
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
params[:local_secondary_indexes] = local_secondary_indexes unless local_secondary_indexes.nil?
|
116
|
+
params[:global_secondary_indexes] = global_secondary_indexes unless global_secondary_indexes.nil?
|
117
|
+
|
118
|
+
@client.create_table(params)
|
119
|
+
has_updates = true
|
120
|
+
end
|
121
|
+
|
122
|
+
if has_updates
|
123
|
+
wait_until_table_available(table_name)
|
124
|
+
puts "DynamoDB table #{table_name} is now fully available."
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# Deletes a DynamoDB table. It does not wait until the table has been deleted.
|
130
|
+
#
|
131
|
+
# *Arguments*
|
132
|
+
# [table_name] The dynamoDB table name to delete.
|
133
|
+
def delete_database(table_name)
|
134
|
+
table_details = get_table_details(table_name)
|
135
|
+
if table_details.nil?
|
136
|
+
puts 'Table did not exist. Nothing to delete.'
|
137
|
+
else
|
138
|
+
wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'
|
139
|
+
@client.delete_table(table_name: table_name)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Awaits a given status of a table.
|
145
|
+
#
|
146
|
+
# *Arguments*
|
147
|
+
# [table_name] The dynamoDB table name to watch until it reaches an active status.
|
148
|
+
def wait_until_table_available(table_name)
|
149
|
+
max_attempts = 24
|
150
|
+
delay_between_attempts = 5
|
151
|
+
|
152
|
+
# wait until the table has updated to being fully available
|
153
|
+
# waiting for ~2min at most; an error will be thrown afterwards
|
154
|
+
begin
|
155
|
+
@client.wait_until(:table_exists, table_name: table_name) do |w|
|
156
|
+
w.max_attempts = max_attempts
|
157
|
+
w.delay = delay_between_attempts
|
158
|
+
w.before_wait do |attempts, _|
|
159
|
+
puts "Waiting until table becomes available. Attempt #{attempts}/#{max_attempts} " \
|
160
|
+
"with polling interval #{delay_between_attempts}."
|
161
|
+
end
|
162
|
+
end
|
163
|
+
rescue Aws::Waiters::Errors::TooManyAttemptsError => e
|
164
|
+
puts "Table #{table_name} did not become available after #{e.attempts} attempts. " \
|
165
|
+
'Try again later or inspect the AWS console.'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def get_table_details(table_name)
|
170
|
+
table_details = nil
|
171
|
+
begin
|
172
|
+
table_details = @client.describe_table(table_name: table_name).table
|
173
|
+
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
174
|
+
puts "Table #{table_name} does not exist."
|
175
|
+
end
|
176
|
+
table_details
|
177
|
+
end
|
178
|
+
|
179
|
+
private :wait_until_table_available, :get_table_details
|
180
|
+
end
|
181
|
+
end
|