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
6 # http://www.apache.org/licenses/LICENSE-2.0
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
15 from toscaparser.dataentity import DataEntity
16 from toscaparser.elements.scalarunit import ScalarUnit_Size
17 from toscaparser.parameters import Input
18 from toscaparser.utils.gettextutils import _
19 from toscaparser.utils.validateutils import TOSCAVersionProperty
20 from translator.hot.syntax.hot_parameter import HotParameter
23 INPUT_CONSTRAINTS = (CONSTRAINTS, DESCRIPTION, LENGTH, RANGE,
24 MIN, MAX, ALLOWED_VALUES, ALLOWED_PATTERN) = \
25 ('constraints', 'description', 'length', 'range',
26 'min', 'max', 'allowed_values', 'allowed_pattern')
28 TOSCA_CONSTRAINT_OPERATORS = (EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN,
29 LESS_OR_EQUAL, IN_RANGE, VALID_VALUES, LENGTH,
30 MIN_LENGTH, MAX_LENGTH, PATTERN) = \
31 ('equal', 'greater_than', 'greater_or_equal',
32 'less_than', 'less_or_equal', 'in_range',
33 'valid_values', 'length', 'min_length',
34 'max_length', 'pattern')
36 TOSCA_TO_HOT_CONSTRAINTS_ATTRS = {'equal': 'allowed_values',
37 'greater_than': 'range',
38 'greater_or_equal': 'range',
40 'less_or_equal': 'range',
42 'valid_values': 'allowed_values',
44 'min_length': 'length',
45 'max_length': 'length',
46 'pattern': 'allowed_pattern'}
48 TOSCA_TO_HOT_INPUT_TYPES = {'string': 'string',
52 'timestamp': 'string',
53 'scalar-unit.size': 'number',
58 log = logging.getLogger('heat-translator')
61 class TranslateInputs(object):
63 '''Translate TOSCA Inputs to Heat Parameters.'''
65 def __init__(self, inputs, parsed_params, deploy=None):
67 self.parsed_params = parsed_params
71 return self._translate_inputs()
73 def _translate_inputs(self):
75 if 'key_name' in self.parsed_params and 'key_name' not in self.inputs:
78 default = self.parsed_params[name]
79 schema_dict = {'type': type, 'default': default}
80 input = Input(name, schema_dict)
81 self.inputs.append(input)
83 log.info(_('Translating TOSCA input type to HOT input type.'))
84 for input in self.inputs:
86 hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type]
88 if input.name in self.parsed_params:
89 hot_default = DataEntity.validate_datatype(
90 input.type, self.parsed_params[input.name])
91 elif input.default is not None:
92 hot_default = DataEntity.validate_datatype(input.type,
96 msg = _("Need to specify a value "
97 "for input {0}.").format(input.name)
100 if input.type == "scalar-unit.size":
101 # Assumption here is to use this scalar-unit.size for size of
102 # cinder volume in heat templates and will be in GB.
103 # should add logic to support other types if needed.
104 input_value = hot_default
105 hot_default = (ScalarUnit_Size(hot_default).
106 get_num_from_scalar_unit('GiB'))
108 msg = _('Unit value should be > 0.')
111 elif int(hot_default) < hot_default:
112 hot_default = int(hot_default) + 1
113 log.warning(_("Cinder unit value should be in multiples"
114 " of GBs. So corrected %(input_value)s "
115 "to %(hot_default)s GB.")
116 % {'input_value': input_value,
117 'hot_default': hot_default})
118 if input.type == 'version':
119 hot_default = TOSCAVersionProperty(hot_default).get_version()
122 if input.constraints:
123 for constraint in input.constraints:
125 constraint.validate(hot_default)
126 hc, hvalue = self._translate_constraints(
127 constraint.constraint_key, constraint.constraint_value)
128 hot_constraints.append({hc: hvalue})
130 hot_inputs.append(HotParameter(name=input.name,
132 description=input.description,
134 constraints=hot_constraints))
137 def _translate_constraints(self, name, value):
138 hot_constraint = TOSCA_TO_HOT_CONSTRAINTS_ATTRS[name]
140 # Offset used to support less_than and greater_than.
141 # TODO(anyone): when parser supports float, verify this works
146 elif name == GREATER_THAN:
147 hot_value = {"min": value + offset}
148 elif name == GREATER_OR_EQUAL:
149 hot_value = {"min": value}
150 elif name == LESS_THAN:
151 hot_value = {"max": value - offset}
152 elif name == LESS_OR_EQUAL:
153 hot_value = {"max": value}
154 elif name == IN_RANGE:
155 # value is list type here
156 min_value = min(value)
157 max_value = max(value)
158 hot_value = {"min": min_value, "max": max_value}
160 hot_value = {"min": value, "max": value}
161 elif name == MIN_LENGTH:
162 hot_value = {"min": value}
163 elif name == MAX_LENGTH:
164 hot_value = {"max": value}
167 return hot_constraint, hot_value