Commit 5ae80dd5 authored by Anael Beutot's avatar Anael Beutot
Browse files

Refactor config handling

Added options for deactivating handlers in config file.
Added deprecated option remote_execution.
parent 7b0ff548
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ from optparse import OptionParser
from os.path import isfile, abspath

from daemon import DaemonContext
from cloudcontrol.common.client.exc import ConfigError

from cloudcontrol.node import __version__
from cloudcontrol.node.node import NodeLoop
@@ -51,7 +52,10 @@ options.config = abspath(options.config)
if not isfile(options.config):
    sys.exit(u'Please supply a valid path to configuration file...')
configure_logging(1, 'console')
try:
    config = NodeConfigParser(options.config)
except ConfigError as exc:
    sys.exit(exc.message)


# take care of pid file if daemon
+90 −34
Original line number Diff line number Diff line
@@ -16,59 +16,115 @@

import logging
import logging.config
from ConfigParser import SafeConfigParser
from StringIO import StringIO
from itertools import ifilterfalse
from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError

from cloudcontrol.common.client.exc import ConfigError


logger = logging.getLogger(__name__)


class _ConfigProxy(object):
    """Simple ConfigParser proxy that provide default values for get* methods.

    """
    def __init__(self, config_parser):
        self.config = config_parser

    @staticmethod
    def config_error(msg):
        logger.error(msg)
        raise ConfigError(msg)

    def __getattr__(self, name):
        if name.startswith('get'):
            def getter(section, option, *default):
                assert not default or len(default) == 1
                try:
                    return getattr(self.config, name)(section, option)
                except NoSectionError:
                    self.config_error('Section "%s" is not present in config'
                                      ' file' % section)
                except NoOptionError:
                    if default:
                        return default[0]

                    self.config_error(
                        'Attribute "%s" not specified in config'
                        ' file (section "%s")' % (option, section))
                except ValueError:
                    self.config_error(
                        'Configuration attribute "%s" value is invalid'
                        ' (section "%s")' % (option, section))

            return getter

        # else
        return getattr(self.config, name)


class NodeConfigParser(object):
    """ConfigParser for ccnode config file."""
    def __init__(self, file_path):
        config = SafeConfigParser()
        config = _ConfigProxy(SafeConfigParser())
        config.read(file_path)

        config = dict(config.items('node'))

        # ccserver settings
        self.server_host = config.get('node', 'address')
        self.server_port = config.getint('node', 'port', 1984)
        self.server_user = config.get('node', 'login')
        self.server_passwd = config.get('node', 'password')

        # node settings
        try:
            self.server_host = config['address']
        except KeyError:
            logger.error('cc-server address not specified in config file')
            raise
        self.server_port = int(config.get('port', 1984))
            self.logging_level = config.getint('node', 'verbosity', 0)
        except ConfigError:
            try:
            self.server_user = config['login']
                self.logging_level = dict(
                    debug=3,
                    info=2,
                    warning=1,
                    error=0,
                )[config.get('node', 'verbosity')]
            except KeyError:
            logger.error('cc-server login not specified in config file')
            raise
        try:
            self.server_passwd = config['password']
        except KeyError:
            logger.error('cc-server password not specified in config file')
            raise

        self.logging_level = int(config.get('verbosity', 0))
                _ConfigProxy.config_error(
                    'Configuration attribute "verbosity"'
                    ' is invalid (section "node")')

        self.debug = config.get('debug', 'no')
        if self.debug in ('yes', '1', 'on', 'true'):
            self.debug = True
        else:
            if self.debug not in ('no', '0', 'off', 'false'):
                logger.error('Invalid value for debug in config file')
            self.debug = False

        self.logging_level = int(config.get('verbosity', 0))
        self.logging_output = 'console' if self.debug == True else 'syslog'
        self.debug = config.getboolean('node', 'debug', False)
        self.logging_output = 'console' if self.debug else 'syslog'

        # path settings
        self.jobs_store_path = config.get('jobs_store_path',
        self.jobs_store_path = config.get('node', 'jobs_store_path',
                                          '/var/lib/cc-node/jobs')
        # plugins persistance
        self.plugins_store_path = config.get('plugins_store_path',
        self.plugins_store_path = config.get('node', 'plugins_store_path',
                                             '/var/lib/cc-node/plugins')

        # RPC handler ACLs
        acl_section_name = 'node_handler'
        if config.has_section(acl_section_name):
            self.forbidden_handlers = set(ifilterfalse(
                lambda o: config.getboolean(acl_section_name, o, True),
                config.options(acl_section_name),
            ))
        else:
            self.forbidden_handlers = set()
        # backward compatibility
        command_execution_handlers = {'shutdown', 'execute'}
        if config.getboolean('node', 'command_execution', None) == False:
            self.forbidden_handlers |= command_execution_handlers
        else:
            self.forbidden_handlers -= command_execution_handlers

        # deprecated options
        for o in ('detect_hypervisor', 'force_xen'):
            if config.get('node', o, None) is not None:
                logger.warning('%s config option is not supported anymore', o)


def configure_logging(level, output):
    level = {