List all available or installed SUSE products.

    all
        List all products available or only installed. Default is False.

    refresh
        force a refresh if set to True.
        If set to False (default) it depends on zypper if a refresh is
        executed.

    root
        operate on a different root directory.

    Includes handling for OEM products, which read the OEM productline file
    and overwrite the release value.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_products
        salt '*' pkg.list_products all=True

def list_products(all=False, refresh=False, root=None):
    '''
    List all available or installed SUSE products.

    all
        List all products available or only installed. Default is False.

    refresh
        force a refresh if set to True.
        If set to False (default) it depends on zypper if a refresh is
        executed.

    root
        operate on a different root directory.

    Includes handling for OEM products, which read the OEM productline file
    and overwrite the release value.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_products
        salt '*' pkg.list_products all=True
    '''
    if refresh:
        refresh_db(root)

    ret = list()
    OEM_PATH = '/var/lib/suseRegister/OEM'
    if root:
        OEM_PATH = os.path.join(root, os.path.relpath(OEM_PATH, os.path.sep))
    cmd = list()
    if not all:
        cmd.append('--disable-repos')
    cmd.append('products')
    if not all:
        cmd.append('-i')

    product_list = __zypper__(root=root).nolock.xml.call(*cmd).getElementsByTagName('product-list')
    if not product_list:
        return ret  # No products found

    for prd in product_list[0].getElementsByTagName('product'):
        p_nfo = dict()
        for k_p_nfo, v_p_nfo in prd.attributes.items():
            if k_p_nfo in ['isbase', 'installed']:
                p_nfo[k_p_nfo] = bool(v_p_nfo in ['true', '1'])
            elif v_p_nfo:
                p_nfo[k_p_nfo] = v_p_nfo

        eol = prd.getElementsByTagName('endoflife')
        if eol:
            p_nfo['eol'] = eol[0].getAttribute('text')
            p_nfo['eol_t'] = int(eol[0].getAttribute('time_t') or 0)
        p_nfo['description'] = " ".join(
            [line.strip() for line in _get_first_aggregate_text(
                prd.getElementsByTagName('description')
            ).split(os.linesep)]
        )
        if 'productline' in p_nfo and p_nfo['productline']:
            oem_file = os.path.join(OEM_PATH, p_nfo['productline'])
            if os.path.isfile(oem_file):
                with salt.utils.files.fopen(oem_file, 'r') as rfile:
                    oem_release = salt.utils.stringutils.to_unicode(rfile.readline()).strip()
                    if oem_release:
                        p_nfo['release'] = oem_release
        ret.append(p_nfo)

    return ret