Package Products :: Package ZenUtils :: Module GlobalConfig |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenUtils.GlobalConfig

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2010, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  import logging
     12  log = logging.getLogger('zen.GlobalConfig')
     13  import sys
     14  from optparse import OptionValueError, BadOptionError
     15  import re
     16  import os.path
     17
     18  from Products.ZenUtils.Utils import zenPath, getAllParserOptionsGen
     19  from Products.ZenUtils.config import Config, ConfigLoader
     20
     21
     22  CONFIG_FILE = zenPath('etc', 'global.conf')
     23
     24
     25  _KEYVALUE = re.compile("^[\s ]*(?P<key>[a-z_]+[a-z0-9_-]*)[\s]+(?P<value>[^\s#]+)", re.IGNORECASE).search
     26
     27 -def globalConfToDict():
     28      settings = {}
     29      globalConfFile = zenPath('etc','global.conf')
     30      if os.path.exists(globalConfFile):
     31          with open(globalConfFile, 'r') as f:
     32              for line in f.xreadlines():
     33                  match = _KEYVALUE(line)
     34                  if match:
     35                      value = match.group('value')
     36                      if value.isdigit():
     37                          value = int(value)
     38                      settings[match.group('key')] = value
     39      return settings
     40
     41 -class GlobalConfig(Config):
     42      """
     43      A method for retrieving the global configuration options
     44      outside of a daemon. This is used to configure the
     45      AMQP connection in Zope and zenhub
     46
     47      @todo Add validation for expected keys and values
     48      """
     49      pass
     50
     51  _GLOBAL_CONFIG = ConfigLoader(CONFIG_FILE, GlobalConfig)
     52 -def getGlobalConfiguration():
     53      return _GLOBAL_CONFIG()
     54
     55
     56 -def flagToConfig(flag):
     57      return flag.trim().lstrip("-").replace("-", "_")
     58
     59 -def configToFlag(option):
     60      return "--" + option.strip().replace("_", "-")
     61
     62 -def _convertConfigLinesToArguments(parser, lines):
     63      """
     64      Converts configuration file lines of the format:
     65
     66         myoption 1
     67         mybooloption False
     68
     69      to the equivalent command-line arguments for the specified OptionParser.
     70      For example, the configuration file above would return the argument
     71      list ['--myoption', '1', '--mybooloption'] if mybooloption has action
     72      store_false, and ['--myoption', '1'] if mybooloption has action store_true.
     73
     74      @parameter parser: OptionParser object containing configuration options.
     75      @type parser: OptionParser
     76      @parameter lines: List of dictionary object parsed from a configuration file.
     77                        Each option is expected to have 'type', 'key', 'value' entries.
     78      @type lines: list of dictionaries.
     79      @return: List of command-line arguments corresponding to the configuration file.
     80      @rtype: list of strings
     81      """
     82      # valid key
     83      #     an option's string without the leading "--"
     84      #     can differ from an option's destination
     85      validOpts = set((opt.get_opt_string() for opt in getAllParserOptionsGen(parser)))
     86
     87      args = []
     88      for line in lines:
     89          if line.get('type', None) != 'option':
     90              continue
     91          optstring = configToFlag(line['key'])
     92          if optstring in validOpts:
     93              option = parser.get_option(optstring)
     94              boolean_value = line.get('value', '').lower() in ('true','yes','1')
     95              if option.action == 'store_true':
     96                  if boolean_value:
     97                      args.append(optstring)
     98              elif option.action == 'store_false':
     99                  if not boolean_value:
    100                      args.append(optstring)
    101              else:
    102                  args.extend([optstring, line['value'],])
    103          else:
    104              log.debug("Unknown option: %s", optstring)
    105
    106      return args
    107
    108 -class _GlobalConfParserAdapter(object):
    109 -    def __init__(self, parser):
    110          self.parser = parser
    111
    112 -    def apply(self):
    113          self.parser.defaults = self._getGlobalConfigFileDefaults()
    114          return self.parser
    115
    116 -    def _getGlobalConfigFileDefaults(self):
    117          # TODO: This should be refactored - duplicated code with CmdBase.
    118          """
    119          Parse a config file which has key-value pairs delimited by white space,
    120          and update the parser's option defaults with these values.
    121          """
    122          options = self.parser.get_default_values()
    123          lines = self._loadConfigFile(CONFIG_FILE)
    124          if lines:
    125              args = _convertConfigLinesToArguments(self.parser, lines)
    126              try:
    127                  self.parser._process_args([], args, options)
    128              except (BadOptionError, OptionValueError) as err:
    129                  # Ignore it, we only care about our own options as defined in the parser
    130                  pass
    131          return options.__dict__
    132
    133 -    def _loadConfigFile(self, filename):
    134          # TODO: This should be refactored - duplicated code with CmdBase.
    135          """
    136          Parse a config file which has key-value pairs delimited by white space.
    137
    138          @parameter filename: path to the configuration file
    139          @type filename: string
    140          """
    141          lines = []
    142          try:
    143              with open(filename) as file:
    144                  for line in file:
    145                      if line.lstrip().startswith('#') or line.strip() == '':
    146                          lines.append(dict(type='comment', line=line))
    147                      else:
    148                          try:
    149                              key, value = line.strip().split(None, 1)
    150                          except ValueError:
    151                              lines.append(dict(type='option', line=line, key=line.strip(), value=None, option=None))
    152                          else:
    153                              option = self.parser.get_option('--%s' % key)
    154                              lines.append(dict(type='option', line=line, key=key, value=value, option=option))
    155          except IOError as e:
    156              errorMessage = 'WARN: unable to read config file {filename} \
    157                  -- skipping. ({exceptionName}: {exception})'.format(
    158                  filename=filename,
    159                  exceptionName=e.__class__.__name__,
    160                  exception=e
    161              )
    162              print >>sys.stderr, errorMessage
    163              return []
    164
    165          return lines
    166
    167
    168 -def applyGlobalConfToParser(parser):
    169      return _GlobalConfParserAdapter(parser).apply()
    170