def _create_function(self, function_name): arn = lambda_api.func_arn(function_name) lambda_api.arn_to_lambda[arn] = LambdaFunction(arn) lambda_api.arn_to_lambda[arn].versions = {'$LATEST': {'CodeSize': self.CODE_SIZE}} lambda_api.arn_to_lambda[arn].handler = self.HANDLER lambda_api.arn_to_lambda[arn].runtime = self.RUNTIME lambda_api.arn_to_lambda[arn].envvars = {}
def create_function(): """ Create new function --- operationId: 'createFunction' parameters: - name: 'request' in: body """ arn = 'n/a' try: data = json.loads(to_str(request.data)) lambda_name = data['FunctionName'] event_publisher.fire_event( event_publisher.EVENT_LAMBDA_CREATE_FUNC, payload={'n': event_publisher.get_hash(lambda_name)}) arn = func_arn(lambda_name) if arn in arn_to_lambda: return error_response('Function already exist: %s' % lambda_name, 409, error_type='ResourceConflictException') arn_to_lambda[arn] = func_details = LambdaFunction(arn) func_details.versions = {'$LATEST': {'CodeSize': 50}} func_details.handler = data['Handler'] func_details.runtime = data['Runtime'] func_details.envvars = data.get('Environment', {}).get('Variables', {}) func_details.tags = data.get('Tags', {}) func_details.timeout = data.get('Timeout', LAMBDA_DEFAULT_TIMEOUT) result = set_function_code(data['Code'], lambda_name) if isinstance(result, Response): del arn_to_lambda[arn] return result result.update({ 'DeadLetterConfig': data.get('DeadLetterConfig'), 'Description': data.get('Description'), 'Environment': { 'Error': {}, 'Variables': func_details.envvars }, 'FunctionArn': arn, 'FunctionName': lambda_name, 'Handler': func_details.handler, 'MemorySize': data.get('MemorySize'), 'Role': data.get('Role'), 'Runtime': func_details.runtime, 'Timeout': func_details.timeout, 'TracingConfig': {}, 'VpcConfig': { 'SecurityGroupIds': [None], 'SubnetIds': [None], 'VpcId': None } }) if data.get('Publish', False): result['Version'] = publish_new_function_version(arn)['Version'] return jsonify(result or {}) except Exception as e: arn_to_lambda.pop(arn, None) return error_response('Unknown error: %s %s' % (e, traceback.format_exc()))
def handle(func): func_name = func['FunctionName'] if re.match(filter, func_name): arn = func['FunctionArn'] f = LambdaFunction(arn) pool[arn] = f result.append(f) if details: sources = get_lambda_event_sources(f.name(), env=env) for src in sources: arn = src['EventSourceArn'] f.event_sources.append(EventSource.get(arn, pool=pool)) try: code_map = get_lambda_code(func_name, env=env) f.targets = extract_endpoints(code_map, pool) except Exception: LOG.warning("Unable to get code for lambda '%s'" % func_name)
class TestLambdaEventInvokeConfig(unittest.TestCase): CODE_SIZE = 50 CODE_SHA_256 = '/u60ZpAA9bzZPVwb8d4390i5oqP1YAObUwV03CZvsWA=' MEMORY_SIZE = 128 ROLE = LAMBDA_TEST_ROLE LAST_MODIFIED = datetime.datetime.utcnow() REVISION_ID = 'e54dbcf8-e3ef-44ab-9af7-8dbef510608a' HANDLER = 'index.handler' RUNTIME = 'node.js4.3' TIMEOUT = 60 FUNCTION_NAME = 'test1' RETRY_ATTEMPTS = 5 EVENT_AGE = 360 DL_QUEUE = 'arn:aws:sqs:us-east-1:000000000000:dlQueue' LAMBDA_OBJ = LambdaFunction(lambda_api.func_arn('test1')) def _create_function(self, function_name, tags={}): self.LAMBDA_OBJ.versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } self.LAMBDA_OBJ.handler = self.HANDLER self.LAMBDA_OBJ.runtime = self.RUNTIME self.LAMBDA_OBJ.timeout = self.TIMEOUT self.LAMBDA_OBJ.tags = tags self.LAMBDA_OBJ.envvars = {} self.LAMBDA_OBJ.last_modified = self.LAST_MODIFIED self.LAMBDA_OBJ.role = self.ROLE self.LAMBDA_OBJ.memory_size = self.MEMORY_SIZE # TODO: remove this test case. Already added it in integration test case def test_put_function_event_invoke_config(self): # creating a lambda function self._create_function(self.FUNCTION_NAME) # calling put_function_event_invoke_config payload = { 'DestinationConfig': { 'OnFailure': { 'Destination': self.DL_QUEUE } }, 'MaximumEventAgeInSeconds': self.EVENT_AGE, 'MaximumRetryAttempts': self.RETRY_ATTEMPTS } response = self.LAMBDA_OBJ.put_function_event_invoke_config( payload ) # checking if response is not None self.assertIsNotNone(response) # calling get_function_event_invoke_config response = self.LAMBDA_OBJ.get_function_event_invoke_config() # verifying set values self.assertEqual(response['FunctionArn'], self.LAMBDA_OBJ.id) self.assertEqual(response['MaximumRetryAttempts'], self.RETRY_ATTEMPTS) self.assertEqual(response['MaximumEventAgeInSeconds'], self.EVENT_AGE) self.assertEqual(response['DestinationConfig']['OnFailure']['Destination'], self.DL_QUEUE)
def lambda_result_to_destination( func_details: LambdaFunction, event: Dict, result: InvocationResult, is_async: bool, error: InvocationException, ): if not func_details.destination_enabled(): return payload = { "version": "1.0", "timestamp": timestamp_millis(), "requestContext": { "requestId": long_uid(), "functionArn": func_details.arn(), "condition": "RetriesExhausted", "approximateInvokeCount": 1, }, "requestPayload": event, "responseContext": { "statusCode": 200, "executedVersion": "$LATEST" }, "responsePayload": {}, } if result and result.result: try: payload["requestContext"]["condition"] = "Success" payload["responsePayload"] = json.loads(result.result) except Exception: payload["responsePayload"] = result.result if error: payload["responseContext"]["functionError"] = "Unhandled" # add the result in the response payload if error.result is not None: payload["responsePayload"] = json.loads(error.result) send_event_to_target(func_details.on_failed_invocation, payload) return if func_details.on_successful_invocation is not None: send_event_to_target(func_details.on_successful_invocation, payload)
def store_lambda_logs(lambda_function: LambdaFunction, log_output: str, invocation_time=None, container_id=None): log_group_name = "/aws/lambda/%s" % lambda_function.name() container_id = container_id or short_uid() invocation_time = invocation_time or int(time.time() * 1000) invocation_time_secs = int(invocation_time / 1000) time_str = time.strftime("%Y/%m/%d", time.gmtime(invocation_time_secs)) log_stream_name = "%s/[LATEST]%s" % (time_str, container_id) return store_cloudwatch_logs(log_group_name, log_stream_name, log_output, invocation_time)
def _create_function(self, function_name, tags={}): arn = lambda_api.func_arn(function_name) lambda_api.arn_to_lambda[arn] = LambdaFunction(arn) lambda_api.arn_to_lambda[arn].versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } lambda_api.arn_to_lambda[arn].handler = self.HANDLER lambda_api.arn_to_lambda[arn].runtime = self.RUNTIME lambda_api.arn_to_lambda[arn].timeout = self.TIMEOUT lambda_api.arn_to_lambda[arn].tags = tags lambda_api.arn_to_lambda[arn].envvars = {} lambda_api.arn_to_lambda[arn].last_modified = self.LAST_MODIFIED lambda_api.arn_to_lambda[arn].role = self.ROLE lambda_api.arn_to_lambda[arn].memory_size = self.MEMORY_SIZE
def create_function(): """ Create new function --- operationId: 'createFunction' parameters: - name: 'request' in: body """ arn = 'n/a' try: data = json.loads(to_str(request.data)) lambda_name = data['FunctionName'] event_publisher.fire_event( event_publisher.EVENT_LAMBDA_CREATE_FUNC, payload={'n': event_publisher.get_hash(lambda_name)}) arn = func_arn(lambda_name) if arn in arn_to_lambda: return error_response('Function already exist: %s' % lambda_name, 409, error_type='ResourceConflictException') arn_to_lambda[arn] = func_details = LambdaFunction(arn) func_details.versions = {'$LATEST': {'RevisionId': str(uuid.uuid4())}} func_details.last_modified = isoformat_milliseconds( datetime.utcnow()) + '+0000' func_details.description = data.get('Description', '') func_details.handler = data['Handler'] func_details.runtime = data['Runtime'] func_details.envvars = data.get('Environment', {}).get('Variables', {}) func_details.tags = data.get('Tags', {}) func_details.timeout = data.get('Timeout', LAMBDA_DEFAULT_TIMEOUT) func_details.role = data['Role'] func_details.memory_size = data.get('MemorySize') func_details.code = data['Code'] result = set_function_code(func_details.code, lambda_name) if isinstance(result, Response): del arn_to_lambda[arn] return result # remove content from code attribute, if present func_details.code.pop('ZipFile', None) # prepare result result.update(format_func_details(func_details)) if data.get('Publish', False): result['Version'] = publish_new_function_version(arn)['Version'] return jsonify(result or {}) except Exception as e: arn_to_lambda.pop(arn, None) if isinstance(e, ClientError): return e.get_response() return error_response('Unknown error: %s %s' % (e, traceback.format_exc()))
def store_lambda_logs(lambda_function: LambdaFunction, log_output: str, invocation_time=None, container_id=None): # leave here to avoid import issues from CLI from localstack.utils.cloudwatch.cloudwatch_util import store_cloudwatch_logs log_group_name = "/aws/lambda/%s" % lambda_function.name() container_id = container_id or short_uid() invocation_time = invocation_time or int(time.time() * 1000) invocation_time_secs = int(invocation_time / 1000) time_str = time.strftime("%Y/%m/%d", time.gmtime(invocation_time_secs)) log_stream_name = "%s/[LATEST]%s" % (time_str, container_id) return store_cloudwatch_logs(log_group_name, log_stream_name, log_output, invocation_time)
def _create_function(self, function_name, tags={}): region = lambda_api.LambdaRegion.get() arn = lambda_api.func_arn(function_name) region.lambdas[arn] = LambdaFunction(arn) region.lambdas[arn].versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } region.lambdas[arn].handler = self.HANDLER region.lambdas[arn].runtime = self.RUNTIME region.lambdas[arn].timeout = self.TIMEOUT region.lambdas[arn].tags = tags region.lambdas[arn].envvars = {} region.lambdas[arn].last_modified = self.LAST_MODIFIED region.lambdas[arn].role = self.ROLE region.lambdas[arn].memory_size = self.MEMORY_SIZE
def create_function(): """ Create new function --- operationId: 'createFunction' parameters: - name: 'request' in: body """ arn = 'n/a' try: data = json.loads(to_str(request.data)) lambda_name = data['FunctionName'] event_publisher.fire_event( event_publisher.EVENT_LAMBDA_CREATE_FUNC, payload={'n': event_publisher.get_hash(lambda_name)}) arn = func_arn(lambda_name) if arn in arn_to_lambda: return error_response('Function already exist: %s' % lambda_name, 409, error_type='ResourceConflictException') arn_to_lambda[arn] = LambdaFunction(arn) arn_to_lambda[arn].versions = {'$LATEST': {'CodeSize': 50}} arn_to_lambda[arn].handler = data['Handler'] arn_to_lambda[arn].runtime = data['Runtime'] arn_to_lambda[arn].envvars = data.get('Environment', {}).get('Variables', {}) result = set_function_code(data['Code'], lambda_name) if isinstance(result, Response): del arn_to_lambda[arn] return result result.update({ "DeadLetterConfig": data.get('DeadLetterConfig'), "Description": data.get('Description'), "Environment": { "Error": {}, "Variables": arn_to_lambda[arn].envvars }, "FunctionArn": arn, "FunctionName": lambda_name, "Handler": arn_to_lambda[arn].handler, "MemorySize": data.get('MemorySize'), "Role": data.get('Role'), "Runtime": arn_to_lambda[arn].runtime, "Timeout": data.get('Timeout'), "TracingConfig": {}, "VpcConfig": { "SecurityGroupIds": [None], "SubnetIds": [None], "VpcId": None } }) return jsonify(result or {}) except Exception as e: del arn_to_lambda[arn] return error_response('Unknown error: %s' % e)
class TestLambdaEventInvokeConfig(unittest.TestCase): CODE_SIZE = 50 CODE_SHA_256 = "/u60ZpAA9bzZPVwb8d4390i5oqP1YAObUwV03CZvsWA=" MEMORY_SIZE = 128 ROLE = LAMBDA_TEST_ROLE LAST_MODIFIED = datetime.datetime.utcnow() REVISION_ID = "e54dbcf8-e3ef-44ab-9af7-8dbef510608a" HANDLER = "index.handler" RUNTIME = "node.js4.3" TIMEOUT = 60 FUNCTION_NAME = "test1" RETRY_ATTEMPTS = 5 EVENT_AGE = 360 DL_QUEUE = "arn:aws:sqs:us-east-1:000000000000:dlQueue" LAMBDA_OBJ = LambdaFunction(lambda_api.func_arn("test1")) def _create_function(self, function_name, tags={}): self.LAMBDA_OBJ.versions = { "$LATEST": { "CodeSize": self.CODE_SIZE, "CodeSha256": self.CODE_SHA_256, "RevisionId": self.REVISION_ID, } } self.LAMBDA_OBJ.handler = self.HANDLER self.LAMBDA_OBJ.runtime = self.RUNTIME self.LAMBDA_OBJ.timeout = self.TIMEOUT self.LAMBDA_OBJ.tags = tags self.LAMBDA_OBJ.envvars = {} self.LAMBDA_OBJ.last_modified = self.LAST_MODIFIED self.LAMBDA_OBJ.role = self.ROLE self.LAMBDA_OBJ.memory_size = self.MEMORY_SIZE # TODO: remove this test case. Already added it in integration test case def test_put_function_event_invoke_config(self): # creating a lambda function self._create_function(self.FUNCTION_NAME) # calling put_function_event_invoke_config payload = { "DestinationConfig": { "OnFailure": { "Destination": self.DL_QUEUE } }, "MaximumEventAgeInSeconds": self.EVENT_AGE, "MaximumRetryAttempts": self.RETRY_ATTEMPTS, } response = self.LAMBDA_OBJ.put_function_event_invoke_config(payload) # checking if response is not None self.assertIsNotNone(response) # calling get_function_event_invoke_config response = self.LAMBDA_OBJ.get_function_event_invoke_config() # verifying set values self.assertEqual(self.LAMBDA_OBJ.id, response["FunctionArn"]) self.assertEqual(self.RETRY_ATTEMPTS, response["MaximumRetryAttempts"]) self.assertEqual(self.EVENT_AGE, response["MaximumEventAgeInSeconds"]) self.assertEqual( self.DL_QUEUE, response["DestinationConfig"]["OnFailure"]["Destination"])