Esempio n. 1
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))
Esempio n. 2
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))
Esempio n. 3
0
 def _validate_field(self, template):
     if not isinstance(template, dict):
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Template "%s"' % self.name,
                                       required=self.TYPE))
     try:
         template[self.TYPE]
     except KeyError:
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Template "%s"' % self.name,
                                       required=self.TYPE))
 def _validate_field(self):
     if not isinstance(self.attrs, dict):
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Output "%s"' % self.name,
                                       required=self.VALUE))
     if self.value is None:
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Output "%s"' % self.name,
                                       required=self.VALUE))
     for name in self.attrs:
         if name not in self.OUTPUTFIELD:
             ExceptionCollector.appendException(
                 UnknownFieldError(what='Output "%s"' % self.name,
                                   field=name))
Esempio n. 5
0
    def __init__(self, name, values):
        self.name = name
        self.tpl = values
        # TOSCA 1.0 backwards compatibility:
        if isinstance(self.tpl, six.string_types):
            tpl = dict(url=self.tpl)
        else:
            tpl = self.tpl
        if isinstance(tpl, dict):
            if URL not in tpl.keys():
                ExceptionCollector.appendException(
                    MissingRequiredFieldError(what=_('repository "%s"') %
                                              self.name,
                                              required='url'))
            for key, value in tpl.items():
                if key not in SECTIONS:
                    ExceptionCollector.appendException(
                        UnknownFieldError(what=_('repository "%s"') % name,
                                          field=key))
                setattr(self, key, value)

            self.validate()
            self.hostname = urlparse(self.url).hostname
        else:
            ExceptionCollector.appendException(
                TypeMismatchError(what=_('repository "%s"') % self.name,
                                  type="dict"))
    def _validate_type(self):
        """validate the node_type of substitution mappings."""
        if self.node:
            node = self.topology.node_templates.get(self.node)
            if not node:
                ExceptionCollector.appendException(
                    ValidationError(message=_(
                        'Unknown node "%s" declared on substitution_mappings')
                                    % self.node))
            self.node_definition = node.type_definition
            return

        node_type = self.sub_mapping_def.get(self.NODE_TYPE)
        if not node_type:
            ExceptionCollector.appendException(
                MissingRequiredFieldError(
                    what=_('SubstitutionMappings used in topology_template'),
                    required=self.NODE_TYPE))
            return False

        node_type_def = self.custom_defs.get(node_type)
        if not node_type_def:
            ExceptionCollector.appendException(
                InvalidNodeTypeError(what=node_type))
            return False
        self.node_definition = NodeType(self.node_type, self.custom_defs)
        return True
Esempio n. 7
0
 def _validate_required_fields(self, template):
     if "file" not in template:
         ExceptionCollector.appendException(
             MissingRequiredFieldError(
                 what='Artifact "%s"' % self.name, required="file"
             )
         )
Esempio n. 8
0
 def _validate_field(self, template):
     if not isinstance(template, dict):
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Template "%s"' % self.name,
                                       required=self.TYPE))
     try:
         relationship = template.get('relationship')
         if relationship and not isinstance(relationship, str):
             relationship[self.TYPE]
         elif isinstance(relationship, str):
             template['relationship']
         else:
             template[self.TYPE]
     except KeyError:
         ExceptionCollector.appendException(
             MissingRequiredFieldError(what='Template "%s"' % self.name,
                                       required=self.TYPE))
Esempio n. 9
0
 def __init__(self, repositories, values):
     self.name = repositories
     self.reposit = values
     if isinstance(self.reposit, dict):
         if 'url' not in self.reposit.keys():
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(what=_('Repository "%s"') %
                                           self.name,
                                           required='url'))
         self.url = self.reposit['url']
     self.load_and_validate(self.name, self.reposit)
    def _validate_type(self):
        """validate the node_type of substitution mappings."""
        node_type = self.sub_mapping_def.get(self.NODE_TYPE)
        if not node_type:
            ExceptionCollector.appendException(
                MissingRequiredFieldError(
                    what=_('SubstitutionMappings used in topology_template'),
                    required=self.NODE_TYPE))

        node_type_def = self.custom_defs.get(node_type)
        if not node_type_def:
            ExceptionCollector.appendException(
                InvalidNodeTypeError(what=node_type))
Esempio n. 11
0
 def validate_inline_artifact(self, inline_artifact):
     if isinstance(inline_artifact, dict):
         if "file" not in inline_artifact:
             ExceptionCollector.appendException(
                 MissingRequiredFieldError(what="inline artifact in " +
                                           self._msg,
                                           required="file"))
         for key in inline_artifact:
             if key not in INLINE_ARTIFACT_DEF_RESERVED_WORDS:
                 what = ("inline artifact in " + self._msg +
                         " contains invalid field " + key)
                 ExceptionCollector.appendException(
                     ValidationError(message=what))
Esempio n. 12
0
    def _validate_field(self):
        version = self._tpl_version()
        if not version:
            ExceptionCollector.appendException(
                MissingRequiredFieldError(what='Template',
                                          required=DEFINITION_VERSION))
        else:
            self._validate_version(version)
            self.version = version

        for name in self.tpl:
            if name not in SECTIONS and name not in SPECIAL_SECTIONS:
                ExceptionCollector.appendException(
                    UnknownFieldError(what='Template', field=name))
Esempio n. 13
0
 def _validate_import_keys(self, import_name, import_uri_def):
     if self.FILE not in import_uri_def.keys():
         log.warning(_('Missing keyname "file" in import "%(name)s".')
                     % {'name': import_name})
         ExceptionCollector.appendException(
             MissingRequiredFieldError(
                 what='Import of template "%s"' % import_name,
                 required=self.FILE))
     for key in import_uri_def.keys():
         if key not in self.IMPORTS_SECTION:
             log.warning(_('Unknown keyname "%(key)s" error in '
                           'imported definition "%(def)s".')
                         % {'key': key, 'def': import_name})
             ExceptionCollector.appendException(
                 UnknownFieldError(
                     what='Import of template "%s"' % import_name,
                     field=key))
Esempio n. 14
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
                            tpl.target = related_tpl
                            tpl.source = self
                            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, self)
                        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, self)
        return explicit_relation
Esempio n. 15
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
        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
            for value_key in list(self.value.keys()):
                if value_key not in allowed_props:
                    ExceptionCollector.appendException(
                        UnknownFieldError(what=(_('Data value of type "%s"') %
                                                self.datatype.type),
                                          field=value_key))

            # 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:
                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
                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 prop_schema.constraints:
                    for constraint in prop_schema.constraints:
                        if isinstance(value, list):
                            for val in value:
                                constraint.validate(val)
                        else:
                            constraint.validate(value)

        return self.value
Esempio n. 16
0
    def _get_explicit_relationship(self, req):
        """Handle explicit relationship

        For example,
        - req:
            node: DBMS
            relationship: tosca.relationships.HostedOn

        Returns a requirements dict and either RelationshipTemplate or None if there was a validation error.

        If no relationship was either assigned or defined by the node's type definition,
        one with type "tosca.relationships.Root" will be returned.
        """
        name, value = next(iter(req.items()))  # list only has one item
        typeReqDef = self._getRequirementDefinition(name)
        reqDef = typeReqDef.copy()
        if isinstance(value, dict):
            # see 3.8.2 Requirement assignment p. 140 for value
            reqDef.update(value)
        else:
            reqDef['node'] = value

        relationship = reqDef['relationship']
        relTpl = None
        type = None
        if isinstance(relationship, dict):
            type = relationship.get('type')
            if not type:
                ExceptionCollector.appendException(
                    MissingRequiredFieldError(
                        what=_('"relationship" used in template '
                               '"%s"') % self.name,
                        required=self.TYPE))
                return reqDef, None
        elif (relationship in self.custom_def
              or relationship in self.type_definition.RELATIONSHIP_TYPE):
            type = relationship
            relationship = dict(type=relationship)  # it's the name of a type
        else:
            # it's the name of a relationship template
            for tpl in self.available_rel_tpls:
                if tpl.name == relationship:
                    type = tpl.type
                    relTpl = tpl
                    break
            else:
                ExceptionCollector.appendException(
                    ValidationError(
                        message=
                        _('Relationship template "%(relationship)s" was not found'
                          ' for requirement "%(rname)s" of node "%(nname)s".')
                        % {
                            'relationship': relationship,
                            'rname': name,
                            'nname': self.name
                        }))
                return reqDef, None

        if not relTpl:
            assert isinstance(
                relationship,
                dict) and relationship['type'] == type, (relationship, type)
            relTpl = RelationshipTemplate(relationship, name, self.custom_def)
        relTpl.source = self

        node = reqDef.get('node')
        node_filter = reqDef.get('node_filter')
        related_node = None
        related_capability = None
        if node:
            related_node = self.topology_template.node_templates.get(node)
            if related_node:
                capabilities = relTpl.get_matching_capabilities(
                    related_node, reqDef.get('capability'))
                if not capabilities:
                    if 'capability' in reqDef:
                        ExceptionCollector.appendException(
                            ValidationError(
                                message=
                                _('No matching capability "%(cname)s" found'
                                  ' on target node "%(tname)s" for requirement "%(rname)s" of node "%(nname)s".'
                                  ) % {
                                      'rname': name,
                                      'nname': self.name,
                                      'cname': reqDef['capability'],
                                      'tname': related_node.name
                                  }))
                        return reqDef, None
                    else:
                        ExceptionCollector.appendException(
                            ValidationError(
                                message=
                                _('No capability with a matching target type found'
                                  ' on target node "%(tname)s" for requirement "%(rname)s" of node "%(nname)s".'
                                  ) % {
                                      'rname': name,
                                      'nname': self.name,
                                      'tname': related_node.name
                                  }))
                        return reqDef, None
                related_capability = capabilities[0]  # first one is best match
        elif 'capability' not in reqDef and not relTpl.type_definition.valid_target_types and not node_filter:
            ExceptionCollector.appendException(
                ValidationError(
                    message=
                    'requirement "%s" of node "%s" must specify a node_filter, a node or a capability'
                    % (name, self.name)))
            return reqDef, None

        if not related_node:
            # check if "node" is a node type
            for nodeTemplate in self.topology_template.node_templates.values():
                found = None
                found_cap = None
                # check if node name is node type
                if not node or nodeTemplate.is_derived_from(node):
                    capability = reqDef.get('capability')
                    # should have already returned an error if this assertion is false
                    if capability or relTpl.type_definition.valid_target_types:
                        capabilities = relTpl.get_matching_capabilities(
                            nodeTemplate, capability)
                        if capabilities:
                            found = nodeTemplate
                            found_cap = capabilities[0]  # first is best match
                        else:
                            continue  # didn't match capabilities, don't check node_filter
                    if node_filter:
                        if nodeTemplate.match_nodefilter(node_filter):
                            found = nodeTemplate
                        else:
                            continue

                if found:
                    if related_node:
                        if "default" in found.directives:
                            continue
                        elif "default" in related_node.directives:
                            related_node = found
                            related_capability = found_cap
                        else:
                            ExceptionCollector.appendException(
                                ValidationError(
                                    message=
                                    'requirement "%s" of node ""%s" is ambiguous, targets more than one template: "%s" and "%s"'
                                    % (name, self.name, related_node.name,
                                       found.name)))
                            return reqDef, None
                    else:
                        related_node = found
                        related_capability = found_cap

        if related_node:
            # if relTpl is in available_rel_tpls what if target and source are already assigned?
            relTpl.target = related_node
            relTpl.capability = related_capability
            related_node.relationship_tpl.append(relTpl)
        else:
            ExceptionCollector.appendException(
                ValidationError(message=_(
                    'No matching target template found'
                    ' for requirement "%(rname)s" of node "%(nname)s".') % {
                        'rname': name,
                        'nname': self.name
                    }))
            return reqDef, None
        return reqDef, relTpl