Ensure event source mapping exists.

    name
        The name of the state definition.

    EventSourceArn
        The Amazon Resource Name (ARN) of the Amazon Kinesis or the Amazon
        DynamoDB stream that is the event source.

    FunctionName
        The Lambda function to invoke when AWS Lambda detects an event on the
        stream.

        You can specify an unqualified function name (for example, "Thumbnail")
        or you can specify Amazon Resource Name (ARN) of the function (for
        example, "arn:aws:lambda:us-west-2:account-id:function:ThumbNail"). AWS
        Lambda also allows you to specify only the account ID qualifier (for
        example, "account-id:Thumbnail"). Note that the length constraint
        applies only to the ARN. If you specify only the function name, it is
        limited to 64 character in length.

    StartingPosition
        The position in the stream where AWS Lambda should start reading.
        (TRIM_HORIZON | LATEST)

    Enabled
        Indicates whether AWS Lambda should begin polling the event source. By
        default, Enabled is true.

    BatchSize
        The largest number of records that AWS Lambda will retrieve from your
        event source at the time of invoking your function. Your function
        receives an event with all the retrieved records. The default is 100
        records.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string) that
        contains a dict with region, key and keyid.

def event_source_mapping_present(name, EventSourceArn, FunctionName,
                                 StartingPosition, Enabled=True, BatchSize=100,
                                 region=None, key=None, keyid=None,
                                 profile=None):
    '''
    Ensure event source mapping exists.

    name
        The name of the state definition.

    EventSourceArn
        The Amazon Resource Name (ARN) of the Amazon Kinesis or the Amazon
        DynamoDB stream that is the event source.

    FunctionName
        The Lambda function to invoke when AWS Lambda detects an event on the
        stream.

        You can specify an unqualified function name (for example, "Thumbnail")
        or you can specify Amazon Resource Name (ARN) of the function (for
        example, "arn:aws:lambda:us-west-2:account-id:function:ThumbNail"). AWS
        Lambda also allows you to specify only the account ID qualifier (for
        example, "account-id:Thumbnail"). Note that the length constraint
        applies only to the ARN. If you specify only the function name, it is
        limited to 64 character in length.

    StartingPosition
        The position in the stream where AWS Lambda should start reading.
        (TRIM_HORIZON | LATEST)

    Enabled
        Indicates whether AWS Lambda should begin polling the event source. By
        default, Enabled is true.

    BatchSize
        The largest number of records that AWS Lambda will retrieve from your
        event source at the time of invoking your function. Your function
        receives an event with all the retrieved records. The default is 100
        records.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string) that
        contains a dict with region, key and keyid.
    '''
    ret = {'name': None,
           'result': True,
           'comment': '',
           'changes': {}
           }

    r = __salt__['boto_lambda.event_source_mapping_exists'](
        EventSourceArn=EventSourceArn, FunctionName=FunctionName,
        region=region, key=key, keyid=keyid, profile=profile)

    if 'error' in r:
        ret['result'] = False
        ret['comment'] = ('Failed to create event source mapping: '
                          '{0}.'.format(r['error']['message']))
        return ret

    if not r.get('exists'):
        if __opts__['test']:
            ret['comment'] = ('Event source mapping {0} is set '
                              'to be created.'.format(FunctionName))
            ret['result'] = None
            return ret
        r = __salt__['boto_lambda.create_event_source_mapping'](
            EventSourceArn=EventSourceArn, FunctionName=FunctionName,
            StartingPosition=StartingPosition, Enabled=Enabled,
            BatchSize=BatchSize, region=region, key=key, keyid=keyid,
            profile=profile)
        if not r.get('created'):
            ret['result'] = False
            ret['comment'] = ('Failed to create event source mapping: '
                              '{0}.'.format(r['error']['message']))
            return ret
        _describe = __salt__['boto_lambda.describe_event_source_mapping'](
            EventSourceArn=EventSourceArn, FunctionName=FunctionName,
            region=region, key=key, keyid=keyid, profile=profile)
        ret['name'] = _describe['event_source_mapping']['UUID']
        ret['changes']['old'] = {'event_source_mapping': None}
        ret['changes']['new'] = _describe
        ret['comment'] = ('Event source mapping {0} '
                          'created.'.format(ret['name']))
        return ret

    ret['comment'] = os.linesep.join(
        [ret['comment'], 'Event source mapping is present.'])
    ret['changes'] = {}
    _describe = __salt__['boto_lambda.describe_event_source_mapping'](
        EventSourceArn=EventSourceArn, FunctionName=FunctionName,
        region=region, key=key, keyid=keyid,
        profile=profile)['event_source_mapping']

    need_update = False
    options = {'BatchSize': BatchSize}

    for key, val in six.iteritems(options):
        if _describe[key] != val:
            need_update = True
            ret['changes'].setdefault('old', {})[key] = _describe[key]
            ret['changes'].setdefault('new', {})[key] = val
    # verify FunctionName against FunctionArn
    function_arn = _get_function_arn(FunctionName, region=region,
                                     key=key, keyid=keyid, profile=profile)
    if _describe['FunctionArn'] != function_arn:
        need_update = True
        ret['changes'].setdefault('new', {})['FunctionArn'] = function_arn
        ret['changes'].setdefault('old', {})['FunctionArn'] = _describe[
            'FunctionArn']
    # TODO check for 'Enabled', since it doesn't directly map to a specific
    # state
    if need_update:
        ret['comment'] = os.linesep.join(
            [ret['comment'], 'Event source mapping to be modified'])
        if __opts__['test']:
            ret['comment'] = (
                'Event source mapping {0} set to be modified.'.format(
                    _describe['UUID']
                )
            )
            ret['result'] = None
            return ret
        _r = __salt__['boto_lambda.update_event_source_mapping'](
            UUID=_describe['UUID'], FunctionName=FunctionName,
            Enabled=Enabled, BatchSize=BatchSize,
            region=region, key=key, keyid=keyid, profile=profile)
        if not _r.get('updated'):
            ret['result'] = False
            ret['comment'] = ('Failed to update mapping: '
                              '{0}.'.format(_r['error']['message']))
            ret['changes'] = {}
    return ret