Source code for maasserver.models.config

# Copyright 2012-2014 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Configuration items."""

from __future__ import (
    absolute_import,
    print_function,
    unicode_literals,
    )

str = None

__metaclass__ = type
__all__ = [
    'Config',
    ]


from collections import defaultdict
import copy
from socket import gethostname

from django.db.models import (
    CharField,
    Manager,
    Model,
    )
from django.db.models.signals import post_save
from maasserver import DefaultMeta
from maasserver.enum import DISTRO_SERIES
from maasserver.fields import JSONObjectField


def get_default_config():
    return {
        ## settings default values.
        # Commissioning section configuration.
        'check_compatibility': False,
        # Ubuntu section configuration.
        'main_archive': 'http://archive.ubuntu.com/ubuntu',
        'ports_archive': 'http://ports.ubuntu.com/ubuntu-ports',
        'commissioning_distro_series': DISTRO_SERIES.trusty,
        # Network section configuration.
        'maas_name': gethostname(),
        'enlistment_domain': b'local',
        'default_distro_series': DISTRO_SERIES.trusty,
        'http_proxy': None,
        'upstream_dns': None,
        'ntp_server': '91.189.94.4',  # ntp.ubuntu.com
        # RPC configuration.
        'rpc_region_certificate': None,
        # Third Party
        'enable_third_party_drivers': True,
        ## /settings
        }


# Default values for config options.
DEFAULT_CONFIG = get_default_config()


class ConfigManager(Manager):
    """Manager for Config model class.

    Don't import or instantiate this directly; access as `Config.objects.
    """

    def __init__(self):
        super(ConfigManager, self).__init__()
        self._config_changed_connections = defaultdict(set)

    def get_config(self, name, default=None):
        """Return the config value corresponding to the given config name.
        Return None or the provided default if the config value does not
        exist.

        :param name: The name of the config item.
        :type name: unicode
        :param name: The optional default value to return if no such config
            item exists.
        :type name: object
        :return: A config value.
        :raises: Config.MultipleObjectsReturned
        """
        try:
            return self.get(name=name).value
        except Config.DoesNotExist:
            return copy.deepcopy(DEFAULT_CONFIG.get(name, default))

    def get_config_list(self, name):
        """Return the config value list corresponding to the given config
        name.

        :param name: The name of the config items.
        :type name: unicode
        :return: A list of the config values.
        :rtype: list
        """
        return [config.value for config in self.filter(name=name)]

    def set_config(self, name, value):
        """Set or overwrite a config value.

        :param name: The name of the config item to set.
        :type name: unicode
        :param value: The value of the config item to set.
        :type value: Any jsonizable object
        """
        config, freshly_created = self.get_or_create(
            name=name, defaults=dict(value=value))
        if not freshly_created:
            config.value = value
            config.save()

    def config_changed_connect(self, config_name, method):
        """Connect a method to Django's 'update' signal for given config name.

        :param config_name: The name of the config item to track.
        :type config_name: unicode
        :param method: The method to be called.
        :type method: callable

        The provided callable should follow Django's convention.  E.g::

          >>> def callable(sender, instance, created, **kwargs):
          ...     pass

          >>> Config.objects.config_changed_connect('config_name', callable)

        """
        self._config_changed_connections[config_name].add(method)

    def _config_changed(self, sender, instance, created, **kwargs):
        for connection in self._config_changed_connections[instance.name]:
            connection(sender, instance, created, **kwargs)


[docs]class Config(Model): """Configuration settings item. :ivar name: The name of the configuration option. :type name: unicode :ivar value: The configuration value. :type value: Any pickleable python object. """ class Meta(DefaultMeta): """Needed for South to recognize this model.""" name = CharField(max_length=255, unique=False) value = JSONObjectField(null=True) objects = ConfigManager() def __unicode__(self): return "%s: %s" % (self.name, self.value) # Connect config manager's _config_changed to Config's post-save signal.
post_save.connect(Config.objects._config_changed, sender=Config)
MAAS logo

MAAS

Metal As A Service.



Related Topics