From bda14d74cb52001f35e198b241e516e5530926f5 Mon Sep 17 00:00:00 2001 From: spzala Date: Tue, 3 Feb 2015 02:05:31 -0800 Subject: [PATCH] Separate TOSCA capabilities definition from assignment With introduction of new TOSCA capabilities like OperatingSystem, Scalability etc., TOSCA capabilites are now more mature and complex. This separation provides cleaner approach. Partially Implements: blueprint tosca-compute-os-capability Change-Id: I9af208741f01eb9ebc74c41b10d0a7bfda9d2e5d --- translator/toscalib/capabilities.py | 35 +++++++++++++++++++ .../toscalib/elements/capabilitytype.py | 34 +++++++++++------- translator/toscalib/entity_template.py | 15 +++----- translator/toscalib/functions.py | 21 ++++++----- 4 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 translator/toscalib/capabilities.py diff --git a/translator/toscalib/capabilities.py b/translator/toscalib/capabilities.py new file mode 100644 index 0000000..35e686a --- /dev/null +++ b/translator/toscalib/capabilities.py @@ -0,0 +1,35 @@ +# 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. + +from translator.toscalib.properties import Property + + +class Capability(object): + '''TOSCA built-in capabilities type.''' + + def __init__(self, name, properties, definition): + self.name = name + self._properties = properties + self.definition = definition + + @property + def properties(self): + '''Return a list of property objects.''' + properties = [] + props = self._properties + if props: + for name, value in props.items(): + for p in self.definition.properties_def: + if p.name == name: + properties.append(Property(name, value, p.schema)) + break + return properties diff --git a/translator/toscalib/elements/capabilitytype.py b/translator/toscalib/elements/capabilitytype.py index 1c8546b..1c3cdef 100644 --- a/translator/toscalib/elements/capabilitytype.py +++ b/translator/toscalib/elements/capabilitytype.py @@ -25,26 +25,34 @@ class CapabilityTypeDef(StatefulEntityType): self.defs = {} if ntype: self.defs = self.TOSCA_DEF[ctype] + self.parent_capabilities = self._get_parent_capabilities() @property def properties_def(self): - '''Return a list of property objects.''' + '''Return a list of property definition objects.''' properties = [] - props = self.entity_value(self.defs, 'properties') - if props: - if isinstance(props, dict): - for prop, schema in props.items(): - prop_val = None - for k, v in schema.items(): - if k == 'default': - prop_val = v - properties.append(PropertyDef(prop, - prop_val, schema)) + parent_properties = {} + if self.parent_capabilities: + for type, value in self.parent_capabilities.items(): + parent_properties[type] = value.get('properties') if self.properties: - for prop, value in self.properties.items(): - properties.append(PropertyDef(prop, value, None)) + for prop, schema in self.properties.items(): + properties.append(PropertyDef(prop, None, schema)) + if parent_properties: + for parent, props in parent_properties.items(): + for prop, schema in props.items(): + properties.append(PropertyDef(prop, None, schema)) return properties + def _get_parent_capabilities(self): + capabilities = {} + parent_cap = self.parent_type + if parent_cap: + while parent_cap != 'tosca.capabilities.Root': + capabilities[parent_cap] = self.TOSCA_DEF[parent_cap] + parent_cap = capabilities[parent_cap]['derived_from'] + return capabilities + @property def parent_type(self): '''Return a capability this capability is derived from.''' diff --git a/translator/toscalib/entity_template.py b/translator/toscalib/entity_template.py index 0aed9e9..3c4a69a 100644 --- a/translator/toscalib/entity_template.py +++ b/translator/toscalib/entity_template.py @@ -10,10 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. - +from translator.toscalib.capabilities import Capability from translator.toscalib.common.exception import MissingRequiredFieldError from translator.toscalib.common.exception import UnknownFieldError -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.relationshiptype import RelationshipType @@ -76,20 +75,14 @@ class EntityTemplate(object): def _create_capabilities(self): capability = [] - properties = {} - cap_type = None caps = self.type_definition.get_value(self.CAPABILITIES, self.entity_tpl) if caps: - for name, value in caps.items(): - for val in value.values(): - properties = val + for name, props in caps.items(): for c in self.type_definition.capabilities: if c.name == name: - cap_type = c.type - cap = CapabilityTypeDef(name, cap_type, - self.name, properties) - capability.append(cap) + cap = Capability(name, props['properties'], c) + capability.append(cap) return capability def _validate_properties(self, template, entitytype): diff --git a/translator/toscalib/functions.py b/translator/toscalib/functions.py index 94cf166..cba3b13 100644 --- a/translator/toscalib/functions.py +++ b/translator/toscalib/functions.py @@ -258,15 +258,20 @@ class GetProperty(Function): """Gets a node template capability property.""" for cap in node_template.capabilities: if cap.name == capability_name: - if property_name not in cap.properties: + property = None + for p in cap.properties: + if property_name == p.name: + property = p.value + break + if not property: raise KeyError(_( - "Property '{0}' not found in capability '{1}' of node " - "template '{2}' referenced from node template " - "'{3}'.").format(property_name, - capability_name, - node_template.name, - self.context.name)) - return cap.properties[property_name] + "Property '{0}' not found in capability '{1}' of node" + " template '{2}' referenced from node template" + " '{3}'.").format(property_name, + capability_name, + node_template.name, + self.context.name)) + return property msg = _("Requirement/Capability '{0}' referenced from '{1}' node " "template not found in '{2}' node template.").format( capability_name,