docs: fix issues
[parser.git] / tosca2heat / heat-translator-0.3.0 / translator / hot / translate_inputs.py
1 #
2 # Licensed under the Apache License, Version 2.0 (the "License"); you may
3 # not use this file except in compliance with the License. You may obtain
4 # a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 # License for the specific language governing permissions and limitations
12 # under the License.
13
14 import logging
15 from toscaparser.dataentity import DataEntity
16 from toscaparser.elements.scalarunit import ScalarUnit_Size
17 from toscaparser.utils.gettextutils import _
18 from toscaparser.utils.validateutils import TOSCAVersionProperty
19 from translator.hot.syntax.hot_parameter import HotParameter
20
21
22 INPUT_CONSTRAINTS = (CONSTRAINTS, DESCRIPTION, LENGTH, RANGE,
23                      MIN, MAX, ALLOWED_VALUES, ALLOWED_PATTERN) = \
24                     ('constraints', 'description', 'length', 'range',
25                      'min', 'max', 'allowed_values', 'allowed_pattern')
26
27 TOSCA_CONSTRAINT_OPERATORS = (EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN,
28                               LESS_OR_EQUAL, IN_RANGE, VALID_VALUES, LENGTH,
29                               MIN_LENGTH, MAX_LENGTH, PATTERN) = \
30                              ('equal', 'greater_than', 'greater_or_equal',
31                               'less_than', 'less_or_equal', 'in_range',
32                               'valid_values', 'length', 'min_length',
33                               'max_length', 'pattern')
34
35 TOSCA_TO_HOT_CONSTRAINTS_ATTRS = {'equal': 'allowed_values',
36                                   'greater_than': 'range',
37                                   'greater_or_equal': 'range',
38                                   'less_than': 'range',
39                                   'less_or_equal': 'range',
40                                   'in_range': 'range',
41                                   'valid_values': 'allowed_values',
42                                   'length': 'length',
43                                   'min_length': 'length',
44                                   'max_length': 'length',
45                                   'pattern': 'allowed_pattern'}
46
47 TOSCA_TO_HOT_INPUT_TYPES = {'string': 'string',
48                             'integer': 'number',
49                             'float': 'number',
50                             'boolean': 'boolean',
51                             'timestamp': 'string',
52                             'scalar-unit.size': 'number',
53                             'version': 'string',
54                             'null': 'string',
55                             'PortDef': 'number'}
56
57 log = logging.getLogger('heat-translator')
58
59
60 class TranslateInputs(object):
61     '''Translate TOSCA Inputs to Heat Parameters.'''
62
63     def __init__(self, inputs, parsed_params):
64         self.inputs = inputs
65         self.parsed_params = parsed_params
66
67     def translate(self):
68         return self._translate_inputs()
69
70     def _translate_inputs(self):
71         hot_inputs = []
72         hot_default = None
73         for input in self.inputs:
74             hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type]
75
76             if input.name in self.parsed_params:
77                 hot_default = DataEntity.validate_datatype(
78                     input.type, self.parsed_params[input.name])
79             elif input.default is not None:
80                 hot_default = DataEntity.validate_datatype(input.type,
81                                                            input.default)
82             else:
83                 log.warning(_("Need to specify a value "
84                               "for input {0}").format(input.name))
85                 raise Exception(_("Need to specify a value "
86                                   "for input {0}").format(input.name))
87             if input.type == "scalar-unit.size":
88                 # Assumption here is to use this scalar-unit.size for size of
89                 # cinder volume in heat templates and will be in GB.
90                 # should add logic to support other types if needed.
91                 input_value = hot_default
92                 hot_default = (ScalarUnit_Size(hot_default).
93                                get_num_from_scalar_unit('GiB'))
94                 if hot_default == 0:
95                     log.warning(_('Unit value should be > 0.'))
96                     raise Exception(_(
97                         'Unit value should be > 0.'))
98                 elif int(hot_default) < hot_default:
99                     hot_default = int(hot_default) + 1
100                     log.warning(_("Cinder unit value should be in multiples"
101                                   " of GBs. So corrected %(input_value)s "
102                                   "to %(hot_default)s GB.")
103                                 % {'input_value': input_value,
104                                    'hot_default': hot_default})
105             if input.type == 'version':
106                 hot_default = TOSCAVersionProperty(hot_default).get_version()
107
108             hot_constraints = []
109             if input.constraints:
110                 for constraint in input.constraints:
111                     constraint.validate(hot_default)
112                     hc, hvalue = self._translate_constraints(
113                         constraint.constraint_key, constraint.constraint_value)
114                     hot_constraints.append({hc: hvalue})
115
116             hot_inputs.append(HotParameter(name=input.name,
117                                            type=hot_input_type,
118                                            description=input.description,
119                                            default=hot_default,
120                                            constraints=hot_constraints))
121         return hot_inputs
122
123     def _translate_constraints(self, name, value):
124         hot_constraint = TOSCA_TO_HOT_CONSTRAINTS_ATTRS[name]
125
126         # Offset used to support less_than and greater_than.
127         # TODO(anyone):  when parser supports float, verify this works
128         offset = 1
129
130         if name == EQUAL:
131             hot_value = [value]
132         elif name == GREATER_THAN:
133             hot_value = {"min": value + offset}
134         elif name == GREATER_OR_EQUAL:
135             hot_value = {"min": value}
136         elif name == LESS_THAN:
137             hot_value = {"max": value - offset}
138         elif name == LESS_OR_EQUAL:
139             hot_value = {"max": value}
140         elif name == IN_RANGE:
141             # value is list type here
142             min_value = min(value)
143             max_value = max(value)
144             hot_value = {"min": min_value, "max": max_value}
145         elif name == LENGTH:
146             hot_value = {"min": value, "max": value}
147         elif name == MIN_LENGTH:
148             hot_value = {"min": value}
149         elif name == MAX_LENGTH:
150             hot_value = {"max": value}
151         else:
152             hot_value = value
153         return hot_constraint, hot_value