コード例 #1
0
    def test_lambda_function_name_invalid(self):
        with pytest.raises(InvalidArnException):
            assert lambda_function_name(
                "arn:aws:lambda:aws-region:acct-id") is None

        with pytest.raises(ValueError):
            assert lambda_function_name(
                "arn:aws:sqs:aws-region:acct-id:foo") is None
コード例 #2
0
        def send_log_event(*args, **kwargs):
            if backend.get_function(args[0]):
                return send_log_event_orig(*args, **kwargs)

            filter_name = args[1]
            log_group_name = args[2]
            log_stream_name = args[3]
            log_events = args[4]

            data = {
                'messageType': 'DATA_MESSAGE',
                'owner': aws_stack.get_account_id(),
                'logGroup': log_group_name,
                'logStream': log_stream_name,
                'subscriptionFilters': [filter_name],
                'logEvents': log_events,
            }

            payload = base64.b64encode(
                json.dumps(data,
                           separators=(',',
                                       ':')).encode('utf-8')).decode('utf-8')
            event = {'awslogs': {'data': payload}}
            client = aws_stack.connect_to_service('lambda')
            lambda_name = aws_stack.lambda_function_name(args[0])
            client.invoke(FunctionName=lambda_name, Payload=event)
コード例 #3
0
        def send_log_event(*args, **kwargs):

            filter_name = args[1]
            log_group_name = args[2]
            log_stream_name = args[3]
            log_events = args[4]

            data = {
                'messageType': 'DATA_MESSAGE',
                'owner': aws_stack.get_account_id(),
                'logGroup': log_group_name,
                'logStream': log_stream_name,
                'subscriptionFilters': [filter_name],
                'logEvents': log_events,
            }

            output = io.BytesIO()
            with GzipFile(fileobj=output, mode='w') as f:
                f.write(
                    json.dumps(data, separators=(',', ':')).encode('utf-8'))
            payload_gz_encoded = base64.b64encode(
                output.getvalue()).decode('utf-8')
            event = {'awslogs': {'data': payload_gz_encoded}}

            client = aws_stack.connect_to_service('lambda')
            lambda_name = aws_stack.lambda_function_name(args[0])
            client.invoke(FunctionName=lambda_name, Payload=json.dumps(event))
コード例 #4
0
 def fetch_state(self, stack_name, resources):
     name = self.resolve_refs_recursively(stack_name, self.props.get('FunctionName'), resources)
     if not name:
         return None
     func_name = aws_stack.lambda_function_name(name)
     func_version = name.split(':')[7] if len(name.split(':')) > 7 else '$LATEST'
     versions = aws_stack.connect_to_service('lambda').list_versions_by_function(FunctionName=func_name)
     return ([v for v in versions['Versions'] if v['Version'] == func_version] or [None])[0]
コード例 #5
0
    def put_log_events_model(self, log_group_name, log_stream_name, log_events,
                             sequence_token):
        # TODO: call/patch upstream method here, instead of duplicating the code!
        self.last_ingestion_time = int(unix_time_millis())
        self.stored_bytes += sum(
            [len(log_event["message"]) for log_event in log_events])
        events = [
            logs_models.LogEvent(self.last_ingestion_time, log_event)
            for log_event in log_events
        ]
        self.events += events
        self.upload_sequence_token += 1

        log_events = [{
            "id": event.event_id,
            "timestamp": event.timestamp,
            "message": event.message,
        } for event in events]

        data = {
            "messageType": "DATA_MESSAGE",
            "owner": aws_stack.get_account_id(),
            "logGroup": log_group_name,
            "logStream": log_stream_name,
            "subscriptionFilters": [self.filter_name],
            "logEvents": log_events,
        }

        output = io.BytesIO()
        with GzipFile(fileobj=output, mode="w") as f:
            f.write(json.dumps(data, separators=(",", ":")).encode("utf-8"))
        payload_gz_encoded = base64.b64encode(
            output.getvalue()).decode("utf-8")
        event = {"awslogs": {"data": payload_gz_encoded}}

        if self.destination_arn:
            if ":lambda:" in self.destination_arn:
                client = aws_stack.connect_to_service("lambda")
                lambda_name = aws_stack.lambda_function_name(
                    self.destination_arn)
                client.invoke(FunctionName=lambda_name,
                              Payload=json.dumps(event))
            if ":kinesis:" in self.destination_arn:
                client = aws_stack.connect_to_service("kinesis")
                stream_name = aws_stack.kinesis_stream_name(
                    self.destination_arn)
                client.put_record(
                    StreamName=stream_name,
                    Data=json.dumps(payload_gz_encoded),
                    PartitionKey=log_group_name,
                )
            if ":firehose:" in self.destination_arn:
                client = aws_stack.connect_to_service("firehose")
                firehose_name = aws_stack.firehose_name(self.destination_arn)
                client.put_record(
                    DeliveryStreamName=firehose_name,
                    Record={"Data": json.dumps(payload_gz_encoded)},
                )
コード例 #6
0
 def Mapping_create_from_cloudformation_json(cls, resource_name,
                                             cloudformation_json,
                                             region_name):
     props = cloudformation_json.get('Properties', {})
     func_name = props.get('FunctionName') or ''
     if ':lambda:' in func_name:
         props['FunctionName'] = aws_stack.lambda_function_name(func_name)
     return Mapping_create_from_cloudformation_json_orig(
         resource_name, cloudformation_json, region_name)
コード例 #7
0
 def get_function(*args, **kwargs):
     result = get_function_orig(*args, **kwargs)
     if result:
         return result
     # in case if lambda is not present in moto fall back to
     #  fetching Lambda details from LocalStack API directly
     client = aws_stack.connect_to_service('lambda')
     lambda_name = aws_stack.lambda_function_name(args[0])
     response = client.get_function(FunctionName=lambda_name)
     return response
コード例 #8
0
 def fetch_state(self, stack_name, resources):
     name = self.resolve_refs_recursively(stack_name, self.props.get("FunctionName"), resources)
     if not name:
         return None
     func_name = aws_stack.lambda_function_name(name)
     func_version = name.split(":")[7] if len(name.split(":")) > 7 else "$LATEST"
     versions = aws_stack.connect_to_service("lambda").list_versions_by_function(
         FunctionName=func_name
     )
     return ([v for v in versions["Versions"] if v["Version"] == func_version] or [None])[0]
コード例 #9
0
        def put_subscription_filter(*args, **kwargs):
            log_group_name = args[0]
            filter_name = args[1]
            filter_pattern = args[2]
            destination_arn = args[3]
            role_arn = args[4]

            log_group = logs_models.logs_backends[
                aws_stack.get_region()].groups.get(log_group_name)

            if not log_group:
                raise ResourceNotFoundException(
                    'The specified log group does not exist.')

            if ':lambda:' in destination_arn:
                client = aws_stack.connect_to_service('lambda')
                lambda_name = aws_stack.lambda_function_name(destination_arn)
                try:
                    client.get_function(FunctionName=lambda_name)
                except Exception:
                    raise InvalidParameterException(
                        'destinationArn for vendor lambda cannot be used with roleArn'
                    )

            elif ':kinesis:' in destination_arn:
                client = aws_stack.connect_to_service('kinesis')
                stream_name = aws_stack.kinesis_stream_name(destination_arn)
                try:
                    client.describe_stream(StreamName=stream_name)
                except Exception:
                    raise InvalidParameterException(
                        'Could not deliver test message to specified Kinesis stream. '
                        'Check if the given kinesis stream is in ACTIVE state. '
                    )

            elif ':firehose:' in destination_arn:
                client = aws_stack.connect_to_service('firehose')
                firehose_name = aws_stack.firehose_name(destination_arn)
                try:
                    client.describe_delivery_stream(
                        DeliveryStreamName=firehose_name)
                except Exception:
                    raise InvalidParameterException(
                        'Could not deliver test message to specified Firehose stream. '
                        'Check if the given Firehose stream is in ACTIVE state.'
                    )

            else:
                service = aws_stack.extract_service_from_arn(destination_arn)
                raise InvalidParameterException(
                    'PutSubscriptionFilter operation cannot work with destinationArn for vendor %s'
                    % service)

            log_group.put_subscription_filter(filter_name, filter_pattern,
                                              destination_arn, role_arn)
コード例 #10
0
def moto_put_subscription_filter(fn, self, *args, **kwargs):
    log_group_name = args[0]
    filter_name = args[1]
    filter_pattern = args[2]
    destination_arn = args[3]
    role_arn = args[4]

    log_group = self.groups.get(log_group_name)

    if not log_group:
        raise ResourceNotFoundException("The specified log group does not exist.")

    if ":lambda:" in destination_arn:
        client = aws_stack.connect_to_service("lambda")
        lambda_name = aws_stack.lambda_function_name(destination_arn)
        try:
            client.get_function(FunctionName=lambda_name)
        except Exception:
            raise InvalidParameterException(
                "destinationArn for vendor lambda cannot be used with roleArn"
            )

    elif ":kinesis:" in destination_arn:
        client = aws_stack.connect_to_service("kinesis")
        stream_name = aws_stack.kinesis_stream_name(destination_arn)
        try:
            client.describe_stream(StreamName=stream_name)
        except Exception:
            raise InvalidParameterException(
                "Could not deliver test message to specified Kinesis stream. "
                "Check if the given kinesis stream is in ACTIVE state. "
            )

    elif ":firehose:" in destination_arn:
        client = aws_stack.connect_to_service("firehose")
        firehose_name = aws_stack.firehose_name(destination_arn)
        try:
            client.describe_delivery_stream(DeliveryStreamName=firehose_name)
        except Exception:
            raise InvalidParameterException(
                "Could not deliver test message to specified Firehose stream. "
                "Check if the given Firehose stream is in ACTIVE state."
            )

    else:
        service = aws_stack.extract_service_from_arn(destination_arn)
        raise InvalidParameterException(
            f"PutSubscriptionFilter operation cannot work with destinationArn for vendor {service}"
        )

    if filter_pattern:
        for stream in log_group.streams.values():
            stream.filter_pattern = filter_pattern

    log_group.put_subscription_filter(filter_name, filter_pattern, destination_arn, role_arn)
コード例 #11
0
    def put_log_events_model(self, log_group_name, log_stream_name, log_events,
                             sequence_token):
        self.lastIngestionTime = int(unix_time_millis())
        self.storedBytes += sum(
            [len(log_event['message']) for log_event in log_events])
        events = [
            logs_models.LogEvent(self.lastIngestionTime, log_event)
            for log_event in log_events
        ]
        self.events += events
        self.uploadSequenceToken += 1

        log_events = [{
            'id': event.eventId,
            'timestamp': event.timestamp,
            'message': event.message,
        } for event in events]

        data = {
            'messageType': 'DATA_MESSAGE',
            'owner': aws_stack.get_account_id(),
            'logGroup': log_group_name,
            'logStream': log_stream_name,
            'subscriptionFilters': [self.filter_name],
            'logEvents': log_events,
        }

        output = io.BytesIO()
        with GzipFile(fileobj=output, mode='w') as f:
            f.write(json.dumps(data, separators=(',', ':')).encode('utf-8'))
        payload_gz_encoded = base64.b64encode(
            output.getvalue()).decode('utf-8')
        event = {'awslogs': {'data': payload_gz_encoded}}

        if self.destination_arn:
            if ':lambda:' in self.destination_arn:
                client = aws_stack.connect_to_service('lambda')
                lambda_name = aws_stack.lambda_function_name(
                    self.destination_arn)
                client.invoke(FunctionName=lambda_name,
                              Payload=json.dumps(event))
            if ':kinesis:' in self.destination_arn:
                client = aws_stack.connect_to_service('kinesis')
                stream_name = aws_stack.kinesis_stream_name(
                    self.destination_arn)
                client.put_record(StreamName=stream_name,
                                  Data=json.dumps(payload_gz_encoded),
                                  PartitionKey=log_group_name)
            if ':firehose:' in self.destination_arn:
                client = aws_stack.connect_to_service('firehose')
                firehose_name = aws_stack.firehose_name(self.destination_arn)
                client.put_record(
                    DeliveryStreamName=firehose_name,
                    Record={'Data': json.dumps(payload_gz_encoded)})
コード例 #12
0
 def Mapping_create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
     props = cloudformation_json.get('Properties', {})
     func_name = props.get('FunctionName') or ''
     if ':lambda:' in func_name:
         props['FunctionName'] = aws_stack.lambda_function_name(func_name)
     try:
         return Mapping_create_from_cloudformation_json_orig(resource_name, cloudformation_json, region_name)
     except Exception:
         LOG.info('Unable to add Lambda event mapping for source ARN "%s" in moto backend (ignoring)' %
             props.get('EventSourceArn'))
         # return an empty dummy instance, to avoid downstream None value issues
         return service_models.BaseModel()
コード例 #13
0
def get_function(fn, self, *args, **kwargs):
    result = fn(self, *args, **kwargs)
    if result:
        return result

    client = aws_stack.connect_to_service("lambda")
    lambda_name = aws_stack.lambda_function_name(args[0])
    response = client.get_function(FunctionName=lambda_name)

    spec = response["Configuration"]
    spec["Code"] = {"ZipFile": "ZW1wdHkgc3RyaW5n"}
    region = aws_stack.extract_region_from_arn(spec["FunctionArn"])
    new_function = moto_awslambda_models.LambdaFunction(spec, region)

    return new_function
コード例 #14
0
def retrieve_resource_details(resource_id, resource_status, resources,
                              stack_name):
    resource = resources.get(resource_id)
    resource_id = resource_status.get('PhysicalResourceId') or resource_id
    if not resource:
        resource = {}
    resource_type = get_resource_type(resource)
    resource_props = resource.get('Properties')
    try:
        if resource_type == 'Lambda::Function':
            resource_id = resource_props[
                'FunctionName'] if resource else resource_id
            return aws_stack.connect_to_service('lambda').get_function(
                FunctionName=resource_id)
        elif resource_type == 'Lambda::Version':
            name = resource_props['FunctionName']
            func_name = aws_stack.lambda_function_name(name)
            func_version = name.split(':')[7] if len(
                name.split(':')) > 7 else '$LATEST'
            versions = aws_stack.connect_to_service(
                'lambda').list_versions_by_function(FunctionName=func_name)
            return ([
                v for v in versions['Versions'] if v['Version'] == func_version
            ] or [None])[0]
        elif resource_type == 'Lambda::EventSourceMapping':
            resource_id = resource_props[
                'FunctionName'] if resource else resource_id
            source_arn = resource_props.get('EventSourceArn')
            resource_id = resolve_refs_recursively(stack_name, resource_id,
                                                   resources)
            source_arn = resolve_refs_recursively(stack_name, source_arn,
                                                  resources)
            if not resource_id or not source_arn:
                raise Exception('ResourceNotFound')
            mappings = aws_stack.connect_to_service(
                'lambda').list_event_source_mappings(FunctionName=resource_id,
                                                     EventSourceArn=source_arn)
            mapping = list(
                filter(
                    lambda m: m['EventSourceArn'] == source_arn and m[
                        'FunctionArn'] == aws_stack.lambda_function_arn(
                            resource_id), mappings['EventSourceMappings']))
            if not mapping:
                raise Exception('ResourceNotFound')
            return mapping[0]
        elif resource_type == 'DynamoDB::Table':
            resource_id = resource_props[
                'TableName'] if resource else resource_id
            return aws_stack.connect_to_service('dynamodb').describe_table(
                TableName=resource_id)
        elif resource_type == 'ApiGateway::RestApi':
            apis = aws_stack.connect_to_service(
                'apigateway').get_rest_apis()['items']
            resource_id = resource_props['Name'] if resource else resource_id
            result = list(filter(lambda api: api['name'] == resource_id, apis))
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Resource':
            api_id = resource_props['RestApiId'] if resource else resource_id
            api_id = resolve_refs_recursively(stack_name, api_id, resources)
            parent_id = resolve_refs_recursively(stack_name,
                                                 resource_props['ParentId'],
                                                 resources)
            if not api_id or not parent_id:
                return None
            api_resources = aws_stack.connect_to_service(
                'apigateway').get_resources(restApiId=api_id)['items']
            target_resource = list(
                filter(
                    lambda res: res.get('parentId') == parent_id and res[
                        'pathPart'] == resource_props['PathPart'],
                    api_resources))
            if not target_resource:
                return None
            path = aws_stack.get_apigateway_path_for_resource(
                api_id, target_resource[0]['id'], resources=api_resources)
            result = list(
                filter(lambda res: res['path'] == path, api_resources))
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Deployment':
            api_id = resource_props['RestApiId'] if resource else resource_id
            api_id = resolve_refs_recursively(stack_name, api_id, resources)
            if not api_id:
                return None
            result = aws_stack.connect_to_service(
                'apigateway').get_deployments(restApiId=api_id)['items']
            # TODO possibly filter results by stage name or other criteria
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Method':
            api_id = resolve_refs_recursively(stack_name,
                                              resource_props['RestApiId'],
                                              resources)
            res_id = resolve_refs_recursively(stack_name,
                                              resource_props['ResourceId'],
                                              resources)
            if not api_id or not res_id:
                return None
            res_obj = aws_stack.connect_to_service('apigateway').get_resource(
                restApiId=api_id, resourceId=res_id)
            match = [
                v for (k, v) in res_obj['resourceMethods'].items()
                if resource_props['HttpMethod'] in (v.get('httpMethod'), k)
            ]
            return match or None
        elif resource_type == 'SQS::Queue':
            sqs_client = aws_stack.connect_to_service('sqs')
            queues = sqs_client.list_queues()
            result = list(
                filter(
                    lambda item:
                    # TODO possibly find a better way to compare resource_id with queue URLs
                    item.endswith('/%s' % resource_id),
                    queues.get('QueueUrls', [])))
            if not result:
                return None
            result = sqs_client.get_queue_attributes(
                QueueUrl=result[0], AttributeNames=['All'])['Attributes']
            result['Arn'] = result['QueueArn']
            return result
        elif resource_type == 'SNS::Topic':
            topics = aws_stack.connect_to_service('sns').list_topics()
            result = list(
                filter(lambda item: item['TopicArn'] == resource_id,
                       topics.get('Topics', [])))
            return result[0] if result else None
        elif resource_type == 'S3::Bucket':
            bucket_name = resource_props.get('BucketName') or resource_id
            return aws_stack.connect_to_service('s3').get_bucket_location(
                Bucket=bucket_name)
        elif resource_type == 'Logs::LogGroup':
            # TODO implement
            raise Exception('ResourceNotFound')
        elif resource_type == 'Kinesis::Stream':
            stream_name = resolve_refs_recursively(stack_name,
                                                   resource_props['Name'],
                                                   resources)
            result = aws_stack.connect_to_service('kinesis').describe_stream(
                StreamName=stream_name)
            return result
        elif resource_type == 'StepFunctions::StateMachine':
            sm_name = resource_props.get('StateMachineName') or resource_id
            sm_name = resolve_refs_recursively(stack_name, sm_name, resources)
            sfn_client = aws_stack.connect_to_service('stepfunctions')
            state_machines = sfn_client.list_state_machines()['stateMachines']
            sm_arn = [
                m['stateMachineArn'] for m in state_machines
                if m['name'] == sm_name
            ]
            if not sm_arn:
                return None
            result = sfn_client.describe_state_machine(
                stateMachineArn=sm_arn[0])
            return result
        if is_deployable_resource(resource):
            LOG.warning(
                'Unexpected resource type %s when resolving references of resource %s: %s'
                % (resource_type, resource_id, resource))
    except Exception as e:
        # we expect this to be a "not found" exception
        markers = ['NoSuchBucket', 'ResourceNotFound', '404']
        if not list(filter(lambda marker, e=e: marker in str(e), markers)):
            LOG.warning(
                'Unexpected error retrieving details for resource %s: %s %s - %s %s'
                % (resource_type, e, traceback.format_exc(), resource,
                   resource_status))
    return None
コード例 #15
0
def retrieve_resource_details(resource_id, resource_status, resources, stack_name):
    resource = resources.get(resource_id)
    resource_id = resource_status.get('PhysicalResourceId') or resource_id
    if not resource:
        resource = {}
    resource_type = get_resource_type(resource)
    resource_props = resource.get('Properties')
    try:
        if resource_type == 'Lambda::Function':
            resource_props['FunctionName'] = (resource_props.get('FunctionName') or
                '{}-lambda-{}'.format(stack_name[:45], common.short_uid()))
            resource_id = resource_props['FunctionName'] if resource else resource_id
            return aws_stack.connect_to_service('lambda').get_function(FunctionName=resource_id)
        elif resource_type == 'Lambda::Version':
            name = resource_props.get('FunctionName')
            if not name:
                return None
            func_name = aws_stack.lambda_function_name(name)
            func_version = name.split(':')[7] if len(name.split(':')) > 7 else '$LATEST'
            versions = aws_stack.connect_to_service('lambda').list_versions_by_function(FunctionName=func_name)
            return ([v for v in versions['Versions'] if v['Version'] == func_version] or [None])[0]
        elif resource_type == 'Lambda::EventSourceMapping':
            resource_id = resource_props['FunctionName'] if resource else resource_id
            source_arn = resource_props.get('EventSourceArn')
            resource_id = resolve_refs_recursively(stack_name, resource_id, resources)
            source_arn = resolve_refs_recursively(stack_name, source_arn, resources)
            if not resource_id or not source_arn:
                raise Exception('ResourceNotFound')
            mappings = aws_stack.connect_to_service('lambda').list_event_source_mappings(
                FunctionName=resource_id, EventSourceArn=source_arn)
            mapping = list(filter(lambda m:
                m['EventSourceArn'] == source_arn and m['FunctionArn'] == aws_stack.lambda_function_arn(resource_id),
                mappings['EventSourceMappings']))
            if not mapping:
                raise Exception('ResourceNotFound')
            return mapping[0]
        elif resource_type == 'IAM::Role':
            role_name = resource_props.get('RoleName') or resource_id
            role_name = resolve_refs_recursively(stack_name, role_name, resources)
            return aws_stack.connect_to_service('iam').get_role(RoleName=role_name)['Role']
        elif resource_type == 'DynamoDB::Table':
            table_name = resource_props.get('TableName') or resource_id
            table_name = resolve_refs_recursively(stack_name, table_name, resources)
            return aws_stack.connect_to_service('dynamodb').describe_table(TableName=table_name)
        elif resource_type == 'ApiGateway::RestApi':
            apis = aws_stack.connect_to_service('apigateway').get_rest_apis()['items']
            api_name = resource_props['Name'] if resource else resource_id
            api_name = resolve_refs_recursively(stack_name, api_name, resources)
            result = list(filter(lambda api: api['name'] == api_name, apis))
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Resource':
            api_id = resource_props['RestApiId'] if resource else resource_id
            api_id = resolve_refs_recursively(stack_name, api_id, resources)
            parent_id = resolve_refs_recursively(stack_name, resource_props['ParentId'], resources)
            if not api_id or not parent_id:
                return None
            api_resources = aws_stack.connect_to_service('apigateway').get_resources(restApiId=api_id)['items']
            target_resource = list(filter(lambda res:
                res.get('parentId') == parent_id and res['pathPart'] == resource_props['PathPart'], api_resources))
            if not target_resource:
                return None
            path = aws_stack.get_apigateway_path_for_resource(api_id,
                target_resource[0]['id'], resources=api_resources)
            result = list(filter(lambda res: res['path'] == path, api_resources))
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Deployment':
            api_id = resource_props['RestApiId'] if resource else resource_id
            api_id = resolve_refs_recursively(stack_name, api_id, resources)
            if not api_id:
                return None
            result = aws_stack.connect_to_service('apigateway').get_deployments(restApiId=api_id)['items']
            # TODO possibly filter results by stage name or other criteria
            return result[0] if result else None
        elif resource_type == 'ApiGateway::Method':
            api_id = resolve_refs_recursively(stack_name, resource_props['RestApiId'], resources)
            res_id = resolve_refs_recursively(stack_name, resource_props['ResourceId'], resources)
            if not api_id or not res_id:
                return None
            res_obj = aws_stack.connect_to_service('apigateway').get_resource(restApiId=api_id, resourceId=res_id)
            match = [v for (k, v) in res_obj['resourceMethods'].items()
                     if resource_props['HttpMethod'] in (v.get('httpMethod'), k)]
            int_props = resource_props.get('Integration')
            if int_props:
                match = [m for m in match if
                    m.get('methodIntegration', {}).get('type') == int_props.get('Type') and
                    m.get('methodIntegration', {}).get('httpMethod') == int_props.get('IntegrationHttpMethod')]
            return any(match) or None
        elif resource_type == 'ApiGateway::GatewayResponse':
            api_id = resolve_refs_recursively(stack_name, resource_props['RestApiId'], resources)
            client = aws_stack.connect_to_service('apigateway')
            result = client.get_gateway_response(restApiId=api_id, responseType=resource_props['ResponseType'])
            return result if 'responseType' in result else None
        elif resource_type == 'SQS::Queue':
            sqs_client = aws_stack.connect_to_service('sqs')
            queues = sqs_client.list_queues()
            result = list(filter(lambda item:
                # TODO possibly find a better way to compare resource_id with queue URLs
                item.endswith('/%s' % resource_id), queues.get('QueueUrls', [])))
            if not result:
                return None
            result = sqs_client.get_queue_attributes(QueueUrl=result[0], AttributeNames=['All'])['Attributes']
            result['Arn'] = result['QueueArn']
            return result
        elif resource_type == 'SNS::Topic':
            topics = aws_stack.connect_to_service('sns').list_topics()
            result = list(filter(lambda item: item['TopicArn'] == resource_id, topics.get('Topics', [])))
            return result[0] if result else None
        elif resource_type == 'S3::Bucket':
            bucket_name = resource_props.get('BucketName') or resource_id
            bucket_name = resolve_refs_recursively(stack_name, bucket_name, resources)
            bucket_name = s3_listener.normalize_bucket_name(bucket_name)
            s3_client = aws_stack.connect_to_service('s3')
            response = s3_client.get_bucket_location(Bucket=bucket_name)
            notifs = resource_props.get('NotificationConfiguration')
            if not response or not notifs:
                return response
            configs = s3_client.get_bucket_notification_configuration(Bucket=bucket_name)
            has_notifs = (configs.get('TopicConfigurations') or configs.get('QueueConfigurations') or
                configs.get('LambdaFunctionConfigurations'))
            if notifs and not has_notifs:
                return None
            return response
        elif resource_type == 'S3::BucketPolicy':
            bucket_name = resource_props.get('Bucket') or resource_id
            bucket_name = resolve_refs_recursively(stack_name, bucket_name, resources)
            return aws_stack.connect_to_service('s3').get_bucket_policy(Bucket=bucket_name)
        elif resource_type == 'Logs::LogGroup':
            # TODO implement
            raise Exception('ResourceNotFound')
        elif resource_type == 'Kinesis::Stream':
            stream_name = resolve_refs_recursively(stack_name, resource_props['Name'], resources)
            result = aws_stack.connect_to_service('kinesis').describe_stream(StreamName=stream_name)
            return result
        elif resource_type == 'StepFunctions::StateMachine':
            sm_name = resource_props.get('StateMachineName') or resource_id
            sm_name = resolve_refs_recursively(stack_name, sm_name, resources)
            sfn_client = aws_stack.connect_to_service('stepfunctions')
            state_machines = sfn_client.list_state_machines()['stateMachines']
            sm_arn = [m['stateMachineArn'] for m in state_machines if m['name'] == sm_name]
            if not sm_arn:
                return None
            result = sfn_client.describe_state_machine(stateMachineArn=sm_arn[0])
            return result
        elif resource_type == 'StepFunctions::Activity':
            act_name = resource_props.get('Name') or resource_id
            act_name = resolve_refs_recursively(stack_name, act_name, resources)
            sfn_client = aws_stack.connect_to_service('stepfunctions')
            activities = sfn_client.list_activities()['activities']
            result = [a['activityArn'] for a in activities if a['name'] == act_name]
            if not result:
                return None
            return result[0]
        if is_deployable_resource(resource):
            LOG.warning('Unexpected resource type %s when resolving references of resource %s: %s' %
                        (resource_type, resource_id, resource))
    except Exception as e:
        check_not_found_exception(e, resource_type, resource, resource_status)
    return None
コード例 #16
0
 def test_lambda_function_name(self):
     assert (lambda_function_name(
         "arn:aws:lambda:aws-region:acct-id:function:helloworld:42") ==
             "helloworld")
     assert lambda_function_name("helloworld") == "helloworld"