summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/models.py
blob: 8d6642a257bef71614198cae708beb3e7a02dd95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
""" Django database models for all plugins """

import sys
import logging
import Bcfg2.Options
import Bcfg2.Server.Plugins

LOGGER = logging.getLogger(__name__)

MODELS = []


class _OptionContainer(object):
    """Options for Bcfg2 database models."""

    # we want to provide a different default plugin list --
    # namely, _all_ plugins, so that the database is guaranteed to
    # work, even if /etc/bcfg2.conf isn't set up properly
    options = [Bcfg2.Options.Common.plugins]

    @staticmethod
    def options_parsed_hook():
        # basic invocation to ensure that a default set of models is
        # loaded, and thus that this module will always work.
        load_models()

Bcfg2.Options.get_parser().add_component(_OptionContainer)


def load_models(plugins=None):
    """ load models from plugins specified in the config """
    # this has to be imported after options are parsed, because Django
    # finalizes its settings as soon as it's loaded, which means that
    # if we import this before Bcfg2.DBSettings has been populated,
    # Django gets a null configuration, and subsequent updates to
    # Bcfg2.DBSettings won't help.
    from django.db import models
    global MODELS

    if not plugins:
        plugins = Bcfg2.Options.setup.plugins

    if MODELS:
        # load_models() has been called once, so first unload all of
        # the models; otherwise we might call load_models() with no
        # arguments, end up with _all_ models loaded, and then in a
        # subsequent call only load a subset of models
        for model in MODELS:
            delattr(sys.modules[__name__], model)
        MODELS = []

    for mod in plugins:
        for sym in dir(mod):
            obj = getattr(mod, sym)
            if isinstance(obj, type) and issubclass(obj, models.Model):
                setattr(sys.modules[__name__], sym, obj)
                MODELS.append(sym)

    class InternalDatabaseVersion(models.Model):
        """ Object that tell us to which version the database is """
        version = models.IntegerField()
        updated = models.DateTimeField(auto_now_add=True)

        def __str__(self):
            return "version %d updated %s" % (self.version,
                                              self.updated.isoformat())

        class Meta:  # pylint: disable=C0111,W0232
            app_label = "reports"
            get_latest_by = "version"