Test Failed
Push — master ( e380d0...f5671d )
by W
02:58
created

tools/config_gen.py (2 issues)

1
#!/usr/bin/env python
2
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
3
# contributor license agreements.  See the NOTICE file distributed with
4
# this work for additional information regarding copyright ownership.
5
# The ASF licenses this file to You under the Apache License, Version 2.0
6
# (the "License"); you may not use this file except in compliance with
7
# the License.  You may obtain a copy of the License at
8
#
9
#     http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16
17
from __future__ import absolute_import
18
import collections
19
import importlib
20
import six
21
import sys
22
import traceback
23
24
from oslo_config import cfg
25
26
27
CONFIGS = ['st2actions.config',
28
           'st2actions.notifier.config',
29
           'st2actions.resultstracker.config',
30
           'st2actions.workflows.config',
31
           'st2api.config',
32
           'st2stream.config',
33
           'st2auth.config',
34
           'st2common.config',
35
           'st2exporter.config',
36
           'st2reactor.rules.config',
37
           'st2reactor.sensor.config',
38
           'st2reactor.timer.config',
39
           'st2reactor.garbage_collector.config']
40
41
SKIP_GROUPS = ['api_pecan', 'rbac', 'results_tracker']
42
43
# We group auth options together to nake it a bit more clear what applies where
44
AUTH_OPTIONS = {
45
    'common': [
46
        'enable',
47
        'mode',
48
        'logging',
49
        'api_url',
50
        'token_ttl',
51
        'service_token_ttl',
52
        'debug'
53
    ],
54
    'standalone': [
55
        'host',
56
        'port',
57
        'use_ssl',
58
        'cert',
59
        'key',
60
        'backend',
61
        'backend_kwargs'
62
    ]
63
}
64
65
# Some of the config values change depenending on the environment where this script is ran so we
66
# set them to static values to ensure consistent and stable output
67
STATIC_OPTION_VALUES = {
68
    'actionrunner': {
69
        'virtualenv_binary': '/usr/bin/virtualenv',
70
        'python_binary': '/usr/bin/python',
71
        'python3_binary': '/usr/bin/python3'
72
    },
73
    'webui': {
74
        'webui_base_url': 'https://localhost'
75
    }
76
}
77
78
COMMON_AUTH_OPTIONS_COMMENT = """
79
# Common option - options below apply in both scenarios - when auth service is running as a WSGI
80
# service (e.g. under Apache or Nginx) and when it's running in the standalone mode.
81
""".strip()
82
83
STANDALONE_AUTH_OPTIONS_COMMENT = """
84
# Standalone mode options - options below only apply when auth service is running in the standalone
85
# mode.
86
""".strip()
87
88
89
def _import_config(config):
90
    try:
91
        return importlib.import_module(config)
92
    except:
93
        traceback.print_exc()
94
    return None
95
96
97
def _read_current_config(opt_groups):
98
    for k, v in six.iteritems(cfg.CONF._groups):
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _groups was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
99
        if k in SKIP_GROUPS:
100
            continue
101
        if k not in opt_groups:
102
            opt_groups[k] = v
103
    return opt_groups
104
105
106
def _clear_config():
107
    cfg.CONF.reset()
108
109
110
def _read_group(opt_group):
111
    all_options = list(opt_group._opts.values())
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _opts was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
112
113
    if opt_group.name == 'auth':
114
        print(COMMON_AUTH_OPTIONS_COMMENT)
115
        print('')
116
        common_options = [option for option in all_options if option['opt'].name in
117
                          AUTH_OPTIONS['common']]
118
        _print_options(opt_group=opt_group, options=common_options)
119
120
        print('')
121
        print(STANDALONE_AUTH_OPTIONS_COMMENT)
122
        print('')
123
        standalone_options = [option for option in all_options if option['opt'].name in
124
                              AUTH_OPTIONS['standalone']]
125
        _print_options(opt_group=opt_group, options=standalone_options)
126
127
        if len(common_options) + len(standalone_options) != len(all_options):
128
            msg = ('Not all options are declared in AUTH_OPTIONS dict, please update it')
129
            raise Exception(msg)
130
    else:
131
        options = all_options
132
        _print_options(opt_group=opt_group, options=options)
133
134
135
def _read_groups(opt_groups):
136
    opt_groups = collections.OrderedDict(sorted(opt_groups.items()))
137
    for name, opt_group in six.iteritems(opt_groups):
138
        print('[%s]' % name)
139
        _read_group(opt_group)
140
        print('')
141
142
143
def _print_options(opt_group, options):
144
    for opt in options:
145
        opt = opt['opt']
146
147
        # Special case for options which could change during this script run
148
        static_option_value = STATIC_OPTION_VALUES.get(opt_group.name, {}).get(opt.name, None)
149
        if static_option_value:
150
            opt.default = static_option_value
151
152
        # Special handling for list options
153
        if isinstance(opt, cfg.ListOpt):
154
            if opt.default:
155
                value = ','.join(opt.default)
156
            else:
157
                value = ''
158
159
            value += ' # comma separated list allowed here.'
160
        else:
161
            value = opt.default
162
163
        print('# %s' % opt.help)
164
        print('%s = %s' % (opt.name, value))
165
166
167
def main(args):
168
    opt_groups = {}
169
    for config in CONFIGS:
170
        mod = _import_config(config)
171
        mod.register_opts()
172
        _read_current_config(opt_groups)
173
        _clear_config()
174
    _read_groups(opt_groups)
175
176
177
if __name__ == '__main__':
178
    main(sys.argv)
179