Ensure the SQS queue exists.

    name
        Name of the SQS queue.

    attributes
        A dict of key/value SQS attributes.

    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 present(
        name,
        attributes=None,
        region=None,
        key=None,
        keyid=None,
        profile=None,
):
    '''
    Ensure the SQS queue exists.

    name
        Name of the SQS queue.

    attributes
        A dict of key/value SQS attributes.

    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': name,
        'result': True,
        'comment': [],
        'changes': {},
    }

    r = __salt__['boto_sqs.exists'](
        name,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in r:
        ret['result'] = False
        ret['comment'].append(r['error'])
        return ret

    if r['result']:
        ret['comment'].append('SQS queue {0} present.'.format(name))
    else:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'].append(
                'SQS queue {0} is set to be created.'.format(name),
            )
            ret['changes'] = {'old': None, 'new': name}
            return ret

        r = __salt__['boto_sqs.create'](
            name,
            attributes=attributes,
            region=region,
            key=key,
            keyid=keyid,
            profile=profile,
        )
        if 'error' in r:
            ret['result'] = False
            ret['comment'].append(
                'Failed to create SQS queue {0}: {1}'.format(name, r['error']),
            )
            return ret

        ret['comment'].append('SQS queue {0} created.'.format(name))
        ret['changes']['old'] = None
        ret['changes']['new'] = name
        # Return immediately, as the create call also set all attributes
        return ret

    if not attributes:
        return ret

    r = __salt__['boto_sqs.get_attributes'](
        name,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in r:
        ret['result'] = False
        ret['comment'].append(
            'Failed to get queue attributes: {0}'.format(r['error']),
        )
        return ret
    current_attributes = r['result']

    attrs_to_set = {}
    for attr, val in six.iteritems(attributes):
        _val = current_attributes.get(attr, None)
        if attr == 'Policy':
            # Normalize by brute force
            if isinstance(_val, six.string_types):
                _val = salt.utils.json.loads(_val)
            if isinstance(val, six.string_types):
                val = salt.utils.json.loads(val)
            if _val != val:
                log.debug('Policies differ:\n%s\n%s', _val, val)
                attrs_to_set[attr] = salt.utils.json.dumps(val, sort_keys=True)
        elif six.text_type(_val) != six.text_type(val):
            log.debug('Attributes differ:\n%s\n%s', _val, val)
            attrs_to_set[attr] = val
    attr_names = ', '.join(attrs_to_set)

    if not attrs_to_set:
        ret['comment'].append('Queue attributes already set correctly.')
        return ret

    final_attributes = current_attributes.copy()
    final_attributes.update(attrs_to_set)

    def _yaml_safe_dump(attrs):
        '''
        Safely dump YAML using a readable flow style
        '''
        dumper = __utils__['yaml.get_dumper']('IndentedSafeOrderedDumper')
        return __utils__['yaml.dump'](
            attrs,
            default_flow_style=False,
            Dumper=dumper)

    attributes_diff = ''.join(difflib.unified_diff(
        _yaml_safe_dump(current_attributes).splitlines(True),
        _yaml_safe_dump(final_attributes).splitlines(True),
    ))

    if __opts__['test']:
        ret['result'] = None
        ret['comment'].append(
            'Attribute(s) {0} set to be updated:\n{1}'.format(
                attr_names,
                attributes_diff,
            )
        )
        ret['changes'] = {'attributes': {'diff': attributes_diff}}
        return ret

    r = __salt__['boto_sqs.set_attributes'](
        name,
        attrs_to_set,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in r:
        ret['result'] = False
        ret['comment'].append(
            'Failed to set queue attributes: {0}'.format(r['error']),
        )
        return ret

    ret['comment'].append(
        'Updated SQS queue attribute(s) {0}.'.format(attr_names),
    )
    ret['changes']['attributes'] = {'diff': attributes_diff}
    return ret