lambda_wrap 0.27.0 → 1.0.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.
@@ -0,0 +1,53 @@
1
+ module LambdaWrap
2
+ # Environment class to pass to the deploy and teardown
3
+ #
4
+ # @!attribute [r] name
5
+ # @return [String] The descriptive name of the environment.
6
+ #
7
+ # @!attribute [r] description
8
+ # @return [String] The description of the environment.
9
+ #
10
+ # @!attribute [r] variables
11
+ # @return [Hash] The Hash of environment variables to deploy with the environment.
12
+ #
13
+ # @since 1.0
14
+ class Environment
15
+ attr_reader :name
16
+ attr_reader :description
17
+ attr_reader :variables
18
+
19
+ # Constructor
20
+ #
21
+ # @param name [String] Name of the environment. Corresponds to the Lambda Alias and API Gateway Stage.
22
+ # Must be at least 3 characters, and no more than 20 characters.
23
+ # @param variables [Hash] Environment variables to pass to the API Gateway stage. Must be a flat hash.
24
+ # Each key must be Alphanumeric (underscores allowed) and no more than 64 characters. Values can have
25
+ # most special characters, and no more than 512 characters.
26
+ # @param description [String] Description of the environment for Stage & Alias descriptions. Must not
27
+ # exceed 256 characters.
28
+ def initialize(name, variables = {}, description = 'Managed by LambdaWrap')
29
+ raise ArgumentError, 'name must be provided (String)!' unless name && name.is_a?(String)
30
+ # Max Alias Name length is 20 characters.
31
+ raise ArgumentError, "Invalid name format: #{name}" unless /^[a-zA-Z0-9\-\_]{3,20}$/ =~ name
32
+ @name = name
33
+
34
+ raise ArgumentError, 'Variables must be a Hash!' unless variables.is_a?(Hash)
35
+ variables.each do |key, value|
36
+ next if /^[0-9a-zA-Z\_]{1,64}$/ =~ key && /^[A-Za-z0-9\-.\_~:\/?#&=,]{1,512}$/ =~ value && value.is_a?(String)
37
+ raise ArgumentError, "Invalid Format of variables hash: #{key} => #{value}"
38
+ end
39
+
40
+ variables[:environment] = name unless variables[:environment]
41
+ @variables = variables
42
+
43
+ raise ArgumentError, 'Description must be a String!' unless description.is_a?(String)
44
+ raise ArgumentError, 'Description too long (Max 256)' unless description.length < 256
45
+ @description = description
46
+ end
47
+
48
+ def to_s
49
+ return @name if @name && @name.is_a?(String)
50
+ super
51
+ end
52
+ end
53
+ end
@@ -1,208 +1,303 @@
1
- require 'aws-sdk'
1
+ require 'set'
2
+ require 'pathname'
2
3
 
3
4
  module LambdaWrap
4
- ##
5
- # The LambdaManager simplifies creating a package, publishing to S3, deploying a new version, & setting permissions.
6
- #
7
- # Note: The concept of an environment of the LambdaWrap gem matches an alias of AWS Lambda.
8
- class LambdaManager
9
- ##
10
- # The constructor does some basic setup
11
- # * Validating basic AWS configuration
12
- # * Creating the underlying client to interace with the AWS SDK
13
- def initialize
14
- # AWS lambda client
15
- @client = Aws::Lambda::Client.new
16
- end
17
-
18
- ##
19
- # Packages a set of files and node modules into a deployable package.
5
+ # Lambda Manager class.
6
+ # Front loads the configuration to the constructor so that the developer can be more declarative with configuration
7
+ # and deployments.
8
+ # @since 1.0
9
+ class Lambda < AwsService
10
+ # Initializes a Lambda Manager. Frontloaded configuration.
20
11
  #
21
- # *Arguments*
22
- # [directory] A temporary directory to copy all related files before they are packages into a single zip file.
23
- # [zipfile] A path where the deployable package, a zip file, should be stored.
24
- # [input_filenames] A list of file names that contain the source code.
25
- # [node_modules] A list of node modules that need to be included in the package.
26
- def package(directory, zipfile, input_filenames, node_modules)
27
- FileUtils.mkdir_p directory
28
- FileUtils.mkdir_p File.join(directory, 'node_modules') unless node_modules.empty?
12
+ # @param [Hash] options The Configuration for the Lambda
13
+ # @option options [String] :lambda_name The name you want to assign to the function you are uploading. The function
14
+ # names appear in the console and are returned in the ListFunctions API. Function names are used to specify
15
+ # functions to other AWS Lambda API operations, such as Invoke. Note that the length constraint applies only to
16
+ # the ARN. If you specify only the function name, it is limited to 64 characters in length.
17
+ # @option options [String] :handler The function within your code that Lambda calls to begin execution.
18
+ # @option options [String] :role_arn The Amazon Resource Name (ARN) of the IAM role that Lambda assumes when it
19
+ # executes your function to access any other Amazon Web Services (AWS) resources.
20
+ # @option options [String] :path_to_zip_file The absolute path to the Deployment Package zip file
21
+ # @option options [String] :runtime The runtime environment for the Lambda function you are uploading.
22
+ # @option options [String] :description ('Deployed with LambdaWrap') A short, user-defined function description.
23
+ # Lambda does not use this value. Assign a meaningful description as you see fit.
24
+ # @option options [Integer] :timeout (30) The function execution time at which Lambda should terminate the function.
25
+ # @option options [Integer] :memory_size (128) The amount of memory, in MB, your Lambda function is given. Lambda
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: 1536.
28
+ # @option options [Array<String>] :subnet_ids ([]) If your Lambda function accesses resources in a VPC, you provide
29
+ # this parameter identifying the list of subnet IDs. These must belong to the same VPC. You must provide at least
30
+ # one security group and one subnet ID to configure VPC access.
31
+ # @option options [Array<String>] :security_group_ids ([]) If your Lambda function accesses resources in a VPC, you
32
+ # provide this parameter identifying the list of security group IDs. These must belong to the same VPC. You must
33
+ # provide at least one security group and one subnet ID.
34
+ # @option options [Boolean] :delete_unreferenced_versions (true) Option to delete any Lambda Function Versions upon
35
+ # deployment that do not have an alias pointing to them.
36
+ def initialize(options)
37
+ defaults = {
38
+ description: 'Deployed with LambdaWrap', subnet_ids: [], security_group_ids: [], timeout: 30, memory_size: 128,
39
+ delete_unreferenced_versions: true
40
+ }
41
+ options_with_defaults = options.reverse_merge(defaults)
29
42
 
30
- input_filenames.each do |filename|
31
- FileUtils.copy_file(File.join(filename), File.join(directory, File.basename(filename)))
43
+ unless (options_with_defaults[:lambda_name]) && (options_with_defaults[:lambda_name].is_a? String)
44
+ raise ArgumentError, 'lambda_name must be provided (String)!'
32
45
  end
46
+ @lambda_name = options_with_defaults[:lambda_name]
33
47
 
34
- node_modules.each do |dir|
35
- FileUtils.cp_r(File.join('node_modules', dir), File.join(directory, 'node_modules'))
48
+ unless (options_with_defaults[:handler]) && (options_with_defaults[:handler].is_a? String)
49
+ raise ArgumentError, 'handler must be provided (String)!'
36
50
  end
51
+ @handler = options_with_defaults[:handler]
37
52
 
38
- ZipFileGenerator.new(directory, zipfile).write
53
+ unless (options_with_defaults[:role_arn]) && (options_with_defaults[:role_arn].is_a? String)
54
+ raise ArgumentError, 'role_arn must be provided (String)!'
55
+ end
56
+ @role_arn = options_with_defaults[:role_arn]
57
+
58
+ unless (options_with_defaults[:path_to_zip_file]) && (options_with_defaults[:path_to_zip_file].is_a? String)
59
+ raise ArgumentError, 'path_to_zip_file must be provided (String)!'
60
+ end
61
+ @path_to_zip_file = options_with_defaults[:path_to_zip_file]
62
+
63
+ unless (options_with_defaults[:runtime]) && (options_with_defaults[:runtime].is_a? String)
64
+ raise ArgumentError, 'runtime must be provided (String)!'
65
+ end
66
+
67
+ case options_with_defaults[:runtime]
68
+ when 'nodejs' then raise ArgumentError, 'AWS Lambda Runtime NodeJS v0.10.42 is deprecated as of April 2017. \
69
+ Please see: https://forums.aws.amazon.com/ann.jspa?annID=4142'
70
+ when 'nodejs4.3', 'nodejs6.10', 'java8', 'python2.7', 'python3.6', 'dotnetcore1.0', 'nodejs4.3-edge'
71
+ @runtime = options_with_defaults[:runtime]
72
+ else
73
+ raise ArgumentError, "Invalid Runtime specified: #{options_with_defaults[:runtime]}. Only accepts: \
74
+ nodejs4.3, nodejs6.10, java8, python2.7, python3.6, dotnetcore1.0, or nodejs4.3-edge"
75
+ end
76
+
77
+ @description = options_with_defaults[:description]
78
+
79
+ @timeout = options_with_defaults[:timeout]
80
+
81
+ unless (options_with_defaults[:memory_size] % 64).zero? && (options_with_defaults[:memory_size] >= 128) &&
82
+ (options_with_defaults[:memory_size] <= 1536)
83
+ raise ArgumentError, 'Invalid Memory Size.'
84
+ end
85
+ @memory_size = options_with_defaults[:memory_size]
86
+
87
+ # VPC
88
+ if options_with_defaults[:subnet_ids].empty? ^ options_with_defaults[:security_group_ids].empty?
89
+ raise ArgumentError, 'Must supply values for BOTH Subnet Ids and Security Group ID if VPC is desired.'
90
+ end
91
+ unless options_with_defaults[:subnet_ids].empty?
92
+ @vpc_configuration = {
93
+ subnet_ids: options_with_defaults[:subnet_ids],
94
+ security_group_ids: options_with_defaults[:security_group_ids]
95
+ }
96
+ end
97
+
98
+ @delete_unreferenced_versions = options_with_defaults[:delete_unreferenced_versions]
39
99
  end
40
100
 
41
- ##
42
- # Publishes a package to S3 so it can be deployed as a lambda function.
101
+ # Deploys the Lambda to the specified Environment. Creates a Lambda Function if one didn't exist.
102
+ # Updates the Lambda's configuration, Updates the Lambda's Code, publishes a new version, and creates
103
+ # an alias that points to the newly published version. If the @delete_unreferenced_versions option
104
+ # is enabled, all Lambda Function versions that don't have an alias pointing to them will be deleted.
43
105
  #
44
- # *Arguments*
45
- # [local_lambda_file] The location of the package that needs to be deployed.
46
- # [bucket] The s3 bucket where the file needs to be uploaded to.
47
- # [key] The S3 path (key) where the package should be stored.
48
- def publish_lambda_to_s3(local_lambda_file, bucket, key)
49
- # get s3 object
50
- s3 = Aws::S3::Resource.new
51
- obj = s3.bucket(bucket).object(key)
106
+ # @param environment_options [LambdaWrap::Environment] The target Environment to deploy
107
+ # @param client [Aws::Lambda::Client] Client to use with SDK. Should be passed in by the API class.
108
+ # @param region [String] AWS Region string. Should be passed in by the API class.
109
+ def deploy(environment_options, client, region = 'AWS_REGION')
110
+ super
111
+
112
+ puts "Deploying Lambda: #{@lambda_name} to Environment: #{environment_options.name}"
52
113
 
53
- # upload
54
- version_id = nil
55
- File.open(local_lambda_file, 'rb') do |file|
56
- version_id = obj.put(body: file).version_id
114
+ unless File.exist?(@path_to_zip_file)
115
+ raise ArgumentError, "Deployment Package Zip File does not exist: #{@path_to_zip_file}!"
57
116
  end
58
- raise 'Upload to S3 failed' unless version_id
59
117
 
60
- puts 'Uploaded object to S3 with version ' + version_id
61
- version_id
118
+ lambda_details = retrieve_lambda_details
119
+
120
+ if lambda_details.nil?
121
+ function_version = create_lambda
122
+ else
123
+ update_lambda_config
124
+ function_version = update_lambda_code
125
+ end
126
+
127
+ create_alias(function_version, environment_options.name, environment_options.description)
128
+
129
+ cleanup_unused_versions if @delete_unreferenced_versions
130
+
131
+ puts "Lambda: #{@lambda_name} successfully deployed!"
132
+ true
133
+ end
134
+
135
+ # Tearsdown an Environment. Deletes an alias with the same name as the environment. Deletes
136
+ # Unreferenced Lambda Function Versions if the option was specified.
137
+ #
138
+ # @param environment_options [LambdaWrap::Environment] The target Environment to teardown.
139
+ # @param client [Aws::Lambda::Client] Client to use with SDK. Should be passed in by the API class.
140
+ # @param region [String] AWS Region string. Should be passed in by the API class.
141
+ def teardown(environment_options, client, region = 'AWS_REGION')
142
+ super
143
+ remove_alias(environment_options.name)
144
+ cleanup_unused_versions if @delete_unreferenced_versions
145
+ true
62
146
  end
63
147
 
64
- ##
65
- # Deploys a package that has been uploaded to S3.
148
+ # Deletes the Lambda Object with associated versions, code, configuration, and aliases.
66
149
  #
67
- # *Arguments*
68
- # [bucket] The S3 bucket where the package can be retrieved from.
69
- # [key] The S3 path (key) where the package can be retrieved from.
70
- # [version_id] The version of the file on S3 to retrieve.
71
- # [function_name] The name of the lambda function.
72
- # [handler] The handler that should be executed for this lambda function.
73
- # [lambda_role] The arn of the IAM role that should be used when executing the lambda function.
74
- # [lambda_description] The description of the lambda function.
75
- # [vpc_subnet_ids] A list of subnet ids for the lambda's VPC configuration. All subnets must be on the same VPC.
76
- # [vpc_security_group_ids] A list of security group ids for the lambda's VPC configuration. All of the
77
- # security_group_ids must be on the same VPC.
78
- # [runtime] The runtime the code is written for.
79
- # [timeout] The integer value of seconds until the lambda timesout. Minimum 1, Maximum 300
80
- # [memory_size] The Memory/ProcessingPower allocated for the Lambda. Minimum 128. Maximum 1536. Only accepts
81
- # integers in multiples of 64.
82
- def deploy_lambda(
83
- bucket, key, version_id, function_name, handler, lambda_role, lambda_description = 'Deployed with LambdaWrap',
84
- vpc_subnet_ids = [], vpc_security_group_ids = [], runtime = 'nodejs4.3', timeout = 5, memory_size = 128
85
- )
86
- # create or update function
150
+ # @param client [Aws::Lambda::Client] Client to use with SDK. Should be passed in by the API class.
151
+ # @param region [String] AWS Region string. Should be passed in by the API class.
152
+ def delete(client, region = 'AWS_REGION')
153
+ super
154
+ puts "Deleting all versions and aliases for Lambda: #{@lambda_name}"
155
+ lambda_details = retrieve_lambda_details
156
+ if lambda_details.nil?
157
+ puts 'No Lambda to delete.'
158
+ else
159
+ @client.delete_function(function_name: @lambda_name)
160
+ puts "Lambda #{@lambda_name} and all Versions & Aliases have been deleted."
161
+ end
162
+ true
163
+ end
164
+
165
+ def to_s
166
+ return @lambda_name if @lambda_name && @lambda_name.is_a?(String)
167
+ super
168
+ end
87
169
 
170
+ private
171
+
172
+ def retrieve_lambda_details
173
+ lambda_details = nil
88
174
  begin
89
- @client.get_function(function_name: function_name)
90
- unless vpc_subnet_ids.empty? && vpc_security_group_ids.empty?
91
- vpc_configuration = {
92
- subnet_ids: vpc_subnet_ids,
93
- security_group_ids: vpc_security_group_ids
94
- }
95
- end
96
- func_config = @client.update_function_configuration(
97
- function_name: function_name, role: lambda_role, runtime: runtime,
98
- handler: handler, timeout: timeout, memory_size: memory_size,
99
- description: lambda_description,
100
- vpc_config: vpc_configuration
101
- ).data
102
- puts func_config
103
-
104
- func_config = @client.update_function_code(
105
- function_name: function_name, s3_bucket: bucket, s3_key: key,
106
- s3_object_version: version_id, publish: true
107
- ).data
108
-
109
- puts func_config
110
- func_version = func_config.version
111
- raise 'Error while publishing existing lambda function ' + function_name unless func_version
112
- rescue Aws::Lambda::Errors::ResourceNotFoundException
113
- # check if vpc_subnet_ids and vpc_security_group_ids are empty or not and set the vpc_config accordingly.
114
- if vpc_subnet_ids.empty? && vpc_security_group_ids.empty?
115
- vpc_configuration = nil
116
- else
117
- vpc_configuration = { subnet_ids: vpc_subnet_ids, security_group_ids: vpc_security_group_ids }
118
- end
175
+ lambda_details = @client.get_function(function_name: @lambda_name).configuration
176
+ rescue Aws::Lambda::Errors::ResourceNotFoundException, Aws::Lambda::Errors::NotFound
177
+ puts "Lambda #{@lambda_name} does not exist."
178
+ end
179
+ lambda_details
180
+ end
181
+
182
+ def create_lambda
183
+ puts "Creating New Lambda Function: #{@lambda_name}...."
184
+ puts "Runtime Engine: #{@runtime}, Timeout: #{@timeout}, Memory Size: #{@memory_size}."
119
185
 
120
- # if we cannot find it, we have to create it instead of updating it
121
- func_config = @client.create_function(
122
- function_name: function_name, runtime: runtime, role: lambda_role,
123
- handler: handler, code: { s3_bucket: bucket, s3_key: key },
124
- timeout: timeout, memory_size: memory_size, publish: true,
125
- description: lambda_description,
126
- vpc_config: vpc_configuration
127
- ).data
186
+ lambda_version = @client.create_function(
187
+ function_name: @lambda_name, runtime: @runtime, role: @role_arn, handler: @handler,
188
+ code: { zip_file: @path_to_zip_file }, description: @description, timeout: @timeout, memory_size: @memory_size,
189
+ vpc_config: @vpc_configuration, publish: true
190
+ ).version
191
+ puts "Successfully created Lambda: #{@lambda_name}!"
192
+ lambda_version
193
+ end
128
194
 
129
- puts func_config
130
- func_version = func_config.version
131
- raise "Error while publishing new lambda function #{function_name}" unless func_version
195
+ def update_lambda_config
196
+ puts "Updating Lambda Config for #{@lambda_name}..."
197
+ puts "Runtime Engine: #{@runtime}, Timeout: #{@timeout}, Memory Size: #{@memory_size}."
198
+ if @vpc_configuration
199
+ puts "With VPC Configuration: Subnets: #{@vpc_configuration[:subnet_ids]}, Security Groups: \
200
+ #{@vpc_configuration[:security_group_ids]}"
132
201
  end
133
202
 
134
- add_api_gateway_permissions(function_name, nil)
203
+ @client.update_function_configuration(
204
+ function_name: @lambda_name, role: @role_arn, handler: @handler, description: @description, timeout: @timeout,
205
+ memory_size: @memory_size, vpc_config: @vpc_configuration, runtime: @runtime
206
+ )
135
207
 
136
- # return the version of the new code, not the config.
137
- func_version
208
+ puts "Successfully updated Lambda configuration for #{@lambda_name}"
138
209
  end
139
210
 
140
- ##
141
- # Creates an alias for a given lambda function version.
142
- #
143
- # *Arguments*
144
- # [function_name] The lambda function name for which the alias should be created.
145
- # [func_version] The lambda function versino to which the alias should point.
146
- # [alias_name] The name of the alias, matching the LambdaWrap environment concept.
147
- def create_alias(function_name, func_version, alias_name)
148
- # create or update alias
149
- func_alias = @client.list_aliases(function_name: function_name).aliases.select { |a| a.name == alias_name }.first
150
- a = if !func_alias
151
- @client.create_alias(
152
- function_name: function_name, name: alias_name, function_version: func_version,
153
- description: 'created by an automated script'
154
- ).data
211
+ def update_lambda_code
212
+ puts "Updating Lambda Code for #{@lambda_name}...."
213
+
214
+ response = @client.update_function_code(
215
+ function_name: @lambda_name,
216
+ zip_file: File.open(@path_to_zip_file, 'rb').read,
217
+ publish: true
218
+ )
219
+
220
+ puts "Successully updated Lambda #{@lambda_name} code to version: #{response.version}"
221
+ response.version
222
+ end
223
+
224
+ def create_alias(func_version, alias_name, alias_description)
225
+ 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
+ )
230
+ 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
+ )
235
+ end
236
+ puts "Created Alias: #{alias_name} for Lambda: #{@lambda_name} v#{func_version}."
237
+ end
238
+
239
+ def remove_alias(alias_name)
240
+ puts "Deleting Alias: #{alias_name} for #{@lambda_name}"
241
+ @client.delete_alias(function_name: @lambda_name, name: alias_name)
242
+ end
243
+
244
+ def cleanup_unused_versions
245
+ puts "Cleaning up unused function versions for #{@lambda_name}."
246
+ function_versions_to_be_deleted = retrieve_all_function_versions -
247
+ retrieve_function_versions_used_in_aliases
248
+
249
+ return if function_versions_to_be_deleted.empty?
250
+
251
+ function_versions_to_be_deleted.each do |version|
252
+ puts "Deleting function version: #{version}."
253
+ @client.delete_function(function_name: @lambda_name, qualifier: version)
254
+ end
255
+
256
+ puts "Cleaned up #{function_versions_to_be_deleted.length} unused versions."
257
+ end
258
+
259
+ def retrieve_all_function_versions
260
+ function_versions = []
261
+ response = nil
262
+ loop do
263
+ response =
264
+ if !response || response.next_marker.nil? || response.next_marker.empty?
265
+ @client.list_versions_by_function(function_name: @lambda_name)
155
266
  else
156
- @client.update_alias(
157
- function_name: function_name, name: alias_name, function_version: func_version,
158
- description: 'updated by an automated script'
159
- ).data
267
+ @client.list_versions_by_function(function_name: @lambda_name, marker: response.next_marker)
160
268
  end
161
- puts a
269
+ function_versions.concat(response.versions.map(&:version))
270
+ if response.next_marker.nil? || response.next_marker.empty?
271
+ return function_versions.reject { |v| v == '$LATEST' }
272
+ end
273
+ end
274
+ end
162
275
 
163
- add_api_gateway_permissions(function_name, alias_name)
276
+ def retrieve_all_aliases
277
+ aliases = []
278
+ response = nil
279
+ loop do
280
+ response = invoke_client_method_with_optional_marker(response, :list_aliases)
281
+ aliases.concat(response.aliases)
282
+ return aliases if response.aliases.empty? || response.next_marker.nil? || response.next_marker.empty?
283
+ end
164
284
  end
165
285
 
166
- ##
167
- # Removes an alias for a function.
168
- #
169
- # *Arguments*
170
- # [function_name] The lambda function name for which the alias should be removed.
171
- # [alias_name] The alias to remove.
172
- def remove_alias(function_name, alias_name)
173
- @client.delete_alias(function_name: function_name, name: alias_name)
286
+ def retrieve_function_versions_used_in_aliases
287
+ function_versions_with_aliases = Set.new []
288
+ function_versions_with_aliases.merge(retrieve_all_aliases.map(&:function_version)).to_a
174
289
  end
175
290
 
176
- ##
177
- # Adds permissions for API gateway to execute this function.
178
- #
179
- # *Arguments*
180
- # [function_name] The function name which needs to be executed from API Gateway.
181
- # [env] The environment (matching the function's alias) which needs to be executed from API Gateway.
182
- # => If nil, the permissions are set of the $LATEST version.
183
- def add_api_gateway_permissions(function_name, env)
184
- # permissions to execute lambda
185
- suffix = (':' + env if env) || ''
186
- func = @client.get_function(function_name: function_name + suffix).data.configuration
187
- statement_id = func.function_name + (('-' + env if env) || '')
188
- begin
189
- existing_policies = @client.get_policy(function_name: func.function_arn).data
190
- existing_policy = JSON.parse(existing_policies.policy)
191
- policy_exists = existing_policy['Statement'].select { |s| s['Sid'] == statement_id }.any?
192
- rescue Aws::Lambda::Errors::ResourceNotFoundException
193
- # policy does not exist, and that is ok
194
- policy_exists = false
195
- end
196
-
197
- unless policy_exists
198
- perm_add = @client.add_permission(
199
- function_name: func.function_arn, statement_id: statement_id,
200
- action: 'lambda:*', principal: 'apigateway.amazonaws.com'
201
- )
202
- puts perm_add.data
203
- end
291
+ def alias_exist?(alias_name)
292
+ retrieve_all_aliases.detect { |a| a.name == alias_name }
204
293
  end
205
294
 
206
- private :add_api_gateway_permissions
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
207
302
  end
208
303
  end
@@ -1,3 +1,4 @@
1
1
  module LambdaWrap
2
- VERSION = '0.27.0'.freeze
2
+ # @!visibility private
3
+ VERSION = '1.0.0'.freeze
3
4
  end
data/lib/lambda_wrap.rb CHANGED
@@ -1,5 +1,15 @@
1
- # :nodoc:
2
- Dir["#{File.expand_path(File.dirname(__FILE__))}/**/*.rb"].each { |f| require f }
1
+ require 'lambda_wrap/version'
2
+
3
+ require 'aws-sdk'
4
+ require 'yaml'
5
+ require 'active_support/core_ext/hash'
6
+
7
+ require 'lambda_wrap/aws_service'
8
+ require 'lambda_wrap/lambda_manager'
9
+ require 'lambda_wrap/dynamo_db_manager'
10
+ require 'lambda_wrap/api_gateway_manager'
11
+ require 'lambda_wrap/environment'
12
+ require 'lambda_wrap/api_manager'
3
13
 
4
14
  STDOUT.sync = true
5
15
  STDERR.sync = true
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: 0.27.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Thurner
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-04-10 00:00:00.000000000 Z
13
+ date: 2017-05-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk
@@ -27,19 +27,19 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  version: '2'
29
29
  - !ruby/object:Gem::Dependency
30
- name: rubyzip
30
+ name: activesupport
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.2'
35
+ version: '4'
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: '1.2'
42
+ version: '4'
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.
@@ -51,11 +51,12 @@ extra_rdoc_files: []
51
51
  files:
52
52
  - lib/lambda_wrap.rb
53
53
  - lib/lambda_wrap/api_gateway_manager.rb
54
+ - lib/lambda_wrap/api_manager.rb
55
+ - lib/lambda_wrap/aws_service.rb
54
56
  - lib/lambda_wrap/dynamo_db_manager.rb
57
+ - lib/lambda_wrap/environment.rb
55
58
  - lib/lambda_wrap/lambda_manager.rb
56
- - lib/lambda_wrap/s3_bucket_manager.rb
57
59
  - lib/lambda_wrap/version.rb
58
- - lib/lambda_wrap/zip_file_generator.rb
59
60
  homepage: https://github.com/Cimpress-MCP/LambdaWrap
60
61
  licenses:
61
62
  - Apache-2.0
@@ -68,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
69
  requirements:
69
70
  - - ">="
70
71
  - !ruby/object:Gem::Version
71
- version: '0'
72
+ version: 1.9.3
72
73
  required_rubygems_version: !ruby/object:Gem::Requirement
73
74
  requirements:
74
75
  - - ">="
@@ -1,32 +0,0 @@
1
- require 'aws-sdk'
2
-
3
- module LambdaWrap
4
- ##
5
- # The S3BucketManager would have functions to help add policies, CORS etc to S3 bucket.
6
- class S3BucketManager
7
- #
8
- # The constructor creates an instance of s3 bucket
9
- # * Validating basic AWS configuration
10
- # * Creating the underlying client to interact with the AWS SDK.
11
- # * Defining the temporary path of the api-gateway-importer jar file
12
- def initialize
13
- @s3bucket = Aws::S3::Client.new
14
- end
15
-
16
- ##
17
- # Adds policy to the bucket
18
- #
19
- # *Arguments*
20
- # [s3_bucket_name] S3 bucket name.
21
- # [policy] Policy to be added to the bucket
22
- def setup_policy(s3_bucket_name, policy)
23
- # Validate the parameters
24
- raise 'S3 bucket is not provided' unless s3_bucket_name
25
- raise 'Policy json is not provided' unless policy
26
-
27
- @s3bucket.put_bucket_policy(bucket: s3_bucket_name,
28
- policy: policy.to_json)
29
- puts "Created/Updated policy: #{policy} in S3 bucket #{s3_bucket_name}"
30
- end
31
- end
32
- end