Passed
Pull Request — master (#3474)
by Lakshmi
07:18
created

_validate_position_values_contiguous()   A

Complexity

Conditions 3

Size

Total Lines 12

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 12
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 six
17
18
from st2common.exceptions.apivalidation import ValueValidationException
19
from st2common.exceptions.db import StackStormDBObjectNotFoundError
20
from st2common import log as logging
21
from st2common.util.action_db import get_runnertype_by_name
22
from st2common.util import schema as util_schema
23
from st2common.content.utils import get_packs_base_paths
24
from st2common.content.utils import check_pack_content_directory_exists
25
from st2common.models.system.common import ResourceReference
26
27
28
LOG = logging.getLogger(__name__)
29
30
31
def validate_action(action_api):
32
    runner_db = _get_runner_model(action_api)
33
34
    # Check if pack is valid.
35
    if not _is_valid_pack(action_api.pack):
36
        packs_base_paths = get_packs_base_paths()
37
        packs_base_paths = ','.join(packs_base_paths)
38
        msg = ('Content pack "%s" is not found or doesn\'t contain actions directory. '
39
               'Searched in: %s' %
40
               (action_api.pack, packs_base_paths))
41
        raise ValueValidationException(msg)
42
43
    # Check if parameters defined are valid.
44
    action_ref = ResourceReference.to_string_reference(pack=action_api.pack, name=action_api.name)
45
    _validate_parameters(action_ref, action_api.parameters, runner_db.runner_parameters)
46
47
48
def _get_runner_model(action_api):
49
    runner_db = None
50
    # Check if runner exists.
51
    try:
52
        runner_db = get_runnertype_by_name(action_api.runner_type)
53
    except StackStormDBObjectNotFoundError:
54
        msg = 'RunnerType %s is not found.' % action_api.runner_type
55
        raise ValueValidationException(msg)
56
    return runner_db
57
58
59
def _is_valid_pack(pack):
60
    return check_pack_content_directory_exists(pack=pack, content_type='actions')
61
62
63
def _validate_parameters(action_ref, action_params=None, runner_params=None):
64
    position_params = {}
65
    for action_param, action_param_meta in six.iteritems(action_params):
66
        # Check if overridden runner parameters are permitted.
67
        if action_param in runner_params:
68
            for action_param_attr, value in six.iteritems(action_param_meta):
69
                util_schema.validate_runner_parameter_attribute_override(
70
                    action_ref, action_param, action_param_attr,
71
                    value, runner_params[action_param].get(action_param_attr))
72
73
        if 'position' in action_param_meta:
74
            pos = action_param_meta['position']
75
            param = position_params.get(pos, None)
76
            if param:
77
                msg = ('Parameters %s and %s have same position %d.' % (action_param, param, pos) +
78
                       ' Position values have to be unique.')
79
                raise ValueValidationException(msg)
80
            else:
81
                position_params[pos] = action_param
82
83
        if 'immutable' in action_param_meta:
84
            if action_param in runner_params:
85
                runner_param_meta = runner_params[action_param]
86
                if 'immutable' in runner_param_meta:
87
                    msg = 'Param %s is declared immutable in runner. ' % action_param + \
88
                          'Cannot override in action.'
89
                    raise ValueValidationException(msg)
90
                if 'default' not in action_param_meta and 'default' not in runner_param_meta:
91
                    msg = 'Immutable param %s requires a default value.' % action_param
92
                    raise ValueValidationException(msg)
93
            else:
94
                if 'default' not in action_param_meta:
95
                    msg = 'Immutable param %s requires a default value.' % action_param
96
                    raise ValueValidationException(msg)
97
98
    return _validate_position_values_contiguous(position_params)
99
100
101
def _validate_position_values_contiguous(position_params):
102
    if not position_params:
103
        return True
104
105
    positions = sorted(position_params.keys())
106
    contiguous = (positions == range(min(positions), max(positions) + 1))
107
108
    if not contiguous:
109
        msg = 'Positions supplied %s for parameters are not contiguous.' % positions
110
        raise ValueValidationException(msg)
111
112
    return True
113