Class: Jets::Cfn::Resource::Lambda::Function
- Includes:
- Environment
- Defined in:
- lib/jets/cfn/resource/lambda/function/controller.rb,
lib/jets/cfn/resource/lambda/function.rb,
lib/jets/cfn/resource/lambda/function/environment.rb
Overview
Handles one_lambda_per_controller
Direct Known Subclasses
Defined Under Namespace
Modules: Environment Classes: Controller
Constant Summary collapse
- MAX_FUNCTION_NAME_SIZE =
64
Class Method Summary collapse
-
.default_runtimes ⇒ Object
Also used by jets/stack/main/dsl/lambda.rb.
Instance Method Summary collapse
-
#assign_iam_role?(klass) ⇒ Boolean
The IAM Role is built in the same nested template but determination of whether or not to assign the IAM Role is determined by the inheritance.
-
#class_properties ⇒ Object
Class properties example:.
- #code_s3_key ⇒ Object
- #combined_properties ⇒ Object
-
#default_description ⇒ Object
Example values: @app_class: Admin/PagesController @definition.meth: index Returns: Admin/PagesController or Admin/PagesController#index.
- #default_handler ⇒ Object
- #default_runtime ⇒ Object
- #definition ⇒ Object
-
#finalize_properties!(props) ⇒ Object
Properties managed by Jets merged with finality.
-
#full_handler(props) ⇒ Object
Ensure that the handler path is normalized.
-
#function_logical_id ⇒ Object
Examples: one_lambda_per_controller PostsControllerLambdaHandlerLambdaFunction one_lambda_per_method PostsControllerIndexLambdaFunction.
-
#function_name ⇒ Object
Examples: “#Jets.project_namespace-sleep_job-perform” “demo-dev-sleep_job-perform”.
-
#function_properties ⇒ Object
Function properties example:.
- #get_descripton(props) ⇒ Object
- #get_layers(runtime) ⇒ Object
- #get_runtime(props) ⇒ Object
-
#global_properties ⇒ Object
Global properties example: jets defaults are in jets/default/application.rb.
- #handler ⇒ Object
-
#handler_value(meth) ⇒ Object
Used for node-shim also.
-
#initialize(definition) ⇒ Function
constructor
A new instance of Function.
-
#lookup_class_properties(klass) ⇒ Object
Accounts for inherited class_properties.
- #one_lambda_per_controller? ⇒ Boolean
- #replacements ⇒ Object
Methods included from Environment
#env_properties, #environment, #jets_env
Methods inherited from Base
#attributes, #logical_id, #outputs, #parameters, #permission, #properties, #replacer, #standarize, #template, truncate_id, #type
Methods included from Util::Camelize
Constructor Details
#initialize(definition) ⇒ Function
Returns a new instance of Function.
6 7 8 9 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 6 def initialize(definition) @definition = definition @app_class = definition.class_name.to_s end |
Class Method Details
.default_runtimes ⇒ Object
Also used by jets/stack/main/dsl/lambda.rb
179 180 181 182 183 184 185 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 179 def self.default_runtimes { node: "nodejs18.x", python: "python3.10", ruby: Jets.ruby_runtime, } end |
Instance Method Details
#assign_iam_role?(klass) ⇒ Boolean
The IAM Role is built in the same nested template but determination of whether or not to assign the IAM Role is determined by the inheritance. The merging of permissions is already handled by Resource::Iam::*Role classes. This also avoids having to pass Application IAM role around.
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 91 def assign_iam_role?(klass) assign = false while klass && klass != Object if klass&.build_class_iam? assign = true break end klass = klass.superclass end assign end |
#class_properties ⇒ Object
Class properties example:
class PostsController < ApplicationController
class_timeout 22
...
end
Also handles iam policy override at the class level. Example:
class_iam_policy("logs:*")
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 74 def class_properties # klass is PostsController, HardJob, GameRule, Hello or HelloFunction klass = Jets::Klass.from_definition(@definition) class_properties = lookup_class_properties(klass) if assign_iam_role?(klass) iam_policy = Jets::Cfn::Resource::Iam::ClassRole.new(klass) class_properties[:Role] = "!GetAtt #{iam_policy.logical_id}.Arn" end camelize(class_properties) end |
#code_s3_key ⇒ Object
214 215 216 217 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 214 def code_s3_key checksum = Jets::Builders::Md5.checksums["stage/code"] "jets/code/code-#{checksum}.zip" # s3_key end |
#combined_properties ⇒ Object
31 32 33 34 35 36 37 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 31 def combined_properties props = env_properties .deep_merge(global_properties) .deep_merge(class_properties) .deep_merge(function_properties) finalize_properties!(props) end |
#default_description ⇒ Object
Example values:
@app_class: Admin/PagesController
@definition.meth: index
Returns:
Admin/PagesController
or
Admin/PagesController#index
254 255 256 257 258 259 260 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 254 def default_description if one_lambda_per_controller? "#{@app_class}" else "#{@app_class}##{@definition.meth}" end end |
#default_handler ⇒ Object
187 188 189 190 191 192 193 194 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 187 def default_handler map = { node: @definition.full_handler(:handler), # IE: handlers/controllers/posts/show.handler python: @definition.full_handler(:lambda_handler), # IE: handlers/controllers/posts/show.lambda_handler ruby: handler, # IE: handlers/controllers/posts_controllers.index } map[@definition.lang] end |
#default_runtime ⇒ Object
174 175 176 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 174 def default_runtime self.class.default_runtimes[@definition.lang] end |
#definition ⇒ Object
11 12 13 14 15 16 17 18 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 11 def definition { function_logical_id => { Type: "AWS::Lambda::Function", Properties: combined_properties } } end |
#finalize_properties!(props) ⇒ Object
Properties managed by Jets merged with finality.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 143 def finalize_properties!(props) handler = full_handler(props) runtime = get_runtime(props) description = get_descripton(props) managed = { Handler: handler, Runtime: runtime, Description: description, } managed[:FunctionName] = function_name if function_name layers = get_layers(runtime) managed[:Layers] = layers if layers props.merge!(managed) end |
#full_handler(props) ⇒ Object
Ensure that the handler path is normalized.
206 207 208 209 210 211 212 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 206 def full_handler(props) if props[:Handler] handler_value(props[:Handler]) else default_handler end end |
#function_logical_id ⇒ Object
Examples:
one_lambda_per_controller PostsControllerLambdaHandlerLambdaFunction
one_lambda_per_method PostsControllerIndexLambdaFunction
23 24 25 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 23 def function_logical_id "{namespace}LambdaFunction" end |
#function_name ⇒ Object
Examples:
"#{Jets.project_namespace}-sleep_job-perform"
"demo-dev-sleep_job-perform"
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 222 def function_name return if ENV['JETS_RESET'] # reset mode, let CloudFormation manage the function name # Example values: # @app_class: admin/pages_controller # @definition.meth: index # method: admin/pages_controller # method: admin-pages_controller-index method = @app_class.underscore method = method.gsub('/','-').gsub(/[^0-9a-z\-_]/i, '') unless one_lambda_per_controller? method += "-#{@definition.meth}" end function_name = "#{Jets.project_namespace}-#{method}" # Returns nil if function name is too long. # CloudFormation will managed the the function name in this case. # A pretty function name won't be generated but the deploy will be successful. function_name.size > MAX_FUNCTION_NAME_SIZE ? nil : function_name end |
#function_properties ⇒ Object
Function properties example:
class PostsController < ApplicationController
timeout 18
def index
...
end
Also handles iam policy override at the function level. Example:
iam_policy("ec2:*")
def new
render json: params.merge(action: "new")
end
133 134 135 136 137 138 139 140 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 133 def function_properties properties = @definition.properties if @definition.build_function_iam? iam_policy = Jets::Cfn::Resource::Iam::FunctionRole.new(@definition) properties[:Role] = "!GetAtt #{iam_policy.logical_id}.Arn" end camelize(properties) end |
#get_descripton(props) ⇒ Object
243 244 245 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 243 def get_descripton(props) props[:Description] || default_description end |
#get_layers(runtime) ⇒ Object
158 159 160 161 162 163 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 158 def get_layers(runtime) return nil unless runtime =~ /^ruby/ || runtime =~ /^provided/ return Jets.config.lambda.layers if Jets.config.pro.disable ["!Ref GemLayer"] + Jets.config.lambda.layers end |
#get_runtime(props) ⇒ Object
165 166 167 168 169 170 171 172 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 165 def get_runtime(props) # Only allow custom runtime for ruby so polymorphic support works for python and node if @definition.lang == :ruby props[:Runtime] || default_runtime else default_runtime end end |
#global_properties ⇒ Object
Global properties example: jets defaults are in jets/default/application.rb. Your application’s default config/application.rb then get used. Example:
Jets.application.configure do
config.function = ActiveSupport::OrderedOptions.new
config.function.timeout = 30
config.function.runtime = "nodejs8.10"
config.function.memory_size = 1536
end
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 49 def global_properties baseline = { Code: { S3Bucket: "!Ref S3Bucket", S3Key: code_s3_key }, Role: "!Ref IamRole", Environment: { Variables: environment }, } application_config = camelize(Jets.application.config.function.to_h) baseline.merge(application_config) end |
#handler ⇒ Object
196 197 198 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 196 def handler handler_value(@definition.meth) # IE: handlers/controllers/posts_controllers.index end |
#handler_value(meth) ⇒ Object
Used for node-shim also
201 202 203 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 201 def handler_value(meth) "handlers/#{@definition.type.pluralize}/#{@app_class.underscore}.#{meth}" end |
#lookup_class_properties(klass) ⇒ Object
Accounts for inherited class_properties
104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 104 def lookup_class_properties(klass) all_classes = [] while klass != Object all_classes << klass klass = klass.superclass end class_properties = {} # Go back down class heirachry top to down all_classes.reverse.each do |k| class_properties.merge!(k.class_properties) end class_properties end |
#one_lambda_per_controller? ⇒ Boolean
262 263 264 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 262 def one_lambda_per_controller? Jets.one_lambda_per_controller? && @app_class.to_s.ends_with?("Controller") end |
#replacements ⇒ Object
27 28 29 |
# File 'lib/jets/cfn/resource/lambda/function.rb', line 27 def replacements @definition.replacements # has namespace replacement end |