Passed
Pull Request — master (#3462)
by Lakshmi
05:23
created

_validate_definitions()   A

Complexity

Conditions 4

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
dl 0
loc 20
rs 9.2
c 0
b 0
f 0
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
"""
17
A script that validates each entry defined in OpenAPI-Spec for st2 APIs
18
(in st2common/openapi.yaml) has a corresponding API model class defined
19
in st2common/models/api/.
20
"""
21
22
import os
23
24
from oslo_config import cfg
25
from prance import ResolvingParser
26
27
from st2common import config
28
from st2common import log as logging
29
from st2common.util import spec_loader
30
from st2common.script_setup import setup as common_setup
31
from st2common.script_setup import teardown as common_teardown
32
33
34
__all__ = [
35
    'main'
36
]
37
38
39
cfg.CONF.register_cli_opt(
40
    cfg.StrOpt('spec-file', short='f', required=False,
41
               default='st2common/st2common/openapi.yaml')
42
)
43
44
cfg.CONF.register_cli_opt(
45
    cfg.BoolOpt('generate', short='-c', required=False,
46
                default=False)
47
)
48
49
LOG = logging.getLogger(__name__)
50
51
52
def setup():
53
    common_setup(config=config, setup_db=False, register_mq_exchanges=False)
54
55
56
def _validate_definitions(spec):
57
    defs = spec.get('definitions', None)
58
    error = False
59
    verbose = cfg.CONF.verbose
60
61
    for (model, definition) in defs.iteritems():
62
        api_model = definition.get('x-api-model', None)
63
64
        if not api_model:
65
            msg = (
66
                'API model field "x-api-model" not defined for definition "%s".' % model
67
            )
68
69
            if verbose:
70
                LOG.info('Supplied definition for model %s: \n\n%s.', model, definition)
71
72
            error = True
73
            LOG.error(msg)
74
75
    return error
76
77
78
def validate_spec():
79
    spec_file = cfg.CONF.spec_file
80
    generate_spec = cfg.CONF.generate
81
82
    if not os.path.exists(spec_file) and not generate_spec:
83
        msg = ('No spec file found in location %s. ' % spec_file +
84
               'Provide a valid spec file or ' +
85
               'pass --generate-api-spec to genrate a spec.')
86
        raise Exception(msg)
87
88
    if generate_spec:
89
        if not spec_file:
90
            raise Exception('Supply a path to write to spec file to.')
91
92
        spec_string = spec_loader.generate_spec('st2common', 'openapi.yaml.j2')
93
94
        with open(spec_file, 'w') as f:
95
            f.write(spec_string)
96
            f.flush()
97
98
    parser = ResolvingParser(spec_file)
99
    spec = parser.specification
100
101
    return _validate_definitions(spec)
102
103
104
def teartown():
105
    common_teardown()
106
107
108
def main():
109
    setup()
110
111
    try:
112
        ret = validate_spec()
113
    except Exception as e:
114
        LOG.error(e.message)
115
        ret = 1
116
    finally:
117
        teartown()
118
119
    return ret
120