def _relationship_templates(self):
     rel_templates = []
     tpls = self._tpl_relationship_templates()
     for name in tpls:
         tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
         rel_templates.append(tpl)
     return rel_templates
 def _relationship_templates(self):
     rel_templates = []
     tpls = self._tpl_relationship_templates()
     for name in tpls:
         exception.TOSCAException.set_context("relationships", name)
         tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
         rel_templates.append(tpl)
     exception.TOSCAException.reset_context()
     return rel_templates
Exemple #3
0
 def _get_attachment_node(self, node, suffix, volume_name):
     attach = False
     ntpl = self.nodetemplates
     for key_r, value_n in node.relationships.items():
         if key_r.is_derived_from('tosca.relationships.AttachesTo'):
             if value_n.is_derived_from('tosca.nodes.BlockStorage'):
                 if volume_name == value_n.name:
                     attach = True
         if attach:
             relationship_tpl = None
             for req in node.requirements:
                 for key, val in req.items():
                     if isinstance(val, dict):
                         if value_n.name != val.get('node'):
                             continue
                     else:
                         if value_n.name != val:
                             continue
                     attach = val
                     relship = val.get('relationship')
                     for rkey, rval in val.items():
                         if relship and isinstance(relship, dict):
                             for rkey, rval in relship.items():
                                 if rkey == 'type':
                                     relationship_tpl = val
                                     attach = rval
                                 elif rkey == 'template':
                                     rel_tpl_list = \
                                         (self.tosca.topology_template.
                                          _tpl_relationship_templates())
                                     relationship_tpl = rel_tpl_list[rval]
                                     attach = rval
                                 else:
                                     continue
                         elif isinstance(relship, str):
                             attach = relship
                             relationship_tpl = val
                             relationship_templates = \
                                 self.tosca._tpl_relationship_templates()
                             if 'relationship' in relationship_tpl and \
                                attach not in \
                                self.tosca._tpl_relationship_types() and \
                                attach in relationship_templates:
                                 relationship_tpl['relationship'] = \
                                     relationship_templates[attach]
                             break
                     if relationship_tpl:
                         rval_new = attach + "_" + str(suffix)
                         att = RelationshipTemplate(
                             relationship_tpl, rval_new,
                             self.tosca._tpl_relationship_types())
                         hot_node = ToscaBlockStorageAttachment(att, ntpl,
                                                                node.name,
                                                                volume_name
                                                                )
                         return hot_node
Exemple #4
0
 def test_relationship_template_properties(self):
     tpl_snippet = '''
     relationship_templates:
         storage_attachto:
             type: AttachesTo
             properties:
               device: test_device
     '''
     expectedmessage = _('"properties" of template "storage_attachto" is '
                         'missing required field "[\'location\']".')
     rel_template = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)
                     )['relationship_templates']
     name = list(rel_template.keys())[0]
     rel_template = RelationshipTemplate(rel_template[name], name)
     err = self.assertRaises(exception.MissingRequiredFieldError,
                             rel_template.validate)
     self.assertEqual(expectedmessage, six.text_type(err))
Exemple #5
0
 def _add_relationship_template(self, requirement, rtype, source):
     req = requirement.copy()
     req['type'] = rtype
     tpl = RelationshipTemplate(req, rtype, self.custom_def, self, source)
     self.relationship_tpl.append(tpl)
    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