RIFT OSM R1 Initial Submission
[osm/SO.git] / common / python / rift / mano / tosca_translator / rwmano / translate_inputs.py
diff --git a/common/python/rift/mano/tosca_translator/rwmano/translate_inputs.py b/common/python/rift/mano/tosca_translator/rwmano/translate_inputs.py
new file mode 100644 (file)
index 0000000..e5583d5
--- /dev/null
@@ -0,0 +1,172 @@
+# STANDARD_RIFT_IO_COPYRIGHT
+
+# Modified from https://github.com/openstack/heat-translator (APL 2.0)
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from rift.mano.tosca_translator.common.utils import _
+from rift.mano.tosca_translator.rwmano.syntax.mano_parameter import ManoParameter
+
+from toscaparser.dataentity import DataEntity
+from toscaparser.elements.scalarunit import ScalarUnit_Size
+from toscaparser.parameters import Input
+from toscaparser.utils.validateutils import TOSCAVersionProperty
+
+
+INPUT_CONSTRAINTS = (CONSTRAINTS, DESCRIPTION, LENGTH, RANGE,
+                     MIN, MAX, ALLOWED_VALUES, ALLOWED_PATTERN) = \
+                    ('constraints', 'description', 'length', 'range',
+                     'min', 'max', 'allowed_values', 'allowed_pattern')
+
+TOSCA_CONSTRAINT_OPERATORS = (EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN,
+                              LESS_OR_EQUAL, IN_RANGE, VALID_VALUES, LENGTH,
+                              MIN_LENGTH, MAX_LENGTH, PATTERN) = \
+                             ('equal', 'greater_than', 'greater_or_equal',
+                              'less_than', 'less_or_equal', 'in_range',
+                              'valid_values', 'length', 'min_length',
+                              'max_length', 'pattern')
+
+TOSCA_TO_MANO_CONSTRAINTS_ATTRS = {'equal': 'allowed_values',
+                                   'greater_than': 'range',
+                                   'greater_or_equal': 'range',
+                                   'less_than': 'range',
+                                   'less_or_equal': 'range',
+                                   'in_range': 'range',
+                                   'valid_values': 'allowed_values',
+                                   'length': 'length',
+                                   'min_length': 'length',
+                                   'max_length': 'length',
+                                   'pattern': 'allowed_pattern'}
+
+TOSCA_TO_MANO_INPUT_TYPES = {'string': 'string',
+                             'integer': 'number',
+                             'float': 'number',
+                             'boolean': 'boolean',
+                             'timestamp': 'string',
+                             'scalar-unit.size': 'number',
+                             'version': 'string',
+                             'null': 'string',
+                             'PortDef': 'number'}
+
+
+class TranslateInputs(object):
+
+    '''Translate TOSCA Inputs to RIFT MANO input Parameters.'''
+
+    def __init__(self, log, inputs, parsed_params, deploy=None):
+        self.log = log
+        self.inputs = inputs
+        self.parsed_params = parsed_params
+        self.deploy = deploy
+
+    def translate(self):
+        return self._translate_inputs()
+
+    def _translate_inputs(self):
+        mano_inputs = []
+        if 'key_name' in self.parsed_params and 'key_name' not in self.inputs:
+            name = 'key_name'
+            type = 'string'
+            default = self.parsed_params[name]
+            schema_dict = {'type': type, 'default': default}
+            input = Input(name, schema_dict)
+            self.inputs.append(input)
+
+        self.log.info(_('Translating TOSCA input type to MANO input type.'))
+        for input in self.inputs:
+            mano_default = None
+            mano_input_type = TOSCA_TO_MANO_INPUT_TYPES[input.type]
+
+            if input.name in self.parsed_params:
+                mano_default = DataEntity.validate_datatype(
+                    input.type, self.parsed_params[input.name])
+            elif input.default is not None:
+                mano_default = DataEntity.validate_datatype(input.type,
+                                                            input.default)
+            else:
+                if self.deploy:
+                    msg = _("Need to specify a value "
+                            "for input {0}.").format(input.name)
+                    self.log.error(msg)
+                    raise Exception(msg)
+            if input.type == "scalar-unit.size":
+                # Assumption here is to use this scalar-unit.size for size of
+                # cinder volume in heat templates and will be in GB.
+                # should add logic to support other types if needed.
+                input_value = mano_default
+                mano_default = (ScalarUnit_Size(mano_default).
+                                get_num_from_scalar_unit('GiB'))
+                if mano_default == 0:
+                    msg = _('Unit value should be > 0.')
+                    self.log.error(msg)
+                    raise Exception(msg)
+                elif int(mano_default) < mano_default:
+                    mano_default = int(mano_default) + 1
+                    self.log.warning(_("Cinder unit value should be in"
+                                       " multiples of GBs. So corrected"
+                                       " %(input_value)s to %(mano_default)s"
+                                       " GB.")
+                                     % {'input_value': input_value,
+                                        'mano_default': mano_default})
+            if input.type == 'version':
+                mano_default = TOSCAVersionProperty(mano_default).get_version()
+
+            mano_constraints = []
+            if input.constraints:
+                for constraint in input.constraints:
+                    if mano_default:
+                        constraint.validate(mano_default)
+                    hc, hvalue = self._translate_constraints(
+                        constraint.constraint_key, constraint.constraint_value)
+                    mano_constraints.append({hc: hvalue})
+
+            mano_inputs.append(ManoParameter(self.log,
+                                             name=input.name,
+                                             type=mano_input_type,
+                                             description=input.description,
+                                             default=mano_default,
+                                             constraints=mano_constraints))
+        return mano_inputs
+
+    def _translate_constraints(self, name, value):
+        mano_constraint = TOSCA_TO_MANO_CONSTRAINTS_ATTRS[name]
+
+        # Offset used to support less_than and greater_than.
+        # TODO(anyone):  when parser supports float, verify this works
+        offset = 1
+
+        if name == EQUAL:
+            mano_value = [value]
+        elif name == GREATER_THAN:
+            mano_value = {"min": value + offset}
+        elif name == GREATER_OR_EQUAL:
+            mano_value = {"min": value}
+        elif name == LESS_THAN:
+            mano_value = {"max": value - offset}
+        elif name == LESS_OR_EQUAL:
+            mano_value = {"max": value}
+        elif name == IN_RANGE:
+            # value is list type here
+            min_value = min(value)
+            max_value = max(value)
+            mano_value = {"min": min_value, "max": max_value}
+        elif name == LENGTH:
+            mano_value = {"min": value, "max": value}
+        elif name == MIN_LENGTH:
+            mano_value = {"min": value}
+        elif name == MAX_LENGTH:
+            mano_value = {"max": value}
+        else:
+            mano_value = value
+        return mano_constraint, mano_value