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 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
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
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
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]