Runs an rpm -Va on a system, and returns the results in a dict

    root
        use root as top level directory (default: "/")

    Files with an attribute of config, doc, ghost, license or readme in the
    package header can be ignored using the ``ignore_types`` keyword argument

    CLI Example:

    .. code-block:: bash

        salt '*' lowpkg.verify
        salt '*' lowpkg.verify httpd
        salt '*' lowpkg.verify httpd postfix
        salt '*' lowpkg.verify httpd postfix ignore_types=['config','doc']

def verify(*packages, **kwargs):
    '''
    Runs an rpm -Va on a system, and returns the results in a dict

    root
        use root as top level directory (default: "/")

    Files with an attribute of config, doc, ghost, license or readme in the
    package header can be ignored using the ``ignore_types`` keyword argument

    CLI Example:

    .. code-block:: bash

        salt '*' lowpkg.verify
        salt '*' lowpkg.verify httpd
        salt '*' lowpkg.verify httpd postfix
        salt '*' lowpkg.verify httpd postfix ignore_types=['config','doc']
    '''
    ftypes = {'c': 'config',
              'd': 'doc',
              'g': 'ghost',
              'l': 'license',
              'r': 'readme'}
    ret = {}
    ignore_types = kwargs.get('ignore_types', [])
    if not isinstance(ignore_types, (list, six.string_types)):
        raise SaltInvocationError(
            'ignore_types must be a list or a comma-separated string'
        )
    if isinstance(ignore_types, six.string_types):
        try:
            ignore_types = [x.strip() for x in ignore_types.split(',')]
        except AttributeError:
            ignore_types = [x.strip() for x in six.text_type(ignore_types).split(',')]

    verify_options = kwargs.get('verify_options', [])
    if not isinstance(verify_options, (list, six.string_types)):
        raise SaltInvocationError(
            'verify_options must be a list or a comma-separated string'
        )
    if isinstance(verify_options, six.string_types):
        try:
            verify_options = [x.strip() for x in verify_options.split(',')]
        except AttributeError:
            verify_options = [x.strip() for x in six.text_type(verify_options).split(',')]

    cmd = ['rpm']
    if kwargs.get('root'):
        cmd.extend(['--root', kwargs['root']])
    cmd.extend(['--' + x for x in verify_options])
    if packages:
        cmd.append('-V')
        # Can't concatenate a tuple, must do a list.extend()
        cmd.extend(packages)
    else:
        cmd.append('-Va')
    out = __salt__['cmd.run_all'](cmd,
                                  output_loglevel='trace',
                                  ignore_retcode=True,
                                  python_shell=False)

    if not out['stdout'].strip() and out['retcode'] != 0:
        # If there is no stdout and the retcode is 0, then verification
        # succeeded, but if the retcode is nonzero, then the command failed.
        msg = 'Failed to verify package(s)'
        if out['stderr']:
            msg += ': {0}'.format(out['stderr'])
        raise CommandExecutionError(msg)

    for line in salt.utils.itertools.split(out['stdout'], '\n'):
        fdict = {'mismatch': []}
        if 'missing' in line:
            line = ' ' + line
            fdict['missing'] = True
            del fdict['mismatch']
        fname = line[13:]
        if line[11:12] in ftypes:
            fdict['type'] = ftypes[line[11:12]]
        if 'type' not in fdict or fdict['type'] not in ignore_types:
            if line[0:1] == 'S':
                fdict['mismatch'].append('size')
            if line[1:2] == 'M':
                fdict['mismatch'].append('mode')
            if line[2:3] == '5':
                fdict['mismatch'].append('md5sum')
            if line[3:4] == 'D':
                fdict['mismatch'].append('device major/minor number')
            if line[4:5] == 'L':
                fdict['mismatch'].append('readlink path')
            if line[5:6] == 'U':
                fdict['mismatch'].append('user')
            if line[6:7] == 'G':
                fdict['mismatch'].append('group')
            if line[7:8] == 'T':
                fdict['mismatch'].append('mtime')
            if line[8:9] == 'P':
                fdict['mismatch'].append('capabilities')
            ret[fname] = fdict
    return ret