Remove tosca node template inheritance from node type.

Tosca node templates and node type should be separate. This will also make
tosca properties and properties definition cleaner.

Change-Id: I67cb60af1849fb02d0c982f82c8e4858aa21f2fc
Implements: blueprint tosca-nodetemplate-inheritance
This commit is contained in:
Sahdev Zala 2014-06-05 15:52:09 -05:00
parent 6369ed3166
commit 78ded47386
8 changed files with 110 additions and 93 deletions

View File

@ -14,7 +14,7 @@
# under the License.
from translator.toscalib.elements.entitytype import EntityType
from translator.toscalib.elements.properties import PropertyDef
from translator.toscalib.elements.property_definition import PropertyDef
class CapabilityTypeDef(EntityType):
@ -41,11 +41,11 @@ class CapabilityTypeDef(EntityType):
for k, v in schema.items():
if k == 'default':
prop_val = v
properties.append(PropertyDef(prop, self.type,
schema, prop_val))
properties.append(PropertyDef(prop,
prop_val, schema))
if self.properties:
for prop, value in self.properties.items():
properties.append(PropertyDef(prop, self.type, None, value))
properties.append(PropertyDef(prop, value, None))
return properties
@property

View File

@ -15,7 +15,7 @@
from translator.toscalib.elements.capabilitytype import CapabilityTypeDef
from translator.toscalib.elements.interfaces import InterfacesDef
from translator.toscalib.elements.properties import PropertyDef
from translator.toscalib.elements.property_definition import PropertyDef
from translator.toscalib.elements.relationshiptype import RelationshipType
from translator.toscalib.elements.statefulentitytype import StatefulEntityType
from translator.toscalib.utils.gettextutils import _
@ -50,10 +50,10 @@ class NodeType(StatefulEntityType):
def properties_def(self):
'''Return a list of property definition objects.'''
properties = []
props = self._get_value(PROPERTIES)
props = self.get_value(PROPERTIES)
if props:
for prop, schema in props.items():
properties.append(PropertyDef(prop, self.type, schema))
properties.append(PropertyDef(prop, None, schema))
return properties
@property
@ -69,11 +69,11 @@ class NodeType(StatefulEntityType):
requires = self.requirements
parent_node = self.parent_type
if requires is None:
requires = self._get_value(REQUIREMENTS, None, True)
requires = self.get_value(REQUIREMENTS, None, True)
parent_node = parent_node.parent_type
if parent_node:
while parent_node.type != 'tosca.nodes.Root':
req = parent_node._get_value(REQUIREMENTS, None, True)
req = parent_node.get_value(REQUIREMENTS, None, True)
requires.extend(req)
parent_node = parent_node.parent_type
if requires:
@ -107,9 +107,9 @@ class NodeType(StatefulEntityType):
typecapabilities = []
self.cap_prop = None
self.cap_type = None
caps = self._get_value(CAPABILITIES)
caps = self.get_value(CAPABILITIES)
if caps is None:
caps = self._get_value(CAPABILITIES, None, True)
caps = self.get_value(CAPABILITIES, None, True)
if caps:
cproperties = None
for name, value in caps.items():
@ -123,11 +123,11 @@ class NodeType(StatefulEntityType):
@property
def requirements(self):
return self._get_value(REQUIREMENTS)
return self.get_value(REQUIREMENTS)
@property
def interfaces(self):
return self._get_value(INTERFACES)
return self.get_value(INTERFACES)
@property
def lifecycle_inputs(self):
@ -163,7 +163,7 @@ class NodeType(StatefulEntityType):
if key == type:
return value
def _get_value(self, ndtype, defs=None, parent=None):
def get_value(self, ndtype, defs=None, parent=None):
value = None
if defs is None:
defs = self.defs
@ -177,6 +177,6 @@ class NodeType(StatefulEntityType):
break
if p and p.type == 'tosca.nodes.Root':
break
value = p._get_value(ndtype)
value = p.get_value(ndtype)
p = p.parent_type
return value

View File

@ -0,0 +1,31 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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.
class PropertyDef(object):
'''TOSCA built-in Property type.'''
def __init__(self, name, value=None, schema=None):
self.name = name
self.value = value
self.schema = schema
@property
def required(self):
if self.schema:
for prop_key, prop_vale in self.schema.items():
if prop_key == 'required' and prop_vale:
return True
return False

View File

@ -19,7 +19,7 @@ import logging
from translator.toscalib.elements.capabilitytype import CapabilityTypeDef
from translator.toscalib.elements.interfaces import InterfacesDef
from translator.toscalib.elements.nodetype import NodeType
from translator.toscalib.elements.properties import PropertyDef
from translator.toscalib.properties import Property
from translator.toscalib.utils.gettextutils import _
SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
@ -30,74 +30,70 @@ SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
log = logging.getLogger('tosca')
class NodeTemplate(NodeType):
class NodeTemplate(object):
'''Node template from a Tosca profile.'''
def __init__(self, name, nodetemplates):
super(NodeTemplate, self).__init__(nodetemplates[name]['type'])
def __init__(self, name, node_templates):
self.name = name
self.nodetemplates = nodetemplates
self.nodetemplate = nodetemplates[self.name]
self.type = self.nodetemplate['type']
self.type_properties = self.properties_def
self.type_capabilities = self.capabilities
self.type_lifecycle_ops = self.lifecycle_operations
self.type_relationship = self.relationship
self.node_type = NodeType(node_templates[name]['type'])
self.node_templates = node_templates
self.node_template = node_templates[self.name]
self.type = self.node_template['type']
self.related = {}
@property
def tpl_requirements(self):
return self._get_value(REQUIREMENTS, self.nodetemplate)
def requirements(self):
return self.node_type.get_value(REQUIREMENTS, self.node_template)
@property
def tpl_relationship(self):
tpl_relation = {}
requires = self.tpl_requirements
def relationship(self):
relation = {}
requires = self.requirements
if requires:
for r in requires:
for cap, node in r.items():
for relationship_type in self.type_relationship.keys():
if cap == relationship_type.capability_name:
rtpl = NodeTemplate(node, self.nodetemplates)
tpl_relation[relationship_type] = rtpl
return tpl_relation
for rtype in self.node_type.relationship.keys():
if cap == rtype.capability_name:
rtpl = NodeTemplate(node, self.node_templates)
relation[rtype] = rtpl
return relation
@property
def tpl_capabilities(self):
tpl_cap = []
def capabilities(self):
capability = []
properties = {}
cap_type = None
caps = self._get_value(CAPABILITIES, self.nodetemplate)
caps = self.node_type.get_value(CAPABILITIES, self.node_template)
if caps:
for name, value in caps.items():
for prop, val in value.items():
properties = val
for c in self.type_capabilities:
for c in self.node_type.capabilities:
if c.name == name:
cap_type = c.type
cap = CapabilityTypeDef(name, cap_type,
self.name, properties)
tpl_cap.append(cap)
return tpl_cap
capability.append(cap)
return capability
@property
def tpl_interfaces(self):
tpl_ifaces = []
ifaces = self._get_value(INTERFACES, self.nodetemplate)
def interfaces(self):
interfaces = []
ifaces = self.node_type.get_value(INTERFACES, self.node_template)
if ifaces:
for i in ifaces:
for name, value in ifaces.items():
for ops, val in value.items():
iface = InterfacesDef(None, name, self.name,
ops, val)
tpl_ifaces.append(iface)
return tpl_ifaces
interfaces.append(iface)
return interfaces
@property
def properties(self):
tpl_props = []
properties = self._get_value(PROPERTIES, self.nodetemplate)
props = []
properties = self.node_type.get_value(PROPERTIES, self.node_template)
requiredprop = []
for p in self.type_properties:
for p in self.node_type.properties_def:
if p.required:
requiredprop.append(p.name)
if properties:
@ -111,14 +107,16 @@ class NodeTemplate(NodeType):
"one or more required properties %(prop)s")
% {'tpl': self.name, 'prop': missingprop})
for name, value in properties.items():
prop = PropertyDef(name, self.type, None, value, self.name)
tpl_props.append(prop)
for p in self.node_type.properties_def:
if p.name == name:
prop = Property(name, value, p.schema)
props.append(prop)
else:
if requiredprop:
raise ValueError(_("Node template %(tpl)s is missing"
"one or more required properties %(prop)s")
% {'tpl': self.name, 'prop': requiredprop})
return tpl_props
return props
def _add_next(self, nodetpl, relationship):
self.related[nodetpl] = relationship
@ -126,24 +124,24 @@ class NodeTemplate(NodeType):
@property
def related_nodes(self):
if not self.related:
for relation, node in self.tpl_relationship.items():
for tpl in self.nodetemplates:
for relation, node in self.node_type.relationship.items():
for tpl in self.node_templates:
if tpl == node.type:
self.related[NodeTemplate(tpl)] = relation
return self.related.keys()
def ref_property(self, cap, cap_name, property):
requires = self.tpl_requirements
tpl_name = None
requires = self.node_type.requirements
name = None
if requires:
for r in requires:
for cap, node in r.items():
if cap == cap:
tpl_name = node
name = node
break
if tpl_name:
tpl = NodeTemplate(tpl_name, self.nodetemplates)
caps = tpl.tpl_capabilities
if name:
tpl = NodeTemplate(name, self.node_templates)
caps = tpl.capabilities
for c in caps:
if c.name == cap_name:
if c.property == property:

View File

@ -17,7 +17,7 @@
import logging
from translator.toscalib.elements.constraints import Constraint
from translator.toscalib.elements.properties import PropertyDef
from translator.toscalib.properties import Property
log = logging.getLogger('tosca')
@ -33,17 +33,17 @@ class Input(object):
@property
def description(self):
if PropertyDef.DESCRIPTION in self.schema:
if Property.DESCRIPTION in self.schema:
return self.schema['description']
@property
def default(self):
if self.PropertyDef.DEFAULT in self.schema:
if self.Property.DEFAULT in self.schema:
return self.schema['default']
@property
def constraints(self):
if PropertyDef.CONSTRAINTS in self.schema:
if Property.CONSTRAINTS in self.schema:
return self.schema['constraints']
def validate(self):
@ -52,7 +52,7 @@ class Input(object):
self.validate_constraints(self.constraints)
def validate_type(self, input_type):
if input_type not in PropertyDef.PROPERTIY_TYPES:
if input_type not in Property.PROPERTIY_TYPES:
raise ValueError(_('Invalid type %s') % type)
def validate_constraints(self, constraints):

View File

@ -16,7 +16,7 @@
from translator.toscalib.elements.constraints import Constraint
class PropertyDef(object):
class Property(object):
'''TOSCA built-in Property type.'''
PROPERTY_KEYS = (
@ -25,29 +25,17 @@ class PropertyDef(object):
'type', 'required', 'description', 'default', 'constraints'
)
PROPERTIY_TYPES = (
INTEGER,
STRING, NUMBER, BOOLEAN,
LIST
INTEGER, STRING, BOOLEAN,
FLOAT, TIMESTAMP
) = (
'integer',
'string', 'number', 'boolean',
'list'
'integer', 'string', 'boolean',
'float', 'timestamp'
)
def __init__(self, name, nodetype, schema=None, value=None, tpl_name=None):
self.name = name
self.nodetype = nodetype
self.schema = schema
def __init__(self, property_name, value, schema=None):
self.name = property_name
self.value = value
self.tpl_name = tpl_name
@property
def required(self):
if self.schema:
for prop_key, prop_vale in self.schema.items():
if prop_key == self.REQUIRED and prop_vale:
return True
return False
self.schema = schema
@property
def constraints(self):

View File

@ -75,24 +75,24 @@ class ToscaTemplateTest(TestCase):
'''Test capabilities.'''
self.assertEqual(
expected_capabilities,
sorted([p.name for p in tpl.tpl_capabilities]))
sorted([p.name for p in tpl.capabilities]))
'''Test requirements.'''
self.assertEqual(
expected_requirements, tpl.tpl_requirements)
expected_requirements, tpl.requirements)
'''Test relationship.'''
self.assertEqual(
expected_relationshp,
[x.type for x in tpl.tpl_relationship.keys()])
[x.type for x in tpl.relationship.keys()])
self.assertEqual(
expected_host,
[y.name for y in tpl.tpl_relationship.values()])
[y.name for y in tpl.relationship.values()])
'''Test interfaces.'''
self.assertEqual(
expected_interface,
[x.type for x in tpl.tpl_interfaces])
[x.type for x in tpl.interfaces])
'''Test property value'''
if tpl.name == 'server':

View File

@ -39,8 +39,8 @@ class ToscaGraph(object):
def _create(self):
for node in self.nodetemplates:
if node.tpl_relationship:
relation = node.tpl_relationship
if node.relationship:
relation = node.relationship
for relation, nodetpls in relation.items():
for tpl in self.nodetemplates:
if tpl.name == nodetpls.name: