Пример #1
0
 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 = {}
Пример #2
0
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)
Пример #4
0
 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)
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
 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
Пример #9
0
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()))
Пример #10
0
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)
Пример #11
0
 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
Пример #12
0
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)
Пример #13
0
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"])