Source code for insights.parsers.hosts

"""
Hosts - file ``/etc/hosts``
===========================

This parser parses the ``/etc/hosts`` file, strips the comments, ignores the
blank lines, and collects the host names by IP address.  IPv4 and IPv6
addresses are supported.

Sample hosts file::

    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    # The same IP address can appear more than once, with different names
    127.0.0.1 fte.example.com

    10.0.0.1 nonlocal.example.com nonlocal2.fte.example.com
    10.0.0.2 other.host.example.com # Comments at end of line are ignored

Examples:

    >>> len(hosts.all_names)
    10
    >>> 'localhost6'in  hosts.all_names
    True
    >>> hosts.data['127.0.0.1']
    ['localhost', 'localhost.localdomain', 'localhost4', 'localhost4.localdomain4', 'fte.example.com']
    >>> sorted(hosts.get_nonlocal().keys())
    ['10.0.0.1', '10.0.0.2']
    >>> hosts.lines[-1]['ip']
    '10.0.0.2'
    >>> hosts.lines[2]['names']
    ['fte.example.com']

"""
from insights.core import Parser
from insights.core.exceptions import SkipComponent
from insights.core.plugins import parser
from insights.specs import Specs


[docs] @parser(Specs.hosts) class Hosts(Parser): """ Read the ``/etc/hosts`` file and parse it into a dictionary of host name lists, keyed on IP address. """
[docs] def parse_content(self, content): self._ips = set() self._names = set() self._lines = list() self._data = dict() for line in content: line = line.strip() if "#" in line: line = line.split("#")[0] words = line.split(None) if len(words) > 1: ip, names = words[0], words[1:] line_data = {'ip': ip, 'names': names, 'raw_line': line} self._ips.add(ip) self._names.update(names) self._lines.append(line_data) if ip not in self._data: self._data[ip] = [] self._data[ip].extend(names) if not self._data: raise SkipComponent("No useful data")
@property def data(self): """ (dict): The parsed result as a dict with IP address as the key. """ return self._data @property def lines(self): """ (list): List of the parsed lines in the original order, in the following format:: { 'ip': '127.0.0.1', 'names': ['localhost', 'localhost.localdomain', 'localhost4', 'localhost4.localdomain4'] 'raw_line:' '127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4' } """ return self._lines @property def all_ips(self): """ (set): The set of ip addresses known. """ return self._ips @property def all_names(self): """ (set): The set of host names known, regardless of their IP address. """ return self._names
[docs] def get_nonlocal(self): """ A dictionary of host name lists, keyed on IP address, that are not the 'localhost' addresses '127.0.0.1' or '::1'. """ return dict((ip, host_list) for ip, host_list in self._data.items() if ip not in ("127.0.0.1", "::1"))
[docs] def ip_of(self, hostname): """ Return the (first) IP address given for this host name. None is returned if no IP address is found. """ for ip, host_list in self._data.items(): if hostname in host_list: return ip return None