Skip to content
config.py 5.86 KiB
Newer Older
# This file is part of CloudControl.
#
# CloudControl is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CloudControl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with CloudControl.  If not, see <http://www.gnu.org/licenses/>.


import logging
import logging.config
from StringIO import StringIO
Anael Beutot's avatar
Anael Beutot committed
from itertools import ifilterfalse
from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError

from cloudcontrol.common.client.exc import ConfigError
logger = logging.getLogger(__name__)
Anael Beutot's avatar
Anael Beutot committed
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):
Anael Beutot's avatar
Anael Beutot committed
        config = _ConfigProxy(SafeConfigParser())
        config.read(file_path)
        # ccserver settings
Anael Beutot's avatar
Anael Beutot committed
        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')
Anael Beutot's avatar
Anael Beutot committed
        # node settings
        try:
            self.logging_level = config.getint('node', 'verbosity', 0)
        except ConfigError:
            try:
                self.logging_level = dict(
                    debug=3,
                    info=2,
                    warning=1,
                    error=0,
                )[config.get('node', 'verbosity')]
            except KeyError:
                _ConfigProxy.config_error(
                    'Configuration attribute "verbosity"'
                    ' is invalid (section "node")')
Anael Beutot's avatar
Anael Beutot committed
        self.debug = config.getboolean('node', 'debug', False)
        self.logging_output = 'console' if self.debug else 'syslog'
Anael Beutot's avatar
Anael Beutot committed
        # path settings
Anael Beutot's avatar
Anael Beutot committed
        self.jobs_store_path = config.get('node', 'jobs_store_path',
Anael Beutot's avatar
Anael Beutot committed
                                          '/var/lib/cc-node/jobs')
        # plugins persistance
Anael Beutot's avatar
Anael Beutot committed
        self.plugins_store_path = config.get('node', 'plugins_store_path',
                                             '/var/lib/cc-node/plugins')
Anael Beutot's avatar
Anael Beutot committed

        # Path to define script
        default_define_script = 'hkvm-define'
        self.define_script = config.get('node', 'define_script', default_define_script)

Anael Beutot's avatar
Anael Beutot committed
        # 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 = set(('shutdown', 'execute'))
Anael Beutot's avatar
Anael Beutot committed
        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 = {
        0: 'ERROR', 1: 'WARNING',
        2: 'INFO', 3: 'DEBUG',
    }[level]
    output = dict(
        console="""
[handler_output]
class=StreamHandler
formatter=simpleFormatter
args=(sys.stderr,)

[formatter_simpleFormatter]
format=cc-node - %(asctime)s - %(name)s - %(levelname)s - %(message)s
""",
        syslog="""
[handler_output]
class=handlers.SysLogHandler
formatter=simpleFormatter
args=('/dev/log', handlers.SysLogHandler.LOG_DAEMON)

[formatter_simpleFormatter]
class=cloudcontrol.common.helpers.formatter.EncodingFormatter
format=cc-node - %(name)s - %(levelname)s - %(message)s

    # create config parser for logging configuration
    logging.config.fileConfig(StringIO("""
[loggers]
Anael Beutot's avatar
Anael Beutot committed
keys=root,ccnode,cccommon,sjrpc

[formatters]
keys=simpleFormatter

[logger_root]
level=ERROR

[logger_ccnode]
Anael Beutot's avatar
Anael Beutot committed
level=%(level)s
handlers=
qualname=cloudcontrol.node

Anael Beutot's avatar
Anael Beutot committed
[logger_cccommon]
level=%(level)s
handlers=
qualname=cloudcontrol.common

[logger_sjrpc]
level=ERROR
handlers=
qualname=sjrpc

%(output)s
    """ % dict(level=level, output=output)))