lambda_wrap 0.27.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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