Beispiel #1
0
 def __init__(self, name, template, entity_name, custom_def=None):
     self.name = name
     self.entity_tpl = template
     self.custom_def = custom_def
     self._validate_field(self.entity_tpl)
     if entity_name == 'node_type':
         self.type_definition = NodeType(self.entity_tpl['type'],
                                         custom_def)
     if entity_name == 'relationship_type':
         self.type_definition = RelationshipType(self.entity_tpl['type'],
                                                 None, custom_def)
     self._properties = None
     self._interfaces = None
     self._requirements = None
     self._capabilities = None
 def __init__(self, name, template, entity_name, custom_def=None):
     self.name = name
     self.entity_tpl = template
     self.custom_def = custom_def
     self._validate_field(self.entity_tpl)
     if entity_name == 'node_type':
         self.type_definition = NodeType(self.entity_tpl['type'],
                                         custom_def)
     if entity_name == 'relationship_type':
         self.type_definition = RelationshipType(self.entity_tpl['type'],
                                                 None, custom_def)
     self._properties = None
     self._interfaces = None
     self._requirements = None
     self._capabilities = None
Beispiel #3
0
    def relationship(self):
        '''Return a dictionary of relationships to other node types.

        This method returns a dictionary of named relationships that nodes
        of the current node type (self) can have to other nodes (of specific
        types) in a TOSCA template.

        '''
        relationship = {}
        requires = self.get_all_requirements()
        if requires:
            # NOTE(sdmonov): Check if requires is a dict.
            # If it is a dict convert it to a list of dicts.
            # This is needed because currently the code below supports only
            # lists as requirements definition. The following check will
            # make sure if a map (dict) was provided it will be converted to
            # a list before proceeding to the parsing.
            if isinstance(requires, dict):
                requires = [{key: value} for key, value in requires.items()]

            keyword = None
            node_type = None
            for req in requires:
                #get all keys in requirement
                if 'relationship' in req:
                    keys = req.keys()
                    for k in keys:
                        if k not in self.SECTIONS:
                            relation = req.get('relationship')
                            node_type = req.get(k)
                            keyword = k
                            break
                else:
                    for key, value in req.items():
                        if key == 'type':
                            continue
                        if key == 'interfaces':
                            continue
                        else:
                            # If value is a dict and has a type key we need
                            # to lookup the node type using the capability type

                            if isinstance(value, dict) and \
                                    'type' in value:
                                captype = value['type']
                                value = \
                                    self._get_node_type_by_cap(key, captype)
                            relation = self._get_relation(key, value)
                            keyword = key
                            node_type = value
                rtype = RelationshipType(relation, keyword, req)
                relatednode = NodeType(node_type, self.custom_def)
                relationship[rtype] = relatednode
        return relationship
 def __init__(self, name, template, entity_name, custom_def=None):
     self.name = name
     self.entity_tpl = template
     self.custom_def = custom_def
     self._validate_field(self.entity_tpl)
     if entity_name == 'node_type':
         self.type_definition = NodeType(self.entity_tpl['type'],
                                         custom_def)
     if entity_name == 'relationship_type':
         relationship = template.get('relationship')
         type = None
         if relationship and isinstance(relationship, dict):
             type = relationship.get('type')
         elif isinstance(relationship, str):
             type = self.entity_tpl['relationship']
         else:
             type = self.entity_tpl['type']
         self.type_definition = RelationshipType(type,
                                                 None, custom_def)
     self._properties = None
     self._interfaces = None
     self._requirements = None
     self._capabilities = None
Beispiel #5
0
 def relationship(self):
     '''returns a dictionary containing relationship to a particular
      node type '''
     relationship = {}
     requirs = self.requirements
     if requirs is None:
         requirs = self._get_value(REQUIREMENTS, None, True)
     if requirs:
         for req in requirs:
             for x, y in req.iteritems():
                 relation = self._get_relation(x, y)
                 rtype = RelationshipType(relation, x)
                 relatednode = NodeType(y)
                 relationship[rtype] = relatednode
     return relationship
Beispiel #6
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 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 are 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):
                raise NotImplementedError(msg)
            related_tpl = NodeTemplate(node, self.templates, self.custom_def)
            relationship = value.get('relationship')
            if relationship:
                found_relationship_tpl = False
                #apply available relationship templates if found
                for tpl in self.available_rel_tpls:
                    if tpl.name == relationship:
                        rtype = RelationshipType(tpl.type)
                        explicit_relation[rtype] = related_tpl
                        self.relationship_tpl.append(tpl)
                        found_relationship_tpl = True
                #create relationship template object.
                if not found_relationship_tpl:
                    if isinstance(relationship, dict):
                        relationship = relationship.get('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)
        return explicit_relation
Beispiel #7
0
class EntityTemplate(object):
    '''Base class for TOSCA templates.'''

    SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
                INTERFACES, CAPABILITIES, TYPE) = \
               ('derived_from', 'properties', 'requirements', 'interfaces',
                'capabilities', 'type')

    def __init__(self, name, template, entity_name, custom_def=None):
        self.name = name
        self.entity_tpl = template
        self.custom_def = custom_def
        self._validate_field(self.entity_tpl)
        if entity_name == 'node_type':
            self.type_definition = NodeType(self.entity_tpl['type'],
                                            custom_def)
        if entity_name == 'relationship_type':
            self.type_definition = RelationshipType(self.entity_tpl['type'],
                                                    None, custom_def)
        self._properties = None
        self._interfaces = None
        self._requirements = None
        self._capabilities = None

    @property
    def type(self):
        return self.type_definition.type

    @property
    def requirements(self):
        if self._requirements is None:
            self._requirements = self.type_definition.get_value(
                self.REQUIREMENTS, self.entity_tpl) or []
        return self._requirements

    def get_properties_objects(self):
        '''Return properties objects for this template.'''
        if self._properties is None:
            self._properties = self._create_properties()
        return self._properties

    def get_properties(self):
        '''Return a dictionary of property name-object pairs.'''
        return {prop.name: prop for prop in self.get_properties_objects()}

    def get_property_value(self, name):
        '''Return the value of a given property name.'''
        props = self.get_properties()
        if props and name in props.keys():
            return props[name].value

    @property
    def interfaces(self):
        if self._interfaces is None:
            self._interfaces = self._create_interfaces()
        return self._interfaces

    def get_capabilities_objects(self):
        '''Return capabilities objects for this template.'''
        if not self._capabilities:
            self._capabilities = self._create_capabilities()
        return self._capabilities

    def get_capabilities(self):
        '''Return a dictionary of capability name-object pairs.'''
        return {cap.name: cap for cap in self.get_capabilities_objects()}

    def _create_capabilities(self):
        capability = []
        caps = self.type_definition.get_value(self.CAPABILITIES,
                                              self.entity_tpl)
        if caps:
            for name, props in caps.items():
                capabilities = self.type_definition.get_capabilities()
                if name in capabilities.keys():
                    c = capabilities[name]
                    cap = Capability(name, props['properties'], c)
                    capability.append(cap)
        return capability

    def _validate_properties(self, template, entitytype):
        properties = entitytype.get_value(self.PROPERTIES, template)
        self._common_validate_properties(entitytype, properties)

    def _validate_capabilities(self):
        type_capabilities = self.type_definition.get_capabilities()
        allowed_caps = \
            type_capabilities.keys() if type_capabilities else []
        capabilities = self.type_definition.get_value(self.CAPABILITIES,
                                                      self.entity_tpl)
        if capabilities:
            self._common_validate_field(capabilities, allowed_caps,
                                        'Capabilities')
            self._validate_capabilities_properties(capabilities)

    def _validate_capabilities_properties(self, capabilities):
        for cap, props in capabilities.items():
            capabilitydef = self.get_capability(cap).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)
                        raise ValidationError(message=err_msg)

    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:
                raise MissingRequiredFieldError(
                    what='Properties of template %s' % self.name,
                    required=missingprop)
        else:
            if required_props:
                raise MissingRequiredFieldError(
                    what='Properties of template %s' % self.name,
                    required=missingprop)

    def _validate_field(self, template):
        if not isinstance(template, dict):
            raise MissingRequiredFieldError(what='Template %s' % self.name,
                                            required=self.TYPE)
        try:
            template[self.TYPE]
        except KeyError:
            raise MissingRequiredFieldError(what='Template %s' % self.name,
                                            required=self.TYPE)

    def _common_validate_field(self, schema, allowedlist, section):
        for name in schema:
            if name not in allowedlist:
                raise UnknownFieldError(
                    what='%(section)s of template %(nodename)s' % {
                        'section': section,
                        'nodename': self.name
                    },
                    field=name)

    def _create_properties(self):
        props = []
        properties = self.type_definition.get_value(self.PROPERTIES,
                                                    self.entity_tpl) or {}
        for name, value in properties.items():
            props_def = self.type_definition.get_properties_def()
            if props_def and name in props_def:
                prop = Property(name, value, props_def[name].schema,
                                self.custom_def)
                props.append(prop)
        for p in self.type_definition.get_properties_def_objects():
            if p.default is not None and p.name not in properties.keys():
                prop = Property(p.name, p.default, p.schema, self.custom_def)
                props.append(prop)
        return props

    def _create_interfaces(self):
        interfaces = []
        type_interfaces = self.type_definition.get_value(
            self.INTERFACES, self.entity_tpl)
        if type_interfaces:
            for interface_type, value in type_interfaces.items():
                for op, op_def in value.items():
                    iface = InterfacesDef(self.type_definition,
                                          interfacetype=interface_type,
                                          node_template=self,
                                          name=op,
                                          value=op_def)
                    interfaces.append(iface)
        return interfaces

    def get_capability(self, name):
        """Provide named capability

        :param name: name of capability
        :return: capability object if found, None otherwise
        """
        caps = self.get_capabilities()
        if caps and name in caps.keys():
            return caps[name]
class EntityTemplate(object):
    '''Base class for TOSCA templates.'''

    SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
                INTERFACES, CAPABILITIES, TYPE) = \
               ('derived_from', 'properties', 'requirements', 'interfaces',
                'capabilities', 'type')

    def __init__(self, name, template, entity_name, custom_def=None):
        self.name = name
        self.entity_tpl = template
        self.custom_def = custom_def
        self._validate_field(self.entity_tpl)
        if entity_name == 'node_type':
            self.type_definition = NodeType(self.entity_tpl['type'],
                                            custom_def)
        if entity_name == 'relationship_type':
            relationship = template.get('relationship')
            type = None
            if relationship and isinstance(relationship, dict):
                type = relationship.get('type')
            elif isinstance(relationship, str):
                type = self.entity_tpl['relationship']
            else:
                type = self.entity_tpl['type']
            self.type_definition = RelationshipType(type,
                                                    None, custom_def)
        self._properties = None
        self._interfaces = None
        self._requirements = None
        self._capabilities = None

    @property
    def type(self):
        return self.type_definition.type

    @property
    def requirements(self):
        if self._requirements is None:
            self._requirements = self.type_definition.get_value(
                self.REQUIREMENTS,
                self.entity_tpl) or []
        return self._requirements

    def get_properties_objects(self):
        '''Return properties objects for this template.'''
        if self._properties is None:
            self._properties = self._create_properties()
        return self._properties

    def get_properties(self):
        '''Return a dictionary of property name-object pairs.'''
        return {prop.name: prop
                for prop in self.get_properties_objects()}

    def get_property_value(self, name):
        '''Return the value of a given property name.'''
        props = self.get_properties()
        if props and name in props.keys():
            return props[name].value

    @property
    def interfaces(self):
        if self._interfaces is None:
            self._interfaces = self._create_interfaces()
        return self._interfaces

    def get_capabilities_objects(self):
        '''Return capabilities objects for this template.'''
        if not self._capabilities:
            self._capabilities = self._create_capabilities()
        return self._capabilities

    def get_capabilities(self):
        '''Return a dictionary of capability name-object pairs.'''
        return {cap.name: cap
                for cap in self.get_capabilities_objects()}

    def _create_capabilities(self):
        capability = []
        caps = self.type_definition.get_value(self.CAPABILITIES,
                                              self.entity_tpl)
        if caps:
            for name, props in caps.items():
                capabilities = self.type_definition.get_capabilities()
                if name in capabilities.keys():
                    c = capabilities[name]
                    cap = Capability(name, props['properties'], c)
                    capability.append(cap)
        return capability

    def _validate_properties(self, template, entitytype):
        properties = entitytype.get_value(self.PROPERTIES, template)
        self._common_validate_properties(entitytype, properties)

    def _validate_capabilities(self):
        type_capabilities = self.type_definition.get_capabilities()
        allowed_caps = \
            type_capabilities.keys() if type_capabilities else []
        capabilities = self.type_definition.get_value(self.CAPABILITIES,
                                                      self.entity_tpl)
        if capabilities:
            self._common_validate_field(capabilities, allowed_caps,
                                        'Capabilities')
            self._validate_capabilities_properties(capabilities)

    def _validate_capabilities_properties(self, capabilities):
        for cap, props in capabilities.items():
            capabilitydef = self.get_capability(cap).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)
                        raise ValidationError(message=err_msg)

    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:
                raise MissingRequiredFieldError(
                    what='Properties of template %s' % self.name,
                    required=missingprop)
        else:
            if required_props:
                raise MissingRequiredFieldError(
                    what='Properties of template %s' % self.name,
                    required=missingprop)

    def _validate_field(self, template):
        if not isinstance(template, dict):
            raise 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:
            raise MissingRequiredFieldError(
                what='Template %s' % self.name, required=self.TYPE)

    def _common_validate_field(self, schema, allowedlist, section):
        for name in schema:
            if name not in allowedlist:
                raise UnknownFieldError(
                    what='%(section)s of template %(nodename)s'
                    % {'section': section, 'nodename': self.name},
                    field=name)

    def _create_properties(self):
        props = []
        properties = self.type_definition.get_value(self.PROPERTIES,
                                                    self.entity_tpl) or {}
        for name, value in properties.items():
            props_def = self.type_definition.get_properties_def()
            if props_def and name in props_def:
                prop = Property(name, value,
                                props_def[name].schema, self.custom_def)
                props.append(prop)
        for p in self.type_definition.get_properties_def_objects():
            if p.default is not None and p.name not in properties.keys():
                prop = Property(p.name, p.default, p.schema, self.custom_def)
                props.append(prop)
        return props

    def _create_interfaces(self):
        interfaces = []
        type_interfaces = self.type_definition.get_value(self.INTERFACES,
                                                         self.entity_tpl)
        if type_interfaces:
            for interface_type, value in type_interfaces.items():
                for op, op_def in value.items():
                    iface = InterfacesDef(self.type_definition,
                                          interfacetype=interface_type,
                                          node_template=self,
                                          name=op,
                                          value=op_def)
                    interfaces.append(iface)
        return interfaces

    def get_capability(self, name):
        """Provide named capability

        :param name: name of capability
        :return: capability object if found, None otherwise
        """
        caps = self.get_capabilities()
        if caps and name in caps.keys():
            return caps[name]