Files
deb-python-tosca-parser/toscaparser/nodetemplate.py
spzala 0a1568ba38 Redefine respository structure
Change the file structure to make appropriate for stand alone parser.

Change-Id: I6d5259b61b1cd82949262fee4930fa66703ad036
2015-08-25 08:18:39 -07:00

219 lines
9.9 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from toscaparser.common.exception import TypeMismatchError
from toscaparser.common.exception import UnknownFieldError
from toscaparser.elements.interfaces import CONFIGURE
from toscaparser.elements.interfaces import CONFIGURE_SHORTNAME
from toscaparser.elements.interfaces import InterfacesDef
from toscaparser.elements.interfaces import LIFECYCLE
from toscaparser.elements.interfaces import LIFECYCLE_SHORTNAME
from toscaparser.elements.relationshiptype import RelationshipType
from toscaparser.entity_template import EntityTemplate
from toscaparser.relationship_template import RelationshipTemplate
from toscaparser.utils.gettextutils import _
log = logging.getLogger('tosca')
class NodeTemplate(EntityTemplate):
'''Node template from a Tosca profile.'''
def __init__(self, name, node_templates, custom_def=None,
available_rel_tpls=None, available_rel_types=None):
super(NodeTemplate, self).__init__(name, node_templates[name],
'node_type',
custom_def)
self.templates = node_templates
self._validate_fields(node_templates[name])
self.custom_def = custom_def
self.related = {}
self.relationship_tpl = []
self.available_rel_tpls = available_rel_tpls
self.available_rel_types = available_rel_types
self._relationships = {}
@property
def relationships(self):
if not self._relationships:
requires = self.requirements
if requires:
for r in requires:
for r1, value in r.items():
explicit = self._get_explicit_relationship(r, value)
if explicit:
for key, value in explicit.items():
self._relationships[key] = value
return self._relationships
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 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 isinstance(value, dict) else None
# check if it's type has relationship defined
if not relationship:
parent_reqs = self.type_definition.get_all_requirements()
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
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 self.available_rel_types and \
relationship in self.available_rel_types.keys():
pass
elif not relationship.startswith(rel_prfx):
relationship = rel_prfx + relationship
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
def _add_relationship_template(self, requirement, rtype):
req = requirement.copy()
req['type'] = rtype
tpl = RelationshipTemplate(req, rtype, None)
self.relationship_tpl.append(tpl)
def get_relationship_template(self):
return self.relationship_tpl
def _add_next(self, nodetpl, relationship):
self.related[nodetpl] = relationship
@property
def related_nodes(self):
if not self.related:
for relation, node in self.type_definition.relationship.items():
for tpl in self.templates:
if tpl == node.type:
self.related[NodeTemplate(tpl)] = relation
return self.related.keys()
def validate(self, tosca_tpl=None):
self._validate_capabilities()
self._validate_requirements()
self._validate_properties(self.entity_tpl, self.type_definition)
self._validate_interfaces()
for prop in self.get_properties_objects():
prop.validate()
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):
raise 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)
allowed_reqs.append(r1)
self._common_validate_field(req, allowed_reqs, 'Requirements')
def _validate_requirements_keys(self, requirement):
for key in requirement.keys():
if key not in self.REQUIREMENTS_SECTION:
raise UnknownFieldError(
what='Requirements of template %s' % self.name,
field=key)
def _validate_interfaces(self):
ifaces = self.type_definition.get_value(self.INTERFACES,
self.entity_tpl)
if ifaces:
for i in 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_confiure_operations,
'Interfaces')
else:
raise UnknownFieldError(
what='Interfaces of template %s' % self.name,
field=name)
def _validate_fields(self, nodetemplate):
for name in nodetemplate.keys():
if name not in self.SECTIONS:
raise UnknownFieldError(what='Node template %s'
% self.name, field=name)