.. versionadded:: 2017.7.0

    Makes sure a SELinux policy for a given filespec (name), filetype
    and SELinux context type is present.

    name
        filespec of the file or directory. Regex syntax is allowed.

    sel_type
        SELinux context type. There are many.

    filetype
        The SELinux filetype specification. Use one of [a, f, d, c, b,
        s, l, p]. See also `man semanage-fcontext`. Defaults to 'a'
        (all files).

    sel_user
        The SELinux user.

    sel_level
        The SELinux MLS range.

def fcontext_policy_present(name, sel_type, filetype='a', sel_user=None, sel_level=None):
    '''
    .. versionadded:: 2017.7.0

    Makes sure a SELinux policy for a given filespec (name), filetype
    and SELinux context type is present.

    name
        filespec of the file or directory. Regex syntax is allowed.

    sel_type
        SELinux context type. There are many.

    filetype
        The SELinux filetype specification. Use one of [a, f, d, c, b,
        s, l, p]. See also `man semanage-fcontext`. Defaults to 'a'
        (all files).

    sel_user
        The SELinux user.

    sel_level
        The SELinux MLS range.
    '''
    ret = {'name': name, 'result': False, 'changes': {}, 'comment': ''}
    new_state = {}
    old_state = {}
    filetype_str = __salt__['selinux.filetype_id_to_string'](filetype)
    current_state = __salt__['selinux.fcontext_get_policy'](
            name=name,
            filetype=filetype,
            sel_type=sel_type,
            sel_user=sel_user,
            sel_level=sel_level)
    if not current_state:
        new_state = {name: {'filetype': filetype_str, 'sel_type': sel_type}}
        if __opts__['test']:
            ret.update({'result': None})
        else:
            add_ret = __salt__['selinux.fcontext_add_policy'](
                    name=name,
                    filetype=filetype,
                    sel_type=sel_type,
                    sel_user=sel_user,
                    sel_level=sel_level)
            if add_ret['retcode'] != 0:
                ret.update({'comment': 'Error adding new rule: {0}'.format(add_ret)})
            else:
                ret.update({'result': True})
    else:
        if current_state['sel_type'] != sel_type:
            old_state.update({name: {'sel_type': current_state['sel_type']}})
            new_state.update({name: {'sel_type': sel_type}})
        else:
            ret.update({'result': True,
                        'comment': 'SELinux policy for "{0}" already present '.format(name) +
                                   'with specified filetype "{0}" and sel_type "{1}".'.format(
                                            filetype_str,
                                            sel_type)})
            return ret

        # Removal of current rule is not neccesary, since adding a new rule for the same
        # filespec and the same filetype automatically overwrites
        if __opts__['test']:
            ret.update({'result': None})
        else:
            change_ret = __salt__['selinux.fcontext_add_policy'](
                    name=name,
                    filetype=filetype,
                    sel_type=sel_type,
                    sel_user=sel_user,
                    sel_level=sel_level)
            if change_ret['retcode'] != 0:
                ret.update({'comment': 'Error adding new rule: {0}'.format(change_ret)})
            else:
                ret.update({'result': True})
    if ret['result'] and (new_state or old_state):
        ret['changes'].update({'old': old_state, 'new': new_state})
    return ret