3aca9043b196784f5f0f56cbd9f68c5588684d9e
   1"""
   2Commonly used general functions.
   3
   4This module provides the following methods:
   5    - `hostname`:       get the current machine's hostname
   6    - `getlocaldomain`: get the current machine's domain name
   7    - `resolve`:        attempt to convert a local/public IP to hostname
   8    - `readlog`:        read contents of a log file from disk
   9"""
  10
  11from datetime import datetime, timedelta
  12import inspect
  13import logging
  14import os
  15from pkg_resources import Requirement, resource_filename
  16import re
  17import socket
  18from systemd import journal
  19
  20from logparse import config
  21
  22
  23logger = logging.getLogger(__name__)
  24
  25
  26def hostname(path): # get the hostname of current server
  27    """
  28    Get the hostname of the current machine using the file supplied in the
  29    `hostname-path` config option.
  30    """
  31
  32    hnfile = open(path, 'r')
  33    hn = re.search('^(\w*)\n*', hnfile.read()).group(1)
  34    return hn
  35
  36
  37def getlocaldomain(): # get the parent fqdn of current server
  38    """
  39    Get parent domain name (possibly FQDN) of the current machine. Note: if
  40    `socket.fetfqdn()` returns localhost, make sure the first entry in the
  41    hostname file includes the FQDN.
  42    """
  43
  44    domain = socket.getfqdn().split('.', 1)
  45    if len(domain) != 2:
  46        logger.warning("Could not get domain of this server, only hostname. Please consider updating the hostname file at {0}".format(config.prefs.get("logparse", "hostname-path")))
  47        return 'localdomain'
  48    else:
  49        return domain[-1]
  50
  51
  52def resolve(ip, fqdn=None):        # try to resolve an ip to hostname
  53    """
  54    Attempt to resolve an IP into a hostname or FQDN.
  55    Possible values for fqdn:
  56        - fqdn            show full hostname and domain
  57        - fqdn-implicit   show hostname and domain unless local
  58        - host-only       only show hostname
  59        - ip              never resolve anything
  60    Note resolve-domains settings defined in individual sections of the config
  61    take priority over the global config (this is enforced in parser modules)
  62    """
  63    
  64    if not fqdn:
  65        fqdn = config.prefs.get("logparse", "resolve-domains")
  66
  67    if fqdn == 'ip':
  68        return(ip)
  69
  70    try:
  71        socket.inet_aton(ip)  # succeeds if text contains ip
  72        hn = socket.gethostbyaddr(ip)[0] # resolve ip to hostname
  73        if fqdn == 'fqdn-implicit' and hn.split('.', 1)[1] == getlocaldomain():
  74            return(hn.split('.')[0])
  75        elif fqdn == 'fqdn' or fqdn == 'fqdn-implicit':
  76            return(hn)
  77        elif fqdn == 'host-only':
  78            return(hn.split('.')[0])
  79        else:
  80            logger.warning("Invalid value for FQDN config")
  81            return(hn)
  82    except socket.herror:
  83        # cannot resolve ip
  84        logger.debug(ip + " cannot be found, might not exist anymore")
  85        return(ip)
  86    except (OSError, socket.error): # socket.error for Python 2 compatibility
  87        # already a hostname
  88        logger.debug(ip + " is already a hostname")
  89        return(ip)
  90    except Exception as err:
  91        logger.warning("failed to resolve hostname for " + ip + ": " + str(err))
  92        return(ip)  # return ip if no hostname exists
  93
  94
  95def readlog(path = None, mode = 'r'):
  96    """
  97    Read a logfile from disk and return string
  98    """
  99    
 100    if (path == None):
 101        logger.error("No path provided")
 102        return 1
 103    else:
 104        if (os.path.isfile(path) is False):
 105            logger.error("Log at {0} was requested but does not exist".format(path))
 106            return ''
 107        else:
 108            try:
 109                return open(path, mode).read()
 110            except IOError or OSError as e:
 111                logger.warning("Error reading log at {0}: {1}".format(path, e.strerror))
 112                return 1