lambda_wrap 0.26.0 → 0.26.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 607ac6f7897fd02734b7becfde1a0433537d0834
|
4
|
+
data.tar.gz: 7a99c2c22b98f5ced65293bfcbfbd0ce8777310c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 384e233666fdac0fe44c7c3ba03ad69ec02b9c418f6a45b39ac20b2b51048850215cad0f13076aa610227be4389d4d9bdf5db80a662b4c9202353fdd31d5bd7b
|
7
|
+
data.tar.gz: 09c693b615ed2c22ab7a72527afd01439d8d7e1dd55fe4003e2ba1c7760bf581499f3dca3d97dc640da0033f93c1d569776ecdc8d3cdba8765110c63fb4cb5dc
|
@@ -1,203 +1,203 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
|
3
|
-
module LambdaWrap
|
4
|
-
# The ApiGatewayManager simplifies downloading the aws-apigateway-importer binary,
|
5
|
-
# importing a {swagger configuration}[http://swagger.io], and managing API Gateway stages.
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module LambdaWrap
|
4
|
+
# The ApiGatewayManager simplifies downloading the aws-apigateway-importer binary,
|
5
|
+
# importing a {swagger configuration}[http://swagger.io], and managing API Gateway stages.
|
6
6
|
# Added functionality to create APIGateway deom Swagger file. Thsi API is useful for gateway's having
|
7
|
-
#custom authorization.
|
8
|
-
|
9
|
-
# Note: The concept of an environment of the LambdaWrap gem matches a stage in AWS ApiGateway terms.
|
10
|
-
class ApiGatewayManager
|
11
|
-
#
|
12
|
-
# The constructor does some basic setup
|
13
|
-
# * Validating basic AWS configuration
|
14
|
-
# * Creating the underlying client to interact with the AWS SDK.
|
15
|
-
# * Defining the temporary path of the api-gateway-importer jar file
|
16
|
-
def initialize
|
17
|
-
# AWS api gateway client
|
18
|
-
@client = Aws::APIGateway::Client.new
|
19
|
-
# path to apigateway-importer jar
|
20
|
-
@jarpath = File.join(Dir.tmpdir, 'aws-apigateway-importer-1.0.3-SNAPSHOT-jar-with-dependencies.jar')
|
21
|
-
@versionpath = File.join(Dir.tmpdir, 'aws-apigateway-importer-1.0.3-SNAPSHOT-jar-with-dependencies.s3version')
|
22
|
-
end
|
23
|
-
|
24
|
-
##
|
25
|
-
# Downloads the aws-apigateway-importer jar from an S3 bucket.
|
26
|
-
# This is a workaround since aws-apigateway-importer does not provide a binary.
|
27
|
-
# Once a binary is available on the public internet, we'll start using this instead
|
28
|
-
# of requiring users of this gem to upload their custom binary to an S3 bucket.
|
29
|
-
#
|
30
|
-
# *Arguments*
|
31
|
-
# [s3_bucket]
|
32
|
-
# [s3_key]
|
33
|
-
def download_apigateway_importer(s3_bucket, s3_key)
|
34
|
-
s3 = Aws::S3::Client.new
|
35
|
-
|
36
|
-
# current version
|
37
|
-
current_s3_version = File.open(@versionpath, 'rb').read if File.exist?(@versionpath)
|
38
|
-
|
39
|
-
# online s3 version
|
40
|
-
desired_s3_version = s3.head_object(bucket: s3_bucket, key: s3_key).version_id
|
41
|
-
|
42
|
-
# compare local with remote version
|
43
|
-
if current_s3_version != desired_s3_version || !File.exist?(@jarpath)
|
44
|
-
puts "Downloading aws-apigateway-importer jar with S3 version #{desired_s3_version}"
|
45
|
-
s3.get_object(response_target: @jarpath, bucket: s3_bucket, key: s3_key)
|
46
|
-
File.write(@versionpath, desired_s3_version)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
##
|
51
|
-
# Sets up the API gateway by searching whether the API Gateway already exists
|
52
|
-
# and updates it with the latest information from the swagger file.
|
53
|
-
#
|
54
|
-
# *Arguments*
|
55
|
-
# [api_name]
|
56
|
-
# [env]
|
57
|
-
# [swagger_file]
|
58
|
-
# [api_description]
|
59
|
-
# [stage_variables]
|
60
|
-
# [region]
|
61
|
-
def setup_apigateway(api_name, env, swagger_file, api_description = 'Deployed with LambdaWrap',
|
62
|
-
stage_variables = {}, region = ENV['AWS_REGION'])
|
63
|
-
# ensure API is created
|
64
|
-
api_id = get_existing_rest_api(api_name)
|
65
|
-
api_id = setup_apigateway_create_rest_api(api_name, api_description) unless api_id
|
66
|
-
|
67
|
-
# create resources
|
68
|
-
setup_apigateway_create_resources(api_id, swagger_file, region)
|
69
|
-
|
70
|
-
# create stages
|
71
|
-
stage_variables.store('environment', env)
|
72
|
-
create_stages(api_id, env, stage_variables)
|
73
|
-
|
74
|
-
# return URI of created stage
|
75
|
-
"https://#{api_id}.execute-api.#{region}.amazonaws.com/#{env}/"
|
76
|
-
end
|
77
|
-
|
78
|
-
##
|
79
|
-
# Shuts down an environment from the API Gateway. This basically deletes the stage
|
80
|
-
# from the API Gateway, but does not delete the API Gateway itself.
|
81
|
-
#
|
82
|
-
# *Argument*
|
83
|
-
# [api_name]
|
84
|
-
# [env]
|
85
|
-
def shutdown_apigateway(api_name, env)
|
86
|
-
api_id = get_existing_rest_api(api_name)
|
87
|
-
delete_stage(api_id, env)
|
88
|
-
end
|
89
|
-
|
90
|
-
##
|
91
|
-
# Gets the ID of an existing API Gateway api, or nil if it doesn't exist
|
92
|
-
#
|
93
|
-
# *Arguments*
|
94
|
-
# [api_name]
|
95
|
-
def get_existing_rest_api(api_name)
|
96
|
-
apis = @client.get_rest_apis(limit: 500).data
|
97
|
-
api = apis.items.select { |a| a.name == api_name }.first
|
98
|
-
|
99
|
-
return api.id if api
|
100
|
-
# nil is returned otherwise
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
|
-
# Creates the API with a given name and returns the id
|
105
|
-
#
|
106
|
-
# *Arguments*
|
107
|
-
# [api_name]
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
api.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
7
|
+
# custom authorization.
|
8
|
+
|
9
|
+
# Note: The concept of an environment of the LambdaWrap gem matches a stage in AWS ApiGateway terms.
|
10
|
+
class ApiGatewayManager
|
11
|
+
#
|
12
|
+
# The constructor does some basic setup
|
13
|
+
# * Validating basic AWS configuration
|
14
|
+
# * Creating the underlying client to interact with the AWS SDK.
|
15
|
+
# * Defining the temporary path of the api-gateway-importer jar file
|
16
|
+
def initialize
|
17
|
+
# AWS api gateway client
|
18
|
+
@client = Aws::APIGateway::Client.new
|
19
|
+
# path to apigateway-importer jar
|
20
|
+
@jarpath = File.join(Dir.tmpdir, 'aws-apigateway-importer-1.0.3-SNAPSHOT-jar-with-dependencies.jar')
|
21
|
+
@versionpath = File.join(Dir.tmpdir, 'aws-apigateway-importer-1.0.3-SNAPSHOT-jar-with-dependencies.s3version')
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Downloads the aws-apigateway-importer jar from an S3 bucket.
|
26
|
+
# This is a workaround since aws-apigateway-importer does not provide a binary.
|
27
|
+
# Once a binary is available on the public internet, we'll start using this instead
|
28
|
+
# of requiring users of this gem to upload their custom binary to an S3 bucket.
|
29
|
+
#
|
30
|
+
# *Arguments*
|
31
|
+
# [s3_bucket] An S3 bucket from where the aws-apigateway-importer binary can be downloaded.
|
32
|
+
# [s3_key] The path (key) to the aws-apigateay-importer binary on the s3 bucket.
|
33
|
+
def download_apigateway_importer(s3_bucket, s3_key)
|
34
|
+
s3 = Aws::S3::Client.new
|
35
|
+
|
36
|
+
# current version
|
37
|
+
current_s3_version = File.open(@versionpath, 'rb').read if File.exist?(@versionpath)
|
38
|
+
|
39
|
+
# online s3 version
|
40
|
+
desired_s3_version = s3.head_object(bucket: s3_bucket, key: s3_key).version_id
|
41
|
+
|
42
|
+
# compare local with remote version
|
43
|
+
if current_s3_version != desired_s3_version || !File.exist?(@jarpath)
|
44
|
+
puts "Downloading aws-apigateway-importer jar with S3 version #{desired_s3_version}"
|
45
|
+
s3.get_object(response_target: @jarpath, bucket: s3_bucket, key: s3_key)
|
46
|
+
File.write(@versionpath, desired_s3_version)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Sets up the API gateway by searching whether the API Gateway already exists
|
52
|
+
# and updates it with the latest information from the swagger file.
|
53
|
+
#
|
54
|
+
# *Arguments*
|
55
|
+
# [api_name] The name of the API to which the swagger file should be applied to.
|
56
|
+
# [env] The environment where it should be published (which is matching an API gateway stage)
|
57
|
+
# [swagger_file] A handle to a swagger file that should be used by aws-apigateway-importer
|
58
|
+
# [api_description] The description of the API to be displayed.
|
59
|
+
# [stage_variables] A Hash of stage variables to be deployed with the stage. Adds an 'environment' by default.
|
60
|
+
# [region] A string representing the region to deploy the API. Defaults to what is set as an environment variable.
|
61
|
+
def setup_apigateway(api_name, env, swagger_file, api_description = 'Deployed with LambdaWrap',
|
62
|
+
stage_variables = {}, region = ENV['AWS_REGION'])
|
63
|
+
# ensure API is created
|
64
|
+
api_id = get_existing_rest_api(api_name)
|
65
|
+
api_id = setup_apigateway_create_rest_api(api_name, api_description) unless api_id
|
66
|
+
|
67
|
+
# create resources
|
68
|
+
setup_apigateway_create_resources(api_id, swagger_file, region)
|
69
|
+
|
70
|
+
# create stages
|
71
|
+
stage_variables.store('environment', env)
|
72
|
+
create_stages(api_id, env, stage_variables)
|
73
|
+
|
74
|
+
# return URI of created stage
|
75
|
+
"https://#{api_id}.execute-api.#{region}.amazonaws.com/#{env}/"
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Shuts down an environment from the API Gateway. This basically deletes the stage
|
80
|
+
# from the API Gateway, but does not delete the API Gateway itself.
|
81
|
+
#
|
82
|
+
# *Argument*
|
83
|
+
# [api_name] The name of the API where the environment should be shut down.
|
84
|
+
# [env] The environment (matching an API Gateway stage) to shutdown.
|
85
|
+
def shutdown_apigateway(api_name, env)
|
86
|
+
api_id = get_existing_rest_api(api_name)
|
87
|
+
delete_stage(api_id, env)
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Gets the ID of an existing API Gateway api, or nil if it doesn't exist
|
92
|
+
#
|
93
|
+
# *Arguments*
|
94
|
+
# [api_name] The name of the API to be checked for existance
|
95
|
+
def get_existing_rest_api(api_name)
|
96
|
+
apis = @client.get_rest_apis(limit: 500).data
|
97
|
+
api = apis.items.select { |a| a.name == api_name }.first
|
98
|
+
|
99
|
+
return api.id if api
|
100
|
+
# nil is returned otherwise
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Creates the API with a given name using the SDK and returns the id
|
105
|
+
#
|
106
|
+
# *Arguments*
|
107
|
+
# [api_name] A String representing the name of the API Gateway Object to be created
|
108
|
+
# [api_description] A String representing the description of the API
|
109
|
+
def setup_apigateway_create_rest_api(api_name, api_description)
|
110
|
+
puts 'Creating API with name ' + api_name
|
111
|
+
api = @client.create_rest_api(name: api_name, description: api_description)
|
112
|
+
api.id
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Invokes the aws-apigateway-importer jar with the required parameter
|
117
|
+
#
|
118
|
+
# *Arguments*
|
119
|
+
# [api_id] The AWS ApiGateway id where the swagger file should be applied to.
|
120
|
+
# [swagger_file] The handle to a swagger definition file that should be imported into API Gateway
|
121
|
+
# [region] A string representing the target region to deploy the API
|
122
|
+
def setup_apigateway_create_resources(api_id, swagger_file, region)
|
123
|
+
raise 'API ID not provided' unless api_id
|
124
|
+
|
125
|
+
cmd = "java -jar #{@jarpath} --update #{api_id} --region #{region} #{swagger_file}"
|
126
|
+
raise 'API gateway not created' unless system(cmd)
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Creates a stage of the currently set resources
|
131
|
+
#
|
132
|
+
# *Arguments*
|
133
|
+
# [api_id] The AWS ApiGateway id where the stage should be created at.
|
134
|
+
# [env] The environment (which matches the stage in API Gateway) to create.
|
135
|
+
# [stage_variables] A Hash of stage variables to deploy with the stage
|
136
|
+
def create_stages(api_id, env, stage_variables)
|
137
|
+
deployment_description = 'Deployment of service to ' + env
|
138
|
+
deployment = @client.create_deployment(
|
139
|
+
rest_api_id: api_id, stage_name: env, cache_cluster_enabled: false, description: deployment_description,
|
140
|
+
variables: stage_variables
|
141
|
+
).data
|
142
|
+
puts deployment
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Deletes a stage of the API Gateway
|
147
|
+
#
|
148
|
+
# *Arguments*
|
149
|
+
# [api_id] The AWS ApiGateway id from which the stage should be deleted from.
|
150
|
+
# [env]The environment (which matches the stage in API Gateway) to delete.
|
151
|
+
def delete_stage(api_id, env)
|
152
|
+
@client.delete_stage(rest_api_id: api_id, stage_name: env)
|
153
|
+
puts 'Deleted API gateway stage ' + env
|
154
|
+
rescue Aws::APIGateway::Errors::NotFoundException
|
155
|
+
puts 'API Gateway stage ' + env + ' does not exist. Nothing to delete.'
|
156
|
+
end
|
157
|
+
|
158
|
+
##
|
159
|
+
# Generate or Update the API Gateway by using the swagger file and the SDK importer
|
160
|
+
#
|
158
161
|
# *Arguments*
|
159
162
|
# [api_name] API Gateway name
|
160
163
|
# [local_swagger_file] Path of the local swagger file
|
161
|
-
# [env] Environment
|
164
|
+
# [env] Environment identifier
|
165
|
+
# [stage_variables] hash of stage variables
|
162
166
|
def setup_apigateway_by_swagger_file(api_name, local_swagger_file, env, stage_variables = {})
|
163
|
-
|
164
|
-
#If API gateway with the name is already present then update it else create a new one
|
167
|
+
# If API gateway with the name is already present then update it else create a new one
|
165
168
|
api_id = get_existing_rest_api(api_name)
|
166
|
-
swagger_file_content =
|
169
|
+
swagger_file_content = File.read(local_swagger_file)
|
167
170
|
|
168
171
|
gateway_response = nil
|
169
|
-
if
|
170
|
-
#Create a new APIGateway
|
172
|
+
if api_id.nil?
|
173
|
+
# Create a new APIGateway
|
171
174
|
gateway_response = @client.import_rest_api(fail_on_warnings: false, body: swagger_file_content)
|
172
175
|
else
|
173
|
-
#Update the exsiting APIgateway. By Merge the exsisting gateway will be merged with the new
|
174
|
-
|
176
|
+
# Update the exsiting APIgateway. By Merge the exsisting gateway will be merged with the new
|
177
|
+
# one supplied in the Swagger file.
|
178
|
+
gateway_response = @client.put_rest_api(rest_api_id: api_id, mode: 'merge', fail_on_warnings: false,
|
179
|
+
body: swagger_file_content)
|
175
180
|
end
|
176
181
|
|
177
|
-
if
|
178
|
-
|
182
|
+
raise "Failed to create API gateway with name #{api_name}" if gateway_response.nil? && gateway_response.id.nil?
|
183
|
+
|
184
|
+
if api_id.nil?
|
185
|
+
puts "Created api gateway #{api_name} having id #{gateway_response.id}"
|
179
186
|
else
|
180
|
-
|
181
|
-
puts "Created api gateway #{api_name} having id #{gateway_response.id}"
|
182
|
-
else
|
183
|
-
puts "Updated api gateway #{api_name} having id #{gateway_response.id}"
|
184
|
-
end
|
187
|
+
puts "Updated api gateway #{api_name} having id #{gateway_response.id}"
|
185
188
|
end
|
186
189
|
|
187
|
-
#Deploy the service
|
188
|
-
deployment_description = 'Deployment of service to ' + env
|
190
|
+
# Deploy the service
|
189
191
|
stage_variables.store('environment', env)
|
190
192
|
create_stages(gateway_response.id, env, stage_variables)
|
191
193
|
|
192
194
|
service_uri = "https://#{gateway_response.id}.execute-api.#{ENV['AWS_REGION']}.amazonaws.com/#{env}/"
|
193
195
|
puts "Service deployed at #{service_uri}"
|
194
196
|
|
195
|
-
|
196
|
-
|
197
|
+
service_uri
|
197
198
|
end
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
200
|
+
private :get_existing_rest_api, :setup_apigateway_create_rest_api, :setup_apigateway_create_resources,
|
201
|
+
:create_stages, :delete_stage
|
202
|
+
end
|
203
|
+
end
|