Exemplo n.º 1
0
    def _validate_and_load_imports(self):
        imports_names = set()

        if not self.importslist:
            msg = _('"imports" keyname is defined without including '
                    'templates.')
            log.error(msg)
            ExceptionCollector.appendException(ValidationError(message=msg))
            return

        for import_def in self.importslist:
            if isinstance(import_def, dict):
                for import_name, import_uri in import_def.items():
                    if import_name in imports_names:
                        msg = (_('Duplicate import name "%s" was found.') %
                               import_name)
                        log.error(msg)
                        ExceptionCollector.appendException(
                            ValidationError(message=msg))
                    imports_names.add(import_name)

                    custom_type = self._load_import_template(import_name,
                                                             import_uri)
                    namespace_prefix = None
                    if isinstance(import_uri, dict):
                        namespace_prefix = import_uri.get(
                            self.NAMESPACE_PREFIX)

                    self._update_custom_def(custom_type, namespace_prefix)
            else:  # old style of imports
                custom_type = self._load_import_template(None,
                                                         import_def)
                if custom_type:
                    self._update_custom_def(custom_type, None)
Exemplo n.º 2
0
 def _validate_fields(self):
     if self.defs:
         for name in self.defs.keys():
             if name not in self.SECTIONS:
                 ExceptionCollector.appendException(
                     UnknownFieldError(what='Group Type %s'
                                       % self.grouptype, field=name))
Exemplo n.º 3
0
 def __init__(self, property_name, property_type, constraint):
     super(Pattern, self).__init__(property_name, property_type, constraint)
     if not isinstance(self.constraint_value, self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "pattern" '
                                          'expects a string.')))
     self.match = re.compile(self.constraint_value).match
Exemplo n.º 4
0
 def validate(self):
     if len(self.args) != 2:
         ExceptionCollector.appendException(
             ValueError(_('Illegal arguments for function "{0}". Expected '
                          'arguments: "node-template-name", '
                          '"attribute-name"').format(GET_ATTRIBUTE)))
     self._find_node_template_containing_attribute()
Exemplo n.º 5
0
 def validate(self):
     if len(self.args) < 2:
         ExceptionCollector.appendException(
             ValueError(_('Expected arguments: "node-template-name", "req-or-cap" ' '(optional), "property name".'))
         )
         return
     if len(self.args) == 2:
         found_prop = self._find_property(self.args[1])
         if not found_prop:
             return
         prop = found_prop.value
         if not isinstance(prop, Function):
             get_function(self.tosca_tpl, self.context, prop)
     elif len(self.args) >= 3:
         # do not use _find_property to avoid raise KeyError
         # if the prop is not found
         # First check if there is property with this name
         node_tpl = self._find_node_template(self.args[0])
         props = node_tpl.get_properties() if node_tpl else []
         index = 2
         found = [props[self.args[1]]] if self.args[1] in props else []
         if found:
             property_value = found[0].value
         else:
             index = 3
             # then check the req or caps
             property_value = self._find_req_or_cap_property(self.args[1], self.args[2])
         if len(self.args) > index:
             for elem in self.args[index:]:
                 if isinstance(property_value, list):
                     int_elem = int(elem)
                     property_value = self._get_index_value(property_value, int_elem)
                 else:
                     property_value = self._get_attribute_value(property_value, elem)
Exemplo n.º 6
0
    def __init__(self, name, value=None, schema=None):
        self.name = name
        self.value = value
        self.schema = schema

        try:
            self.schema['type']
        except KeyError:
            msg = (_('Schema definition of "%(pname)s" must have a "type" '
                     'attribute.') % dict(pname=self.name))
            ExceptionCollector.appendException(
                InvalidSchemaError(message=msg))

        if 'required' in self.schema:
            required = self.schema['required']
            if not isinstance(required, bool):
                if required.lower() not in self.VALID_REQUIRED_VALUES:
                    valid_values = ', '.join(self.VALID_REQUIRED_VALUES)
                    msg = (_('Schema definition of "%(propname)s" has '
                             '"required" attribute with invalid value '
                             '"%(value1)s". The value must be one of '
                             '"%(value2)s".') % {"propname": self.name,
                                                 "value1": required,
                                                 "value2": valid_values})
                    ExceptionCollector.appendException(
                        InvalidSchemaError(message=msg))
Exemplo n.º 7
0
 def validate(self):
     if len(self.args) < 1:
         ExceptionCollector.appendException(
             ValueError(
                 _('Invalid arguments for function "{0}". Expected ' "at least one arguments.").format(CONCAT)
             )
         )
Exemplo n.º 8
0
 def _common_validate_properties(self, entitytype, properties):
     allowed_props = []
     required_props = []
     for p in entitytype.get_properties_def_objects():
         allowed_props.append(p.name)
         if p.required:
             required_props.append(p.name)
     if properties:
         self._common_validate_field(properties, allowed_props,
                                     'properties')
         # make sure it's not missing any property required by a tosca type
         missingprop = []
         for r in required_props:
             if r not in properties.keys():
                 missingprop.append(r)
         if missingprop:
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(
                     what='"properties" of template "%s"' % self.name,
                     required=missingprop))
     else:
         if required_props:
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(
                     what='"properties" of template "%s"' % self.name,
                     required=missingprop))
Exemplo n.º 9
0
    def _validate_requirements(self):
        type_requires = self.type_definition.get_all_requirements()
        allowed_reqs = ["template"]
        if type_requires:
            for treq in type_requires:
                for key, value in treq.items():
                    allowed_reqs.append(key)
                    if isinstance(value, dict):
                        for key in value:
                            allowed_reqs.append(key)

        requires = self.type_definition.get_value(self.REQUIREMENTS,
                                                  self.entity_tpl)
        if requires:
            if not isinstance(requires, list):
                ExceptionCollector.appendException(
                    TypeMismatchError(
                        what='"requirements" of template "%s"' % self.name,
                        type='list'))
            for req in requires:
                for r1, value in req.items():
                    if isinstance(value, dict):
                        self._validate_requirements_keys(value)
                        self._validate_requirements_properties(value)
                        allowed_reqs.append(r1)
                self._common_validate_field(req, allowed_reqs, 'requirements')
Exemplo n.º 10
0
 def __init__(self, property_name, property_type, constraint):
     super(ValidValues, self).__init__(property_name, property_type,
                                       constraint)
     if not isinstance(self.constraint_value, collections.Sequence):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "valid_values" '
                                          'expects a list.')))
Exemplo n.º 11
0
 def _common_validate_properties(self, entitytype, properties):
     allowed_props = []
     required_props = []
     for p in entitytype.get_properties_def_objects():
         allowed_props.append(p.name)
         # If property is 'required' and has no 'default' value then record
         if p.required and p.default is None:
             required_props.append(p.name)
     # validate all required properties have values
     if properties:
         req_props_no_value_or_default = []
         self._common_validate_field(properties, allowed_props,
                                     'properties')
         # make sure it's not missing any property required by a tosca type
         for r in required_props:
             if r not in properties.keys():
                 req_props_no_value_or_default.append(r)
         # Required properties found without value or a default value
         if req_props_no_value_or_default:
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(
                     what='"properties" of template "%s"' % self.name,
                     required=req_props_no_value_or_default))
     else:
         # Required properties in schema, but not in template
         if required_props:
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(
                     what='"properties" of template "%s"' % self.name,
                     required=required_props))
Exemplo n.º 12
0
 def _validate_keys(self):
     """validate the keys of substitution mappings."""
     for key in self.sub_mapping_def.keys():
         if key not in self.SECTIONS:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='SubstitutionMappings',
                                   field=key))
Exemplo n.º 13
0
 def __init__(self, property_name, property_type, constraint):
     super(GreaterThan, self).__init__(property_name, property_type,
                                       constraint)
     if not isinstance(constraint[self.GREATER_THAN], self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "greater_than" '
                                          'expects comparable values.')))
Exemplo n.º 14
0
 def __init__(self, property_name, property_type, constraint):
     super(LessOrEqual, self).__init__(property_name, property_type,
                                       constraint)
     if not isinstance(self.constraint_value, self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "less_or_equal" '
                                          'expects comparable values.')))
Exemplo n.º 15
0
    def _validate_capabilities_properties(self, capabilities):
        for cap, props in capabilities.items():
            capability = self.get_capability(cap)
            if not capability:
                continue
            capabilitydef = capability.definition
            self._common_validate_properties(capabilitydef,
                                             props[self.PROPERTIES])

            # validating capability properties values
            for prop in self.get_capability(cap).get_properties_objects():
                prop.validate()

                # TODO(srinivas_tadepalli): temporary work around to validate
                # default_instances until standardized in specification
                if cap == "scalable" and prop.name == "default_instances":
                    prop_dict = props[self.PROPERTIES]
                    min_instances = prop_dict.get("min_instances")
                    max_instances = prop_dict.get("max_instances")
                    default_instances = prop_dict.get("default_instances")
                    if not (min_instances <= default_instances
                            <= max_instances):
                        err_msg = ('"properties" of template "%s": '
                                   '"default_instances" value is not between '
                                   '"min_instances" and "max_instances".' %
                                   self.name)
                        ExceptionCollector.appendException(
                            ValidationError(message=err_msg))
Exemplo n.º 16
0
    def validate_additional_req(properties, prop_name, custom_def=None, ):
        try:
            source = properties.get(PortSpec.SOURCE)
            source_range = properties.get(PortSpec.SOURCE_RANGE)
            target = properties.get(PortSpec.TARGET)
            target_range = properties.get(PortSpec.TARGET_RANGE)

            # verify one of the specified values is set
            if source is None and source_range is None and \
                    target is None and target_range is None:
                ExceptionCollector.appendException(
                    InvalidTypeAdditionalRequirementsError(
                        type=PortSpec.TYPE_URI))
            # Validate source value is in specified range
            if source and source_range:
                validateutils.validate_value_in_range(source, source_range,
                                                      PortSpec.SOURCE)
            else:
                from toscaparser.dataentity import DataEntity
                portdef = DataEntity('PortDef', source, None, PortSpec.SOURCE)
                portdef.validate()
            # Validate target value is in specified range
            if target and target_range:
                validateutils.validate_value_in_range(target, target_range,
                                                      PortSpec.TARGET)
            else:
                from toscaparser.dataentity import DataEntity
                portdef = DataEntity('PortDef', source, None, PortSpec.TARGET)
                portdef.validate()
        except Exception:
            msg = _('"%(value)s" do not meet requirements '
                    'for type "%(type)s".') \
                % {'value': properties, 'type': PortSpec.SHORTNAME}
            ExceptionCollector.appendException(
                ValueError(msg))
Exemplo n.º 17
0
 def __init__(self, property_name, property_type, constraint):
     super(MaxLength, self).__init__(property_name, property_type,
                                     constraint)
     if not isinstance(self.constraint_value, self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "max_length" '
                                          'expects an integer.')))
Exemplo n.º 18
0
 def _validate_requirements_keys(self, requirement):
     for key in requirement.keys():
         if key not in self.REQUIREMENTS_SECTION:
             ExceptionCollector.appendException(
                 UnknownFieldError(
                     what='"requirements" of template "%s"' % self.name,
                     field=key))
Exemplo n.º 19
0
def validate_range(range):
    # list class check
    validate_list(range)
    # validate range list has a min and max
    if len(range) != 2:
        ExceptionCollector.appendException(
            ValueError(_('"%s" is not a valid range.') % range))
    # validate min and max are numerics or the keyword UNBOUNDED
    min_test = max_test = False
    if not range[0] == RANGE_UNBOUNDED:
        min = validate_numeric(range[0])
    else:
        min_test = True
    if not range[1] == RANGE_UNBOUNDED:
        max = validate_numeric(range[1])
    else:
        max_test = True
    # validate the max > min (account for UNBOUNDED)
    if not min_test and not max_test:
        # Note: min == max is allowed
        if min > max:
            ExceptionCollector.appendException(
                ValueError(_('"%s" is not a valid range.') % range))

    return range
Exemplo n.º 20
0
 def _validate_interfaces(self):
     ifaces = self.type_definition.get_value(self.INTERFACES,
                                             self.entity_tpl)
     if ifaces:
         for name, value in ifaces.items():
             if name in (LIFECYCLE, LIFECYCLE_SHORTNAME):
                 self._common_validate_field(
                     value, InterfacesDef.
                     interfaces_node_lifecycle_operations,
                     'interfaces')
             elif name in (CONFIGURE, CONFIGURE_SHORTNAME):
                 self._common_validate_field(
                     value, InterfacesDef.
                     interfaces_relationship_configure_operations,
                     'interfaces')
             elif name in self.type_definition.interfaces.keys():
                 self._common_validate_field(
                     value,
                     self._collect_custom_iface_operations(name),
                     'interfaces')
             else:
                 ExceptionCollector.appendException(
                     UnknownFieldError(
                         what='"interfaces" of template "%s"' %
                         self.name, field=name))
Exemplo n.º 21
0
 def _validate_keys(self):
     if self.defs:
         for key in self.defs.keys():
             if key not in self.SECTIONS:
                 ExceptionCollector.appendException(
                     UnknownFieldError(what='Nodetype"%s"' % self.ntype,
                                       field=key))
Exemplo n.º 22
0
 def _get_capability_property(self,
                              node_template,
                              capability_name,
                              property_name):
     """Gets a node template capability property."""
     caps = node_template.get_capabilities()
     if caps and capability_name in caps.keys():
         cap = caps[capability_name]
         property = None
         props = cap.get_properties()
         if props and property_name in props.keys():
             property = props[property_name].value
         if not property:
             ExceptionCollector.appendException(
                 KeyError(_('Property "%(prop)s" was not found in '
                            'capability "%(cap)s" of node template '
                            '"%(ntpl1)s" referenced from node template '
                            '"%(ntpl2)s".') % {'prop': property_name,
                                               'cap': capability_name,
                                               'ntpl1': node_template.name,
                                               'ntpl2': self.context.name}))
         return property
     msg = _('Requirement/Capability "{0}" referenced from node template '
             '"{1}" was not found in node template "{2}".').format(
                 capability_name,
                 self.context.name,
                 node_template.name)
     ExceptionCollector.appendException(KeyError(msg))
Exemplo n.º 23
0
 def _get_capability_attribute(self,
                               node_template,
                               capability_name,
                               attr_name):
     """Gets a node template capability attribute."""
     caps = node_template.get_capabilities()
     if caps and capability_name in caps.keys():
         cap = caps[capability_name]
         attribute = None
         attrs = cap.definition.get_attributes_def()
         if attrs and attr_name in attrs.keys():
             attribute = attrs[attr_name]
         if not attribute:
             ExceptionCollector.appendException(
                 KeyError(_('Attribute "%(attr)s" was not found in '
                            'capability "%(cap)s" of node template '
                            '"%(ntpl1)s" referenced from node template '
                            '"%(ntpl2)s".') % {'attr': attr_name,
                                               'cap': capability_name,
                                               'ntpl1': node_template.name,
                                               'ntpl2': self.context.name}))
         return attribute
     msg = _('Requirement/Capability "{0}" referenced from node template '
             '"{1}" was not found in node template "{2}".').format(
                 capability_name,
                 self.context.name,
                 node_template.name)
     ExceptionCollector.appendException(KeyError(msg))
Exemplo n.º 24
0
 def __init__(self, node_type, interfacetype,
              node_template=None, name=None, value=None):
     self.ntype = node_type
     self.node_template = node_template
     self.type = interfacetype
     self.name = name
     self.value = value
     self.implementation = None
     self.inputs = None
     self.defs = {}
     if interfacetype == LIFECYCLE_SHORTNAME:
         interfacetype = LIFECYCLE
     if interfacetype == CONFIGURE_SHORTNAME:
         interfacetype = CONFIGURE
     if node_type:
         self.defs = self.TOSCA_DEF[interfacetype]
     if value:
         if isinstance(self.value, dict):
             for i, j in self.value.items():
                 if i == IMPLEMENTATION:
                     self.implementation = j
                 elif i == INPUTS:
                     self.inputs = j
                 else:
                     what = ('"interfaces" of template "%s"' %
                             self.node_template.name)
                     ExceptionCollector.appendException(
                         UnknownFieldError(what=what, field=i))
         else:
             self.implementation = value
Exemplo n.º 25
0
 def _validate_type_version(self, version):
     if version not in self.VALID_TEMPLATE_VERSIONS:
         ExceptionCollector.appendException(
             InvalidTemplateVersion(
                 what=version + " in " + self.import_def, valid_versions=", ".join(self.VALID_TEMPLATE_VERSIONS)
             )
         )
Exemplo n.º 26
0
 def _validate_occurrences(self, occurrences):
     DataEntity.validate_datatype('list', occurrences)
     for value in occurrences:
         DataEntity.validate_datatype('integer', value)
     if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \
         or occurrences[1] == 0:
         ExceptionCollector.appendException(
             InvalidPropertyValueError(what=(occurrences)))
Exemplo n.º 27
0
 def _find_interface_name(self, interface_name):
     if interface_name in toscaparser.elements.interfaces.SECTIONS:
         return interface_name
     else:
         ExceptionCollector.appendException(
             ValueError(_('Enter a valid interface name'
                          ).format(GET_OPERATION_OUTPUT)))
         return
Exemplo n.º 28
0
 def validate(self):
     if len(self.args) != 1:
         ExceptionCollector.appendException(
             ValueError(_('Expected one argument for function "get_input" but ' 'received "%s".') % self.args)
         )
     inputs = [input.name for input in self.tosca_tpl.inputs]
     if self.args[0] not in inputs:
         ExceptionCollector.appendException(UnknownInputError(input_name=self.args[0]))
Exemplo n.º 29
0
 def validate(self, value):
     self.value_msg = value
     if self.property_type in scalarunit.ScalarUnit.SCALAR_UNIT_TYPES:
         value = scalarunit.get_scalarunit_value(self.property_type, value)
     if not self._is_valid(value):
         err_msg = self._err_msg(value)
         ExceptionCollector.appendException(
             ValidationError(message=err_msg))
Exemplo n.º 30
0
 def _common_validate_field(self, schema, allowedlist, section):
     for name in schema:
         if name not in allowedlist:
             ExceptionCollector.appendException(
                 UnknownFieldError(
                     what=('"%(section)s" of template "%(nodename)s"'
                           % {'section': section, 'nodename': self.name}),
                     field=name))
Exemplo n.º 31
0
    def validate(self):
        '''Validate the value by the definition of the datatype.'''

        # A datatype can not have both 'type' and 'properties' definitions.
        # If the datatype has 'type' definition
        log.debug("{}: Data type validate: {}, {}".format(
            self.datatype.type, self.datatype.value_type, self.value))
        if self.datatype.value_type:
            self.value = DataEntity.validate_datatype(self.datatype.value_type,
                                                      self.value, None,
                                                      self.custom_def)
            schema = Schema(self.property_name, self.datatype.defs)
            for constraint in schema.constraints:
                constraint.validate(self.value)
        # If the datatype has 'properties' definition
        else:
            if not isinstance(self.value, dict):
                ExceptionCollector.appendException(
                    TypeMismatchError(what=self.value,
                                      type=self.datatype.type))
            allowed_props = []
            required_props = []
            default_props = {}
            if self.schema:
                allowed_props = self.schema.keys()
                for name, prop_def in self.schema.items():
                    if prop_def.required:
                        required_props.append(name)
                    if prop_def.default:
                        default_props[name] = prop_def.default

            # check allowed field
            try:
                for value_key in list(self.value.keys()):
                    if value_key not in allowed_props:
                        log.info("Unknown field data {}: {}".format(
                            self.datatype.type, value_key))
                        ExceptionCollector.appendException(
                            UnknownFieldError(
                                what=(_('Data value of type "%s"') %
                                      self.datatype.type),
                                field=value_key))
            except Exception as e:
                log.error("Value: {}: {}".format(self.value, e))
                raise e

            # check default field
            for def_key, def_value in list(default_props.items()):
                if def_key not in list(self.value.keys()):
                    self.value[def_key] = def_value

            # check missing field
            missingprop = []
            for req_key in required_props:
                if req_key not in list(self.value.keys()):
                    missingprop.append(req_key)
            if missingprop:
                log.info("Missing field data {}: {}".format(
                    self.datatype.type, missingprop))
                ExceptionCollector.appendException(
                    MissingRequiredFieldError(
                        what=(_('Data value of type "%s"') %
                              self.datatype.type),
                        required=missingprop))

            # check every field
            for name, value in list(self.value.items()):
                schema_name = self._find_schema(name)
                if not schema_name:
                    continue
                log.debug("Name: {}, Schema: {}".format(name, schema_name))
                prop_schema = Schema(name, schema_name)
                # check if field value meets type defined
                DataEntity.validate_datatype(prop_schema.type, value,
                                             prop_schema.entry_schema,
                                             self.custom_def)
                # check if field value meets constraints defined if not a function
                from toscaparser.functions import is_function
                if prop_schema.constraints and is_function(value) is False:
                    for constraint in prop_schema.constraints:
                        if isinstance(value, list):
                            for val in value:
                                constraint.validate(val)
                        else:
                            constraint.validate(value)

        return self.value
Exemplo n.º 32
0
 def __init__(self, property_name, property_type, constraint):
     super(Enum, self).__init__(property_name, property_type, constraint)
     if not isinstance(self.constraint_value, self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=f'The property "enum expects a list of dict.'))
Exemplo n.º 33
0
def validate_list(value):
    if not isinstance(value, list):
        ExceptionCollector.appendException(
            ValueError(_('"%s" is not a list.') % value))
    return value
Exemplo n.º 34
0
 def _validate_field(self):
     for name in self.schema.schema:
         if name not in self.INPUTFIELD:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Input "%s"' % self.name,
                                   field=name))
Exemplo n.º 35
0
 def _validate_fields(self, nodetemplate):
     for name in nodetemplate.keys():
         if name not in self.SECTIONS and name not in self.SPECIAL_SECTIONS:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Node template "%s"' % self.name,
                                   field=name))
Exemplo n.º 36
0
def restructure_value(mapping_value, self, if_format_str=True, if_upper=True):
    """
    Recursive function which processes the mapping_value to become parameter:value format
    :param mapping_value: the map of non normative parameter:value
    :param self: the function used to store normative parameter, value and other values
    :param if_format_str:
    :param if_upper: detects if the parameter value must be saved
    :return: dict in the end of recursion, because the first is always (parameter, value) keys
    """
    if isinstance(mapping_value, dict):
        flat_mapping_value = dict()
        for key in MAPPING_VALUE_KEYS:
            mapping_sub_value = mapping_value.get(key)
            if mapping_sub_value is not None:
                restructured_value = restructure_value(mapping_sub_value, self,
                                                       key != PARAMETER, False)
                if restructured_value is None:
                    ExceptionCollector.appendException(
                        ToscaParametersMappingFailed(what=mapping_value))
                    return
                flat_mapping_value[key] = restructured_value

        # NOTE: the case when value has keys ERROR and REASON
        if flat_mapping_value.get(ERROR, False):
            ExceptionCollector.appendException(
                UnsupportedToscaParameterUsage(
                    what=flat_mapping_value.get(REASON).format(self=self)))

        # NOTE: the case when value has keys PARAMETER, VALUE, KEYNAME
        parameter = flat_mapping_value.get(PARAMETER)
        value = flat_mapping_value.get(VALUE)
        keyname = flat_mapping_value.get(KEYNAME)
        if value is None:
            # The case when variable is indivisible
            # This case parameter and keyname are None too or they doesn't have sense
            filled_value = dict()
            for k, v in mapping_value.items():
                filled_k = restructure_value(k, self, if_upper=False)
                filled_v = restructure_value(v, self, if_upper=False)
                filled_value[filled_k] = filled_v
            return filled_value
        if parameter is not None:
            if not isinstance(parameter, six.string_types):
                ExceptionCollector.appendException(
                    ToscaParametersMappingFailed(what=parameter))
            if parameter[:6] == '{self[' and parameter[-1] == '}':
                ExceptionCollector.appendException(
                    ToscaParametersMappingFailed(what=parameter))
            r = dict()
            r[parameter] = value

            if if_upper:
                # r[PARAMETER] = parameter
                if keyname:
                    r[KEYNAME] = keyname
            return r

        # NOTE: the case when value has keys SOURCE, PARAMETERS, EXTRA, VALUE, EXECUTOR
        source_name = flat_mapping_value.get(SOURCE)
        parameters_dict = flat_mapping_value.get(PARAMETERS)
        extra_parameters = flat_mapping_value.get(EXTRA)
        executor_name = flat_mapping_value.get(EXECUTOR)
        if source_name is not None and executor_name is not None:
            if executor_name == PYTHON_EXECUTOR:
                return execute_function(PYTHON_SOURCE_DIRECTORY, source_name,
                                        parameters_dict)
            if not CONFIGURATION_TOOLS.get(executor_name):
                ExceptionCollector.appendException(
                    UnsupportedExecutorType(what=executor_name))
            if self.get(ARTIFACTS) is None:
                self[ARTIFACTS] = []

            tool = CONFIGURATION_TOOLS[executor_name]()
            extension = tool.get_artifact_extension()

            seed(time())
            artifact_name = '_'.join([
                self[NAME], executor_name, source_name,
                str(randint(ARTIFACT_RANGE_START, ARTIFACT_RANGE_END))
            ]) + extension
            flat_mapping_value.update(name=artifact_name,
                                      configuration_tool=executor_name)
            self[ARTIFACTS].append(flat_mapping_value)
            # return the name of artifact
            return artifact_name

        ExceptionCollector.appendException(
            ToscaParametersMappingFailed(what=mapping_value))
        return

    elif isinstance(mapping_value, list):
        return [
            restructure_value(v, self, if_upper=False) for v in mapping_value
        ]

    if isinstance(mapping_value, str) and if_format_str:
        # NOTE: the process is needed because using only format function makes string from json
        mapping_value = format_value(mapping_value, self)
    return mapping_value
Exemplo n.º 37
0
def get_resulted_mapping_values(parameter, mapping_value, value, self):
    """
    Manage the case when mapping value has multiple structures in mapping_value
    :param parameter:
    :param mapping_value:
    :param value:
    :return:
    """
    mapping_value = copy.deepcopy(mapping_value)
    if isinstance(mapping_value, six.string_types):
        mapping_value = {PARAMETER: mapping_value, VALUE: "{self[value]}"}
    mapping_value_parameter = mapping_value.get(PARAMETER)
    mapping_value_value = mapping_value.get(VALUE)
    # NOTE at first check if parameter self[buffer] parameter
    if mapping_value_parameter and mapping_value_parameter[:6] == '{self[' and \
            mapping_value_parameter[-1] == '}':
        self[VALUE] = value
        self[PARAMETER] = parameter
        # The case when variable is written to the parameter self!
        # Inside string can be more self parameters
        format_parameter = mapping_value_parameter[6:-2].format(self=self)
        params_parameter = format_parameter.split('][')
        if isinstance(mapping_value_value, dict):
            if mapping_value_value.get(VALUE) and mapping_value_value.get(EXECUTOR) == PYTHON_EXECUTOR and \
                    mapping_value_value.get(SOURCE):
                mapping_value_value = execute_function(
                    PYTHON_SOURCE_DIRECTORY, mapping_value_value[SOURCE],
                    {'self': self})
        iter_value = format_value(mapping_value_value, self)
        iter_num = len(params_parameter)
        for i in range(iter_num - 1, 0, -1):
            temp_param = dict()
            temp_param[params_parameter[i]] = iter_value
            iter_value = temp_param
        self = deep_update_dict(self, {params_parameter[0]: iter_value})
        return []
    elif mapping_value_parameter:
        splitted_mapping_value_parameter = mapping_value_parameter.split(
            SEPARATOR)
        has_section = False
        for v in splitted_mapping_value_parameter:
            if v in NODE_TEMPLATE_KEYS:
                has_section = True
                break
        if not has_section:
            mapping_value_value = mapping_value.get(VALUE)
            if isinstance(mapping_value_value,
                          list) and len(mapping_value_value) > 1:
                r = []
                for v in mapping_value_value:
                    mapping_value[VALUE] = v
                    item = get_resulted_mapping_values(parameter,
                                                       mapping_value, value,
                                                       self)
                    if isinstance(item, list):
                        if len(item) == 1:
                            item = [item]
                    else:
                        item = [item]
                    r.extend(item)
                return r
            if isinstance(mapping_value_value, six.string_types):
                splitted_mapping_value_value = mapping_value_value.split(
                    SEPARATOR)
                for i in range(len(splitted_mapping_value_value)):
                    if splitted_mapping_value_value[i] in NODE_TEMPLATE_KEYS:
                        # parameter_tag = SEPARATOR.join(splitted_mapping_value_value[:i+1])
                        # value_new = SEPARATOR.join(splitted_mapping_value_value[i-1:])
                        # mapping_value[PARAMETER] = mapping_value_parameter + SEPARATOR + parameter_tag
                        # mapping_value[VALUE] = value_new
                        mapping_value[
                            PARAMETER] = mapping_value_parameter + SEPARATOR + mapping_value_value
                        mapping_value[VALUE] = "{self[value]}"
                        return dict(parameter=parameter,
                                    map=mapping_value,
                                    value=value)
            if isinstance(mapping_value_value, dict):
                # NOTE the only valid case when the value is parameter-value structure
                mapping_value_value_parameter = mapping_value_value.get(
                    PARAMETER)
                mapping_value_value_value = mapping_value_value.get(VALUE)
                if mapping_value_value_parameter and mapping_value_value_value:
                    mapping_value_value_keyname = mapping_value_value.get(
                        KEYNAME)
                    if mapping_value_value_keyname:
                        mapping_value[KEYNAME] = mapping_value_value_keyname
                    mapping_value[
                        PARAMETER] = mapping_value_parameter + SEPARATOR + mapping_value_value_parameter
                    mapping_value[VALUE] = mapping_value_value_value
                    r = get_resulted_mapping_values(parameter, mapping_value,
                                                    value, self)
                    return r

            ExceptionCollector.appendException(
                ToscaParametersMappingFailed(what=mapping_value))

    return dict(parameter=parameter, map=mapping_value, value=value)
Exemplo n.º 38
0
    def sort_nodes_by_dependency(self):
        """
        Use dependency requirement between nodes of the same type, check dependency of different types
        :param self.template_dependencies
        :param self.relationship_templates_by_name
        :param self.provider_node_names_by_priority
        :param self.provider_nodes_by_name
        :return: List of nodes sorted by priority
        """
        template_names = []
        relation_names = list(self.relationship_templates_by_name.keys())

        group_by_templ_name = dict()
        group = 0
        for priority in range(0, len(self.provider_node_names_by_priority)):
            nodes_in_priority = []
            nodes_left_next = set(self.provider_node_names_by_priority[priority])
            infinite_error = False
            while len(nodes_left_next) or infinite_error > 0:
                nodes_left = copy.copy(nodes_left_next)
                infinite_error = True
                for templ_name in nodes_left:
                    set_intersection = nodes_left_next.intersection(self.template_dependencies.get(templ_name, set()))
                    if len(set_intersection) == 0:
                        infinite_error = False
                        nodes_in_priority.append(templ_name)
                        nodes_left_next.remove(templ_name)
                        group_by_templ_name[templ_name] = group
                group += 1
            # Here we added nodes of the same priority
            if infinite_error:
                ExceptionCollector.appendException(TemplateDependencyError(
                    what="of priority " + str(priority)
                ))
            for templ_name in nodes_in_priority:
                # Add relationships for every node
                node_dependencies = self.template_dependencies.get(templ_name, set())

                for dep_name in node_dependencies:
                    if dep_name in relation_names and not dep_name in template_names:
                        template_names.append(dep_name)
                    elif dep_name in template_names:
                        pass
                    else:
                        ExceptionCollector.appendException(TemplateDependencyError(
                            what=dep_name
                        ))
                template_names.append(templ_name)

        templates = []
        for templ_name in template_names:
            templ = self.provider_nodes_by_name.get(templ_name, self.relationship_templates_by_name.get(templ_name))
            if templ is None:
                ExceptionCollector.appendException(TemplateDependencyError(
                    what=templ_name
                ))
            if group_by_templ_name.get(templ_name):
                templ.dependency_order = group_by_templ_name[templ_name]
            templates.append(templ)

        return templates
Exemplo n.º 39
0
    def _resolve_import_template(self, import_name, import_uri_def):
        short_import_notation = False
        if isinstance(import_uri_def, dict):
            self._validate_import_keys(import_name, import_uri_def)
            file_name = import_uri_def.get(self.FILE)
            repository = import_uri_def.get(self.REPOSITORY)
            repos = self.repositories.keys()
            if repository is not None:
                if repository not in repos:
                    ExceptionCollector.appendException(
                        ValidationError(
                            message=_('Repository not found: "%s"') % repository
                        )
                    )
                    return None, None, None
        else:
            file_name = import_uri_def
            repository = None
            short_import_notation = True

        if file_name is None:
            msg = _(
                "A template file name is not provided with import "
                'definition "%(import_name)s".'
            ) % {"import_name": import_name}
            log.error(msg)
            ExceptionCollector.appendException(ValidationError(message=msg))
            return None, None, None

        if toscaparser.utils.urlutils.UrlUtils.validate_url(file_name):
            # it's an absolute URL
            return self.resolver.get_url(self, repository, file_name, False)

        if not repository:
            fragment = None
            import_template = None
            if self.path:
                if toscaparser.utils.urlutils.UrlUtils.validate_url(self.path):
                    if os.path.isabs(file_name):
                        msg = _(
                            'Absolute file name "%(name)s" cannot be '
                            "used in a URL-based input template "
                            '"%(template)s".'
                        ) % {"name": file_name, "template": self.path}
                        log.error(msg)
                        ExceptionCollector.appendException(ImportError(msg))
                        return None, None, None
                    import_template = toscaparser.utils.urlutils.UrlUtils.join_url(
                        self.path, file_name
                    )
                    assert import_template
                    a_file = False
                else:
                    a_file = True
                    main_a_file = os.path.isfile(self.path)
                    if "#" in file_name:
                        file_name, sep, fragment = file_name.rpartition("#")
                    if os.path.isabs(file_name):
                        import_template = file_name
                    elif os.path.isdir(self.path):
                        import_template = os.path.join(self.path, file_name)
                    elif main_a_file:
                        if os.path.isfile(file_name):
                            import_template = file_name
                        else:
                            full_path = os.path.join(
                                os.path.dirname(os.path.abspath(self.path)), file_name
                            )
                            if os.path.isfile(full_path):
                                import_template = full_path
                            else:
                                file_path = file_name.rpartition(os.path.sep)
                                dir_path = os.path.dirname(os.path.abspath(self.path))
                                if file_path[0] != "" and dir_path.endswith(
                                    file_path[0]
                                ):
                                    import_template = os.path.join(
                                        dir_path, file_path[2]
                                    )
                                    if not os.path.isfile(import_template):
                                        msg = _(
                                            '"%(import_template)s" is'
                                            "not a valid file"
                                        ) % {"import_template": import_template}
                                        log.error(msg)
                                        ExceptionCollector.appendException
                                        (ValueError(msg))
                                else:
                                    import_template = full_path  # try anyway

            else:  # template is pre-parsed
                if os.path.isabs(file_name) and os.path.isfile(file_name):
                    a_file = True
                    import_template = file_name
                else:
                    msg = _(
                        'Relative file name "%(name)s" cannot be used '
                        "in a pre-parsed input template."
                    ) % {"name": file_name}
                    log.error(msg)
                    ExceptionCollector.appendException(ImportError(msg))
                    return None, None, None

            if not import_template:
                ExceptionCollector.appendException(
                    ImportError(_('Import "%s" is not valid.') % import_uri_def)
                )
                return None, None, None

            url_info = self.resolver.get_url(self, repository, import_template, a_file)
            if not url_info:
                log.error(_('Import "%s" is not valid.') % import_uri_def)
                ExceptionCollector.appendException(
                    ImportError(_('Import "%s" is not valid.') % import_uri_def)
                )
                return None, None, None
            return url_info[0], url_info[1], fragment

        if short_import_notation:
            log.error('Import "%(name)s" is not valid.' % import_uri_def)
            ExceptionCollector.appendException(
                ImportError(_('Import "%s" is not valid.') % import_uri_def)
            )
            return None, None, None

        assert repository
        return self._resolve_from_repository(repository, import_name, file_name)
Exemplo n.º 40
0
    def validate(self):
        if len(self.args) < 2:
            ExceptionCollector.appendException(
                ValueError(
                    _('Illegal arguments for function "{0}". Expected '
                      'arguments: "node-template-name", "req-or-cap"'
                      '(optional), "property name"').format(GET_ATTRIBUTE)))
            return
        elif len(self.args) == 2:
            self._find_node_template_containing_attribute()
        else:
            node_tpl = self._find_node_template(self.args[0])
            if node_tpl is None:
                return
            index = 2
            attrs = node_tpl.type_definition.get_attributes_def()
            found = [attrs[self.args[1]]] if self.args[1] in attrs else []
            if found:
                attr = found[0]
            else:
                index = 3
                # then check the req or caps
                attr = self._find_req_or_cap_attribute(self.args[1],
                                                       self.args[2])
                if not attr:
                    return

            value_type = attr.schema['type']
            if len(self.args) > index:
                for elem in self.args[index:]:
                    if value_type == "list":
                        if not isinstance(elem, int):
                            ExceptionCollector.appendException(
                                ValueError(
                                    _('Illegal arguments for function'
                                      ' "{0}". "{1}" Expected positive'
                                      ' integer argument').format(
                                          GET_ATTRIBUTE, elem)))
                        value_type = attr.schema['entry_schema']['type']
                    elif value_type == "map":
                        value_type = attr.schema['entry_schema']['type']
                    elif value_type in Schema.PROPERTY_TYPES:
                        ExceptionCollector.appendException(
                            ValueError(
                                _('Illegal arguments for function'
                                  ' "{0}". Unexpected attribute/'
                                  'index value "{1}"').format(
                                      GET_ATTRIBUTE, elem)))
                        return
                    else:  # It is a complex type
                        data_type = DataType(value_type)
                        props = data_type.get_properties_def()
                        found = [props[elem]] if elem in props else []
                        if found:
                            prop = found[0]
                            value_type = prop.schema['type']
                        else:
                            ExceptionCollector.appendException(
                                KeyError(
                                    _('Illegal arguments for function'
                                      ' "{0}". Attribute name "{1}" not'
                                      ' found in "{2}"').format(
                                          GET_ATTRIBUTE, elem, value_type)))
Exemplo n.º 41
0
 def _find_node_template(self, node_template_name):
     # if the node_template_name has the long format
     if isinstance(node_template_name, dict):
         # get only the node name
         if 'node' in node_template_name:
             node_template_name = node_template_name['node']
         else:
             ExceptionCollector.appendException(
                 ValueError(_(' No node name in the relationship.')))
             return
     if node_template_name == HOST:
         # Currently this is the only way to tell whether the function
         # is used within the outputs section of the TOSCA template.
         if isinstance(self.context, list):
             ExceptionCollector.appendException(
                 ValueError(
                     _('"get_attribute: [ HOST, ... ]" is not allowed in '
                       '"outputs" section of the TOSCA template.')))
             return
         node_tpl = self._find_host_containing_attribute()
         if not node_tpl:
             ExceptionCollector.appendException(
                 ValueError(
                     _('"get_attribute: [ HOST, ... ]" was used in node '
                       'template "{0}" but "{1}" was not found in '
                       'the relationship chain.').format(
                           self.context.name, HOSTED_ON)))
             return
         return node_tpl
     if node_template_name == TARGET:
         if not isinstance(self.context.type_definition, RelationshipType):
             ExceptionCollector.appendException(
                 KeyError(
                     _('"TARGET" keyword can only be used in context'
                       ' to "Relationships" target node')))
             return
         return self.context.target
     if node_template_name == SOURCE:
         if not isinstance(self.context.type_definition, RelationshipType):
             ExceptionCollector.appendException(
                 KeyError(
                     _('"SOURCE" keyword can only be used in context'
                       ' to "Relationships" source node')))
             return
         return self.context.source
     name = self.context.name \
         if node_template_name == SELF and \
         not isinstance(self.context, list) \
         else node_template_name
     for node_template in self.tosca_tpl.nodetemplates:
         if node_template.name == name or node_template.is_derived_from(
                 name):
             return node_template
     ExceptionCollector.appendException(
         KeyError(
             _('Node template "{0}" was not found.').format(
                 node_template_name)))
Exemplo n.º 42
0
 def _find_node_template(self, node_template_name):
     # if the node_template_name has the long format
     if isinstance(node_template_name, dict):
         # get only the node name
         if 'node' in node_template_name:
             node_template_name = node_template_name['node']
         else:
             ExceptionCollector.appendException(
                 ValueError(_(' No node name in the relationship.')))
             return
     if node_template_name == SELF:
         return self.context
     # enable the HOST value in the function
     if node_template_name == HOST:
         node = self._find_host_containing_property()
         if node is None:
             if len(self.args) == 2:
                 ExceptionCollector.appendException(
                     KeyError(
                         _("Property '{0}' not found on host when referenced from node template '{1}'"
                           ).format(self.args[1], self.context.name)))
             else:
                 ExceptionCollector.appendException(
                     KeyError(
                         _("Property '{0}' not found in capability/requirement"
                           " '{1}' referenced from node template '{2}'").
                         format(self.args[2], self.args[1],
                                self.context.name)))
             return None
         else:
             return node
     if node_template_name == TARGET:
         if not isinstance(self.context.type_definition, RelationshipType):
             ExceptionCollector.appendException(
                 KeyError(
                     _('"TARGET" keyword can only be used in context'
                       ' to "Relationships" target node')))
             return
         return self.context.target
     if node_template_name == SOURCE:
         if not isinstance(self.context.type_definition, RelationshipType):
             ExceptionCollector.appendException(
                 KeyError(
                     _('"SOURCE" keyword can only be used in context'
                       ' to "Relationships" source node')))
             return
         return self.context.source
     if not hasattr(self.tosca_tpl, 'nodetemplates'):
         return
     for node_template in self.tosca_tpl.nodetemplates:
         if node_template.name == node_template_name or node_template.is_derived_from(
                 node_template_name):
             return node_template
     ExceptionCollector.appendException(
         KeyError(
             _('Node template "{0}" was not found.'
               ' referenced from node template {1}').format(
                   node_template_name, self.context.name)))
Exemplo n.º 43
0
 def validate_type(self, input_type):
     if input_type not in Schema.PROPERTY_TYPES:
         ExceptionCollector.appendException(
             ValueError(_('Invalid type "%s".') % type))
Exemplo n.º 44
0
def get_structure_of_mapped_param(mapped_param,
                                  value,
                                  input_value=None,
                                  indivisible=False,
                                  if_list_type=False):
    if mapped_param is None:
        # NOTE The case when parameter was 'input_value'
        return [], None
    if input_value is None:
        input_value = value

    if isinstance(mapped_param, str):
        splitted_mapped_param = mapped_param.split(SEPARATOR)
        if splitted_mapped_param[-1] in INDIVISIBLE_KEYS:
            indivisible = True
        if not indivisible:
            if isinstance(value, list):
                r = []
                len_v = len(value)
                if len_v == 1:
                    param, _ = get_structure_of_mapped_param(mapped_param,
                                                             value[0],
                                                             input_value,
                                                             if_list_type=True)
                    return param, None

                for v in value:
                    if isinstance(v, str):
                        param, _ = get_structure_of_mapped_param(
                            SEPARATOR.join([mapped_param, v]), input_value,
                            input_value)
                    else:
                        param, _ = get_structure_of_mapped_param(
                            mapped_param, v, input_value)
                    r += param
                return r, None

            if isinstance(value, dict):
                r = dict()
                for k, v in value.items():
                    param, _ = get_structure_of_mapped_param(k, v, input_value)
                    for p in param:
                        r = deep_update_dict(r, p)
                r, _ = get_structure_of_mapped_param(mapped_param,
                                                     r,
                                                     input_value,
                                                     indivisible=True,
                                                     if_list_type=if_list_type)
                return r, None

        # NOTE: end of recursion
        structure = value
        if if_list_type:
            structure = [value]
        for i in range(len(splitted_mapped_param), 0, -1):
            structure = {splitted_mapped_param[i - 1]: structure}
        return [structure], None

    if isinstance(mapped_param, list):
        r = []
        for p in mapped_param:
            param, _ = get_structure_of_mapped_param(p, value, input_value)
            r += param
        return r, None

    if isinstance(mapped_param, dict):
        # NOTE: Assert number of keys! Always start of recursion?
        num_of_keys = len(mapped_param.keys())
        # if mapped_param.get(PARAMETER) and (num_of_keys == 2 or num_of_keys == 3 and KEYNAME in mapped_param.keys()):
        if num_of_keys == 1 or num_of_keys == 2 and KEYNAME in mapped_param.keys(
        ):
            for k, v in mapped_param.items():
                if k != PARAMETER and k != KEYNAME:
                    param, _ = get_structure_of_mapped_param(k, v, input_value)
                    if isinstance(param, tuple):
                        (param, keyname) = param
                        if mapped_param.get(KEYNAME):
                            mapped_param[KEYNAME] = keyname
                    return param, mapped_param.get(KEYNAME)
        else:
            # TODO find the cases
            assert False

    ExceptionCollector.appendException(
        ToscaParametersMappingFailed(what=mapped_param))
Exemplo n.º 45
0
    def _load_import_template(self, import_name, import_uri_def):
        """Handle custom types defined in imported template files

        This method loads the custom type definitions referenced in "imports"
        section of the TOSCA YAML template by determining whether each import
        is specified via a file reference (by relative or absolute path) or a
        URL reference.

        Possibilities:
        +----------+--------+------------------------------+
        | template | import | comment                      |
        +----------+--------+------------------------------+
        | file     | file   | OK                           |
        | file     | URL    | OK                           |
        | preparsed| file   | file must be a full path     |
        | preparsed| URL    | OK                           |
        | URL      | file   | file must be a relative path |
        | URL      | URL    | OK                           |
        +----------+--------+------------------------------+
        """
        short_import_notation = False
        if isinstance(import_uri_def, dict):
            self._validate_import_keys(import_name, import_uri_def)
            file_name = import_uri_def.get(self.FILE)
            repository = import_uri_def.get(self.REPOSITORY)
            repos = self.repositories.keys()
            if repository is not None:
                if repository not in repos:
                    ExceptionCollector.appendException(
                        InvalidPropertyValueError(
                            what=_('Repository is not found in "%s"') % repos))
        else:
            file_name = import_uri_def
            repository = None
            short_import_notation = True

        if not file_name:
            msg = (_('A template file name is not provided with import '
                     'definition "%(import_name)s".')
                   % {'import_name': import_name})
            log.error(msg)
            ExceptionCollector.appendException(ValidationError(message=msg))
            return None, None

        if toscaparser.utils.urlutils.UrlUtils.validate_url(file_name):
            return file_name, YAML_LOADER(file_name, False)
        elif not repository:
            import_template = None
            if self.path:
                if toscaparser.utils.urlutils.UrlUtils.validate_url(self.path):
                    if os.path.isabs(file_name):
                        msg = (_('Absolute file name "%(name)s" cannot be '
                                 'used in a URL-based input template '
                                 '"%(template)s".')
                               % {'name': file_name, 'template': self.path})
                        log.error(msg)
                        ExceptionCollector.appendException(ImportError(msg))
                        return None, None
                    import_template = toscaparser.utils.urlutils.UrlUtils.\
                        join_url(self.path, file_name)
                    a_file = False
                else:
                    a_file = True
                    main_a_file = os.path.isfile(self.path)

                    if main_a_file:
                        if os.path.isfile(file_name):
                            import_template = file_name
                        else:
                            full_path = os.path.join(
                                os.path.dirname(os.path.abspath(self.path)),
                                file_name)
                            if os.path.isfile(full_path):
                                import_template = full_path
                            else:
                                file_path = file_name.rpartition("/")
                                dir_path = os.path.dirname(os.path.abspath(
                                    self.path))
                                if file_path[0] != '' and dir_path.endswith(
                                        file_path[0]):
                                        import_template = dir_path + "/" +\
                                            file_path[2]
                                        if not os.path.isfile(import_template):
                                            msg = (_('"%(import_template)s" is'
                                                     'not a valid file')
                                                   % {'import_template':
                                                      import_template})
                                            log.error(msg)
                                            ExceptionCollector.appendException
                                            (ValueError(msg))
            else:  # template is pre-parsed
                if os.path.isabs(file_name) and os.path.isfile(file_name):
                    a_file = True
                    import_template = file_name
                else:
                    msg = (_('Relative file name "%(name)s" cannot be used '
                             'in a pre-parsed input template.')
                           % {'name': file_name})
                    log.error(msg)
                    ExceptionCollector.appendException(ImportError(msg))
                    return None, None

            if not import_template:
                log.error(_('Import "%(name)s" is not valid.') %
                          {'name': import_uri_def})
                ExceptionCollector.appendException(
                    ImportError(_('Import "%s" is not valid.') %
                                import_uri_def))
                return None, None
            return import_template, YAML_LOADER(import_template, a_file)

        if short_import_notation:
            log.error(_('Import "%(name)s" is not valid.') % import_uri_def)
            ExceptionCollector.appendException(
                ImportError(_('Import "%s" is not valid.') % import_uri_def))
            return None, None

        full_url = ""
        if repository:
            if self.repositories:
                for repo_name, repo_def in self.repositories.items():
                    if repo_name == repository:
                        # Remove leading, ending spaces and strip
                        # the last character if "/"
                        repo_url = ((repo_def['url']).strip()).rstrip("//")
                        full_url = repo_url + "/" + file_name

            if not full_url:
                msg = (_('referenced repository "%(n_uri)s" in import '
                         'definition "%(tpl)s" not found.')
                       % {'n_uri': repository, 'tpl': import_name})
                log.error(msg)
                ExceptionCollector.appendException(ImportError(msg))
                return None, None

        if toscaparser.utils.urlutils.UrlUtils.validate_url(full_url):
            return full_url, YAML_LOADER(full_url, False)
        else:
            msg = (_('repository url "%(n_uri)s" is not valid in import '
                     'definition "%(tpl)s".')
                   % {'n_uri': repo_url, 'tpl': import_name})
            log.error(msg)
            ExceptionCollector.appendException(ImportError(msg))
Exemplo n.º 46
0
def get_source_structure_from_facts(condition, fact_name, value, arguments,
                                    executor, target_parameter,
                                    source_parameter, source_value):
    """

    :param condition:
    :param fact_name:
    :param value:
    :param arguments:
    :param executor
    :param target_parameter:
    :param source_parameter:
    :param source_value:
    :return:
    """

    if isinstance(fact_name, six.string_types):
        fact_name_splitted = fact_name.split(SEPARATOR)
        source_name = fact_name_splitted[0]
        facts_result = "facts_result"
        if len(fact_name_splitted) > 1:
            facts_result += "[\"" + "\"][\"".join(
                fact_name_splitted[1:]) + "\"]"
        facts_result = "{{{{ " + facts_result + " }}}}"
        new_global_elements_map_total_implementation = [{
            SOURCE: source_name,
            VALUE: "facts_result",
            EXECUTOR: executor,
            PARAMETERS: {}
        }, {
            SOURCE: SET_FACT_SOURCE,
            PARAMETERS: {
                "target_objects": facts_result
            },
            VALUE: "tmp_value",
            EXECUTOR: executor
        }]
    else:
        new_global_elements_map_total_implementation = fact_name

    target_parameter_splitted = target_parameter.split(SEPARATOR)
    relationship_name = "{self[name]}_server_" + snake_case.convert(
        target_parameter_splitted[-1])

    provider = target_parameter_splitted[0]
    target_interface_name = "Target"
    target_relationship_type = SEPARATOR.join(
        [provider, RELATIONSHIPS, "DependsOn"])

    target_type = None
    target_short_parameter = None
    for i in range(len(target_parameter_splitted)):
        if target_parameter_splitted[i] in NODE_TEMPLATE_KEYS:
            target_type = SEPARATOR.join(target_parameter_splitted[:i])
            target_short_parameter = '_'.join(target_parameter_splitted[i:])
            break
    if not target_type or not target_short_parameter:
        ExceptionCollector.appendException(
            ToscaParametersMappingFailed(what=target_parameter))

    tag_operation_name = None
    if isinstance(fact_name, six.string_types):
        tag_operation_name = fact_name.replace(SEPARATOR, '_')
    elif isinstance(fact_name, dict):
        for k, v in fact_name:
            tag_operation_name = k.replace(SEPARATOR, '_')
            break
    elif isinstance(fact_name, list):
        if isinstance(fact_name[0], dict):
            for k, v in fact_name[0].items():
                tag_operation_name = k.replace(SEPARATOR, '_')
                break
        else:
            tag_operation_name = str(fact_name[0]).replace(SEPARATOR, '_')
    else:
        tag_operation_name = str(fact_name).replace(SEPARATOR, '_')

    choose_operation_name = "choose_" + tag_operation_name
    total_operation_name = "total_" + tag_operation_name

    target_total_parameter_new = SEPARATOR.join([
        target_relationship_type, INTERFACES, target_interface_name,
        total_operation_name
    ])
    target_choose_parameter_new = SEPARATOR.join([
        target_relationship_type, INTERFACES, target_interface_name,
        choose_operation_name
    ])

    new_elements_map = {
        GET_OPERATION_OUTPUT: [
            relationship_name, target_interface_name, choose_operation_name,
            value
        ]
    }
    new_global_elements_map_total = {
        PARAMETER: target_total_parameter_new,
        KEYNAME: relationship_name,
        VALUE: {
            IMPLEMENTATION: new_global_elements_map_total_implementation
        }
    }
    new_global_elements_map_choose = {
        PARAMETER: target_choose_parameter_new,
        KEYNAME: relationship_name,
        VALUE: {
            IMPLEMENTATION: [
                condition + ".yaml", {
                    SOURCE: SET_FACT_SOURCE,
                    PARAMETERS: {
                        value: "{{{{ matched_object[\"" + value + "\"] }}}}"
                    },
                    VALUE: "tmp_value",
                    EXECUTOR: executor
                }
            ],
            INPUTS: {
                "input_facts": {
                    GET_OPERATION_OUTPUT: [
                        SELF, target_interface_name, total_operation_name,
                        "target_objects"
                    ]
                },
                "input_args": arguments
            }
        }
    }
    new_global_elements_map = [{
        PARAMETER: source_parameter,
        MAP_KEY: new_global_elements_map_choose,
        VALUE: source_value
    }, {
        PARAMETER: source_parameter,
        MAP_KEY: new_global_elements_map_total,
        VALUE: source_value
    }]

    return new_elements_map, new_global_elements_map
Exemplo n.º 47
0
 def _validate_type_version(self, version):
     if version not in self.VALID_TEMPLATE_VERSIONS:
         ExceptionCollector.appendException(
             InvalidTemplateVersion(
                 what=version + ' in ' + str(self.import_def),
                 valid_versions='", "'. join(self.VALID_TEMPLATE_VERSIONS)))
Exemplo n.º 48
0
def restructure_mapping_facts(elements_map,
                              extra_elements_map=None,
                              target_parameter=None,
                              source_parameter=None,
                              source_value=None):
    """
    Function is used to restructure mapping values with the case of `facts`, `condition`, `arguments`, `value` keys
    :param elements_map:
    :param extra_elements_map:
    :param target_parameter:
    :param source_parameter:
    :param source_value:
    :return:
    """
    conditions = []
    elements_map = copy.deepcopy(elements_map)
    if not extra_elements_map:
        extra_elements_map = []

    if isinstance(elements_map, dict):
        cur_parameter = elements_map.get(PARAMETER)
        if cur_parameter and isinstance(cur_parameter, str):
            if elements_map.get(MAP_KEY):
                source_parameter = cur_parameter
                source_value = elements_map.get(VALUE)
            elif target_parameter:
                target_parameter += SEPARATOR + cur_parameter
            else:
                target_parameter = cur_parameter
        new_elements_map = dict()
        for k, v in elements_map.items():
            cur_elements, extra_elements_map, new_conditions = restructure_mapping_facts(
                v, extra_elements_map, target_parameter, source_parameter,
                source_value)
            new_elements_map.update({k: cur_elements})
            conditions.extend(new_conditions)

        if isinstance(new_elements_map.get(PARAMETER, ''), dict):
            separated_target_parameter = target_parameter.split(SEPARATOR)
            target_type = None
            target_short_parameter = None
            for i in range(len(separated_target_parameter)):
                if separated_target_parameter[i] in NODE_TEMPLATE_KEYS:
                    target_type = SEPARATOR.join(
                        separated_target_parameter[:i])
                    target_short_parameter = '_'.join(
                        separated_target_parameter[i:])
                    break
            if not target_short_parameter or not target_type:
                ExceptionCollector.appendException(
                    ToscaParametersMappingFailed(what=target_parameter))

            input_parameter = new_elements_map[PARAMETER]
            input_value = new_elements_map[VALUE]
            input_keyname = new_elements_map.get(KEYNAME)

            provider = separated_target_parameter[0]
            target_relationship_type = SEPARATOR.join(
                [provider, RELATIONSHIPS, "DependsOn"])
            relationship_name = "{self[name]}_server_" + snake_case.convert(
                separated_target_parameter[-1])

            operation_name = 'modify_' + target_short_parameter
            value_name = 'modified_' + target_short_parameter
            interface_name = 'Extra'
            new_elements_map = {
                GET_OPERATION_OUTPUT: [
                    relationship_name, interface_name, operation_name,
                    value_name
                ]
            }

            cur_target_parameter = SEPARATOR.join([
                target_relationship_type, INTERFACES, interface_name,
                operation_name
            ])
            cur_extra_element = {
                PARAMETER: source_parameter,
                MAP_KEY: {
                    PARAMETER: cur_target_parameter,
                    KEYNAME: relationship_name,
                    VALUE: {
                        IMPLEMENTATION: {
                            SOURCE: SET_FACT_SOURCE,
                            VALUE: "default_value",
                            EXECUTOR: ANSIBLE,
                            PARAMETERS: {
                                value_name:
                                "{{{{ {{ input_parameter: input_value }} }}}}"
                                # so many braces because format
                                # uses braces and replace '{{' with '{'
                            }
                        },
                        INPUTS: {
                            "input_parameter": input_parameter,
                            "input_value": input_value
                        }
                    }
                },
                VALUE: source_value
            }
            if input_keyname:
                # TODO add keyname to the parameter outside the new_elements_map
                cur_extra_element[map][KEYNAME] = input_keyname
            extra_elements_map.append(cur_extra_element)

        if_facts_structure = False
        keys = new_elements_map.keys()
        if len(keys) > 0:
            if_facts_structure = True
            for k in FACTS_MAPPING_VALUE_STRUCTURE:
                if k not in keys:
                    if_facts_structure = False
        if if_facts_structure:
            # NOTE: end of recursion
            assert target_parameter

            condition = new_elements_map[CONDITION]
            fact_name = new_elements_map[FACTS]
            value = new_elements_map[VALUE]
            arguments = new_elements_map[ARGUMENTS]
            executor = new_elements_map[EXECUTOR]
            if executor not in CONFIGURATION_TOOLS.keys():
                ExceptionCollector.appendException(
                    UnsupportedExecutorType(what=executor))
            new_elements_map, cur_extra_elements = get_source_structure_from_facts(
                condition, fact_name, value, arguments, executor,
                target_parameter, source_parameter, source_value)
            conditions.append(condition)
            extra_elements_map.extend(cur_extra_elements)

        return new_elements_map, extra_elements_map, conditions

    if isinstance(elements_map, list):
        new_elements_map = []
        for k in elements_map:
            cur_elements, extra_elements_map, new_conditions = restructure_mapping_facts(
                k, extra_elements_map, target_parameter, source_parameter,
                source_value)
            new_elements_map.append(cur_elements)
            conditions.extend(new_conditions)
        return new_elements_map, extra_elements_map, conditions

    return elements_map, extra_elements_map, conditions
Exemplo n.º 49
0
    def _get_explicit_relationship(self, req, value):
        """Handle explicit relationship

        For example,
        - req:
            node: DBMS
            relationship: tosca.relationships.HostedOn
        """
        explicit_relation = {}
        node = value.get('node') if isinstance(value, dict) else value

        if node:
            # TODO(spzala) implement look up once Glance meta data is available
            # to find a matching TOSCA node using the TOSCA types
            msg = _('Lookup by TOSCA types is not supported. '
                    'Requirement for "%s" can not be full-filled.') % self.name
            if (node in list(self.type_definition.TOSCA_DEF.keys())
                    or node in self.custom_def):
                ExceptionCollector.appendException(NotImplementedError(msg))
                return

            if node not in self.templates:
                ExceptionCollector.appendException(
                    KeyError(_('Node template "%s" was not found.') % node))
                return

            related_tpl = NodeTemplate(node, self.templates, self.custom_def)
            relationship = value.get('relationship') \
                if isinstance(value, dict) else None
            # check if it's type has relationship defined
            if not relationship:
                parent_reqs = self.type_definition.get_all_requirements()
                if parent_reqs is None:
                    ExceptionCollector.appendException(
                        ValidationError(message='parent_req is ' +
                                        str(parent_reqs)))
                else:
                    for key in req.keys():
                        for req_dict in parent_reqs:
                            if key in req_dict.keys():
                                relationship = (
                                    req_dict.get(key).get('relationship'))
                                break
            if relationship:
                found_relationship_tpl = False
                # apply available relationship templates if found
                if self.available_rel_tpls:
                    for tpl in self.available_rel_tpls:
                        if tpl.name == relationship:
                            rtype = RelationshipType(tpl.type, None,
                                                     self.custom_def)
                            explicit_relation[rtype] = related_tpl
                            self.relationship_tpl.append(tpl)
                            found_relationship_tpl = True
                # create relationship template object.
                rel_prfx = self.type_definition.RELATIONSHIP_PREFIX
                if not found_relationship_tpl:
                    if isinstance(relationship, dict):
                        relationship = relationship.get('type')
                        if relationship:
                            if self.available_rel_types and \
                               relationship in self.available_rel_types.keys():
                                pass
                            elif not relationship.startswith(rel_prfx):
                                relationship = rel_prfx + relationship
                        else:
                            ExceptionCollector.appendException(
                                MissingRequiredFieldError(
                                    what=_('"relationship" used in template '
                                           '"%s"') % related_tpl.name,
                                    required=self.TYPE))
                    for rtype in self.type_definition.relationship.keys():
                        if rtype.type == relationship:
                            explicit_relation[rtype] = related_tpl
                            related_tpl._add_relationship_template(
                                req, rtype.type)
                        elif self.available_rel_types:
                            if relationship in self.available_rel_types.keys():
                                rel_type_def = self.available_rel_types.\
                                    get(relationship)
                                if 'derived_from' in rel_type_def:
                                    super_type = \
                                        rel_type_def.get('derived_from')
                                    if not super_type.startswith(rel_prfx):
                                        super_type = rel_prfx + super_type
                                    if rtype.type == super_type:
                                        explicit_relation[rtype] = related_tpl
                                        related_tpl.\
                                            _add_relationship_template(
                                                req, rtype.type)
        return explicit_relation
Exemplo n.º 50
0
 def _validate_keys(self):
     for key in self.trigger_tpl.keys():
         if key not in SECTIONS:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Triggers "%s"' % self.name,
                                   field=key))
Exemplo n.º 51
0
def validate_string(value):
    if not isinstance(value, str):
        ExceptionCollector.appendException(
            ValueError(_('"%s" is not a string.') % value))
    return value
Exemplo n.º 52
0
 def _validate_condition(self):
     for key in self.get_condition():
         if key not in CONDITION_KEYNAMES:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Triggers "%s"' % self.name,
                                   field=key))
Exemplo n.º 53
0
def validate_numeric(value):
    if not isinstance(value, numbers.Number):
        ExceptionCollector.appendException(
            ValueError(_('"%s" is not a numeric.') % value))
    return value
Exemplo n.º 54
0
 def __init__(self, property_name, property_type, constraint):
     super(Length, self).__init__(property_name, property_type, constraint)
     if not isinstance(self.constraint_value, self.valid_types):
         ExceptionCollector.appendException(
             InvalidSchemaError(message=_('The property "length" expects '
                                          'an integer.')))
Exemplo n.º 55
0
def validate_map(value):
    if not isinstance(value, collections.Mapping):
        ExceptionCollector.appendException(
            ValueError(_('"%s" is not a map.') % value))
    return value
Exemplo n.º 56
0
    def _validate_and_load_imports(self):
        imports_names = set()

        log.debug("Imports list: {}".format(self.importslist))

        if not self.importslist:
            msg = _('"imports" keyname is defined without including '
                    'templates.')
            log.error(msg)
            ExceptionCollector.appendException(ValidationError(message=msg))
            return

        def update_import_entry(fpath, defs):
            if 'imports' in defs:
                dirname = os.path.dirname(fpath)
                imports = []
                for f in defs['imports']:
                    if isinstance(f, dict):
                        imp = f
                        if 'file' in imp:
                            fn = imp['file']
                            if fn.startswith('http') is False:
                                dname = os.path.dirname(fn)
                                imp['file'] = os.path.abspath(
                                    os.path.join(dirname, dname,
                                                 os.path.basename(fn)))
                        imports.append(imp)
                    else:
                        dname = os.path.dirname(f)
                        fn = os.path.abspath(
                            os.path.join(dirname, dname, os.path.basename(f)))
                        imports.append(fn)
                return imports

        for import_def in self.importslist:
            if isinstance(import_def, dict):
                full_file_name, custom_type, namespace_prefix = None, None, None
                if self.version == TypeValidation.STANDARD_TEMPLATE_VERSIONS[0] or \
                self.version not in TypeValidation.STANDARD_TEMPLATE_VERSIONS:
                    # Assume tosca_simple_yaml_1_0 import format
                    for import_name, import_uri in import_def.items():
                        log.debug("Import {}: {}".format(
                            import_name, import_uri))
                        if import_name in imports_names:
                            msg = (_('Duplicate import name "%s" was found.') %
                                   import_name)
                            log.error(msg)
                            ExceptionCollector.appendException(
                                ValidationError(message=msg))
                        imports_names.add(import_name)

                        full_file_name, custom_type = self._load_import_template(
                            import_name, import_uri)
                        if isinstance(import_uri, dict):
                            namespace_prefix = import_uri.get(
                                self.NAMESPACE_PREFIX)
                else:
                    full_file_name, custom_type = self._load_import_template(
                        None, import_def)
                    namespace_prefix = import_def.get(self.NAMESPACE_PREFIX)

                if custom_type:
                    imp = update_import_entry(full_file_name, custom_type)
                    if imp:
                        custom_type['imports'] = imp
                    TypeValidation(custom_type, import_def)
                    self._update_custom_def(custom_type, namespace_prefix)

            else:  # old style of imports
                log.debug("Import old style: {}".format(import_def))
                full_file_name, custom_type = self._load_import_template(
                    None, import_def)
                if custom_type:
                    imp = update_import_entry(full_file_name, custom_type)
                    if imp:
                        custom_type['imports'] = imp
                    TypeValidation(custom_type, import_def)
                    self._update_custom_def(custom_type, None)

            self._update_nested_tosca_tpls(full_file_name, custom_type)
Exemplo n.º 57
0
 def _validate_keys(self):
     for key in self.defs.keys():
         if key not in self.SECTIONS:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Relationshiptype "%s"' % self.type,
                                   field=key))
Exemplo n.º 58
0
 def validate(self):
     if len(self.args) < 1:
         ExceptionCollector.appendException(
             ValueError(
                 _('Invalid arguments for function "{0}". Expected '
                   'at least one arguments.').format(CONCAT)))
Exemplo n.º 59
0
    def load_yaml(self, importLoader, path, isFile=True, fragment=None):
        try:
            logger.trace("attempting to load YAML %s: %s",
                         "file" if isFile else "url", path)
            originalPath = path
            f = importLoader.stream

            if not f:
                try:
                    if isFile:
                        ignoreFileNotFound = self.ignoreFileNotFound
                        if ignoreFileNotFound and not os.path.isfile(path):
                            return None

                        if self.loader:
                            # show == True if file was decrypted
                            contents, show = self.loader._get_file_contents(
                                path)
                            f = six.StringIO(codecs.decode(contents))
                        else:
                            f = codecs.open(path,
                                            encoding="utf-8",
                                            errors="strict")
                    else:
                        f = urllib.request.urlopen(path)
                except urllib.error.URLError as e:
                    if hasattr(e, "reason"):
                        msg = _(
                            ('Failed to reach server "%(path)s". Reason is: ' +
                             "%(reason)s.")) % {
                                 "path": path,
                                 "reason": e.reason
                             }
                        ExceptionCollector.appendException(
                            URLException(what=msg))
                        return
                    elif hasattr(e, "code"):
                        msg = _((
                            'The server "%(path)s" couldn\'t fulfill the request. '
                            + 'Error code: "%(code)s".')) % {
                                "path": path,
                                "code": e.code
                            }
                        ExceptionCollector.appendException(
                            URLException(what=msg))
                        return
                    else:
                        raise
            with f:
                doc = yaml.load(f.read())
                if isinstance(doc, CommentedMap):
                    if self.expand:
                        includes, doc = expand_doc(doc,
                                                   cls=make_map_with_base(
                                                       doc,
                                                       get_base_dir(path)))
                        doc.includes = includes
                    doc.path = path

            if fragment and doc:
                return _refResolver.resolve_fragment(doc, fragment)
            else:
                return doc
        except:
            if path != originalPath:
                msg = f'Could not load "{path}" (originally "{originalPath}")'
            else:
                msg = f'Could not load "{path}"'
            raise UnfurlError(msg, True)
Exemplo n.º 60
0
 def _validate_targets(self, targets_list, custom_def):
     for nodetype in targets_list:
         if nodetype not in custom_def:
             ExceptionCollector.appendException(
                 InvalidTypeError(what='"%s" defined in targets for '
                                  'policy "%s"' % (nodetype, self.type)))