|
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_configs_for_all_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_config_for_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 = ConfigAPI.to_model(config_api) |
|
115
|
|
|
|
|
116
|
|
|
try: |
|
117
|
|
|
config_db.id = Config.get_by_pack(config_api.pack).id |
|
118
|
|
|
except StackStormDBObjectNotFoundError: |
|
119
|
|
|
LOG.debug('Config for pack "%s" not found. Creating new entry.', pack) |
|
120
|
|
|
|
|
121
|
|
|
try: |
|
122
|
|
|
config_db = Config.add_or_update(config_db) |
|
123
|
|
|
extra = {'config_db': config_db} |
|
124
|
|
|
LOG.audit('Config for pack "%s" is updated.', config_db.pack, extra=extra) |
|
125
|
|
|
except Exception: |
|
126
|
|
|
LOG.exception('Failed to config for pack %s.', pack) |
|
127
|
|
|
raise |
|
128
|
|
|
|
|
129
|
|
|
return config_db |
|
130
|
|
|
|
|
131
|
|
|
|
|
132
|
|
|
def register_configs(packs_base_paths=None, pack_dir=None, use_pack_cache=True, |
|
133
|
|
|
fail_on_failure=False, validate_configs=True): |
|
134
|
|
|
|
|
135
|
|
|
if packs_base_paths: |
|
136
|
|
|
assert isinstance(packs_base_paths, list) |
|
137
|
|
|
|
|
138
|
|
|
if not packs_base_paths: |
|
139
|
|
|
packs_base_paths = content_utils.get_packs_base_paths() |
|
140
|
|
|
|
|
141
|
|
|
registrar = ConfigsRegistrar(use_pack_cache=use_pack_cache, |
|
142
|
|
|
fail_on_failure=fail_on_failure, |
|
143
|
|
|
validate_configs=validate_configs) |
|
144
|
|
|
|
|
145
|
|
|
if pack_dir: |
|
146
|
|
|
result = registrar.register_config_for_pack(pack_dir=pack_dir) |
|
147
|
|
|
else: |
|
148
|
|
|
result = registrar.register_configs_for_all_packs(base_dirs=packs_base_paths) |
|
149
|
|
|
|
|
150
|
|
|
return result |
|
151
|
|
|
|