Completed
Push — develop ( f3cc78...070420 )
by Plexxi
05:07 queued 02:33
created

ConfigsRegistrar.save_model()   A

Complexity

Conditions 3

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
dl 0
loc 19
rs 9.4285
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import os
17
18
from oslo_config import cfg
19
20
from st2common import log as logging
21
from st2common.content import utils as content_utils
22
from st2common.constants.meta import ALLOWED_EXTS
23
from st2common.bootstrap.base import ResourceRegistrar
24
from st2common.models.api.pack import ConfigAPI
25
from st2common.persistence.pack import Config
26
from st2common.exceptions.db import StackStormDBObjectNotFoundError
27
28
__all__ = [
29
    'ConfigsRegistrar'
30
]
31
32
33
LOG = logging.getLogger(__name__)
34
35
36
class ConfigsRegistrar(ResourceRegistrar):
37
    """
38
    Class for loading and registering pack configs located in
39
    /opt/stackstorm/configs/<pack name>.yaml
40
    """
41
42
    ALLOWED_EXTENSIONS = ALLOWED_EXTS
43
44
    def __init__(self, use_pack_cache=True, fail_on_failure=False, validate_configs=True):
45
        super(ConfigsRegistrar, self).__init__(use_pack_cache=use_pack_cache,
46
                                               fail_on_failure=fail_on_failure)
47
48
        self._validate_configs = validate_configs
49
50
    def register_from_packs(self, base_dirs):
51
        """
52
        Register configs for all the available packs.
53
        """
54
        # Register packs first
55
        self.register_packs(base_dirs=base_dirs)
56
57
        registered_count = 0
58
        packs = self._pack_loader.get_packs(base_dirs=base_dirs)
59
        pack_names = packs.keys()
60
61
        for pack_name in pack_names:
62
            config_path = self._get_config_path_for_pack(pack_name=pack_name)
63
64
            if not os.path.isfile(config_path):
65
                # Config for that pack doesn't exist
66
                LOG.debug('No config found for pack "%s" (file "%s" is not present).', pack_name,
67
                          config_path)
68
                continue
69
70
            try:
71
                self._register_config_for_pack(pack=pack_name, config_path=config_path)
72
            except Exception as e:
73
                if self._fail_on_failure:
74
                    raise e
75
76
                LOG.exception('Failed to register config for pack "%s": %s', pack_name, str(e))
77
            else:
78
                registered_count += 1
79
80
        return registered_count
81
82
    def register_from_pack(self, pack_dir):
83
        """
84
        Register config for a provided pack.
85
        """
86
        pack_dir = pack_dir[:-1] if pack_dir.endswith('/') else pack_dir
87
        _, pack_name = os.path.split(pack_dir)
88
89
        # Register pack first
90
        self.register_pack(pack_name=pack_name, pack_dir=pack_dir)
91
92
        config_path = self._get_config_path_for_pack(pack_name=pack_name)
93
        if not os.path.isfile(config_path):
94
            return 0
95
96
        self._register_config_for_pack(pack=pack_name, config_path=config_path)
97
        return 1
98
99
    def _get_config_path_for_pack(self, pack_name):
100
        configs_path = os.path.join(cfg.CONF.system.base_path, 'configs/')
101
        config_path = os.path.join(configs_path, '%s.yaml' % (pack_name))
102
103
        return config_path
104
105
    def _register_config_for_pack(self, pack, config_path):
106
        content = {}
107
        values = self._meta_loader.load(config_path)
108
109
        content['pack'] = pack
110
        content['values'] = values
111
112
        config_api = ConfigAPI(**content)
113
        config_api.validate(validate_against_schema=self._validate_configs)
114
        config_db = self.save_model(config_api)
115
116
        return config_db
117
118
    @staticmethod
119
    def save_model(config_api):
120
        pack = config_api.pack
121
        config_db = ConfigAPI.to_model(config_api)
122
123
        try:
124
            config_db.id = Config.get_by_pack(pack).id
125
        except StackStormDBObjectNotFoundError:
126
            LOG.debug('Config for pack "%s" not found. Creating new entry.', pack)
127
128
        try:
129
            config_db = Config.add_or_update(config_db)
130
            extra = {'config_db': config_db}
131
            LOG.audit('Config for pack "%s" is updated.', config_db.pack, extra=extra)
132
        except Exception:
133
            LOG.exception('Failed to config for pack %s.', pack)
134
            raise
135
136
        return config_db
137
138
139
def register_configs(packs_base_paths=None, pack_dir=None, use_pack_cache=True,
140
                     fail_on_failure=False, validate_configs=True):
141
142
    if packs_base_paths:
143
        assert isinstance(packs_base_paths, list)
144
145
    if not packs_base_paths:
146
        packs_base_paths = content_utils.get_packs_base_paths()
147
148
    registrar = ConfigsRegistrar(use_pack_cache=use_pack_cache,
149
                                 fail_on_failure=fail_on_failure,
150
                                 validate_configs=validate_configs)
151
152
    if pack_dir:
153
        result = registrar.register_from_pack(pack_dir=pack_dir)
154
    else:
155
        result = registrar.register_from_packs(base_dirs=packs_base_paths)
156
157
    return result
158