Support of nested properties and indexes in get_property function
Change-Id: Ib2f53047cc32a7a0913ee364f1405b8559b11f6c Related-Bug: 1527206
This commit is contained in:
parent
2330571e72
commit
5014b33690
@ -239,10 +239,11 @@ class GetProperty(Function):
|
|||||||
* { get_property: [ mysql_server, port ] }
|
* { get_property: [ mysql_server, port ] }
|
||||||
* { get_property: [ SELF, db_port ] }
|
* { get_property: [ SELF, db_port ] }
|
||||||
* { get_property: [ SELF, database_endpoint, port ] }
|
* { get_property: [ SELF, database_endpoint, port ] }
|
||||||
|
* { get_property: [ SELF, database_endpoint, port, 1 ] }
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if len(self.args) < 2 or len(self.args) > 3:
|
if len(self.args) < 2:
|
||||||
ExceptionCollector.appendException(
|
ExceptionCollector.appendException(
|
||||||
ValueError(_(
|
ValueError(_(
|
||||||
'Expected arguments: "node-template-name", "req-or-cap" '
|
'Expected arguments: "node-template-name", "req-or-cap" '
|
||||||
@ -255,15 +256,31 @@ class GetProperty(Function):
|
|||||||
prop = found_prop.value
|
prop = found_prop.value
|
||||||
if not isinstance(prop, Function):
|
if not isinstance(prop, Function):
|
||||||
get_function(self.tosca_tpl, self.context, prop)
|
get_function(self.tosca_tpl, self.context, prop)
|
||||||
elif len(self.args) == 3:
|
elif len(self.args) >= 3:
|
||||||
get_function(self.tosca_tpl,
|
# do not use _find_property to avoid raise KeyError
|
||||||
self.context,
|
# if the prop is not found
|
||||||
self._find_req_or_cap_property(self.args[1],
|
# First check if there is property with this name
|
||||||
self.args[2]))
|
node_tpl = self._find_node_template(self.args[0])
|
||||||
else:
|
props = node_tpl.get_properties() if node_tpl else []
|
||||||
ExceptionCollector.appendException(
|
index = 2
|
||||||
NotImplementedError(_(
|
found = [props[self.args[1]]] if self.args[1] in props else []
|
||||||
'Nested properties are not supported.')))
|
if found:
|
||||||
|
property_value = found[0].value
|
||||||
|
else:
|
||||||
|
index = 3
|
||||||
|
# then check the req or caps
|
||||||
|
property_value = self._find_req_or_cap_property(self.args[1],
|
||||||
|
self.args[2])
|
||||||
|
if len(self.args) > index:
|
||||||
|
for elem in self.args[index:]:
|
||||||
|
if isinstance(property_value, list):
|
||||||
|
int_elem = int(elem)
|
||||||
|
property_value = self._get_index_value(property_value,
|
||||||
|
int_elem)
|
||||||
|
else:
|
||||||
|
property_value = self._get_attribute_value(
|
||||||
|
property_value,
|
||||||
|
elem)
|
||||||
|
|
||||||
def _find_req_or_cap_property(self, req_or_cap, property_name):
|
def _find_req_or_cap_property(self, req_or_cap, property_name):
|
||||||
node_tpl = self._find_node_template(self.args[0])
|
node_tpl = self._find_node_template(self.args[0])
|
||||||
@ -341,6 +358,52 @@ class GetProperty(Function):
|
|||||||
'Node template "{0}" was not found.'
|
'Node template "{0}" was not found.'
|
||||||
).format(node_template_name)))
|
).format(node_template_name)))
|
||||||
|
|
||||||
|
def _get_index_value(self, value, index):
|
||||||
|
if isinstance(value, list):
|
||||||
|
if index < len(value):
|
||||||
|
return value[index]
|
||||||
|
else:
|
||||||
|
ExceptionCollector.appendException(
|
||||||
|
KeyError(_(
|
||||||
|
"Property '{0}' found in capability '{1}'"
|
||||||
|
" referenced from node template {2}"
|
||||||
|
" must have an element with index {3}.").
|
||||||
|
format(self.args[2],
|
||||||
|
self.args[1],
|
||||||
|
self.context.name,
|
||||||
|
index)))
|
||||||
|
else:
|
||||||
|
ExceptionCollector.appendException(
|
||||||
|
KeyError(_(
|
||||||
|
"Property '{0}' found in capability '{1}'"
|
||||||
|
" referenced from node template {2}"
|
||||||
|
" must be a list.").format(self.args[2],
|
||||||
|
self.args[1],
|
||||||
|
self.context.name)))
|
||||||
|
|
||||||
|
def _get_attribute_value(self, value, attibute):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
if attibute in value:
|
||||||
|
return value[attibute]
|
||||||
|
else:
|
||||||
|
ExceptionCollector.appendException(
|
||||||
|
KeyError(_(
|
||||||
|
"Property '{0}' found in capability '{1}'"
|
||||||
|
" referenced from node template {2}"
|
||||||
|
" must have an attribute named {3}.").
|
||||||
|
format(self.args[2],
|
||||||
|
self.args[1],
|
||||||
|
self.context.name,
|
||||||
|
attibute)))
|
||||||
|
else:
|
||||||
|
ExceptionCollector.appendException(
|
||||||
|
KeyError(_(
|
||||||
|
"Property '{0}' found in capability '{1}'"
|
||||||
|
" referenced from node template {2}"
|
||||||
|
" must be a dict.").format(self.args[2],
|
||||||
|
self.args[1],
|
||||||
|
self.context.name)))
|
||||||
|
|
||||||
# Add this functions similar to get_attribute case
|
# Add this functions similar to get_attribute case
|
||||||
def _find_host_containing_property(self, node_template_name=SELF):
|
def _find_host_containing_property(self, node_template_name=SELF):
|
||||||
node_template = self._find_node_template(node_template_name)
|
node_template = self._find_node_template(node_template_name)
|
||||||
@ -364,9 +427,29 @@ class GetProperty(Function):
|
|||||||
return len(found) == 1
|
return len(found) == 1
|
||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
if len(self.args) == 3:
|
if len(self.args) >= 3:
|
||||||
property_value = self._find_req_or_cap_property(self.args[1],
|
# First check if there is property with this name
|
||||||
self.args[2])
|
node_tpl = self._find_node_template(self.args[0])
|
||||||
|
props = node_tpl.get_properties() if node_tpl else []
|
||||||
|
index = 2
|
||||||
|
found = [props[self.args[1]]] if self.args[1] in props else []
|
||||||
|
if found:
|
||||||
|
property_value = found[0].value
|
||||||
|
else:
|
||||||
|
index = 3
|
||||||
|
# then check the req or caps
|
||||||
|
property_value = self._find_req_or_cap_property(self.args[1],
|
||||||
|
self.args[2])
|
||||||
|
if len(self.args) > index:
|
||||||
|
for elem in self.args[index:]:
|
||||||
|
if isinstance(property_value, list):
|
||||||
|
int_elem = int(elem)
|
||||||
|
property_value = self._get_index_value(property_value,
|
||||||
|
int_elem)
|
||||||
|
else:
|
||||||
|
property_value = self._get_attribute_value(
|
||||||
|
property_value,
|
||||||
|
elem)
|
||||||
else:
|
else:
|
||||||
property_value = self._find_property(self.args[1]).value
|
property_value = self._find_property(self.args[1]).value
|
||||||
if isinstance(property_value, Function):
|
if isinstance(property_value, Function):
|
||||||
|
10
toscaparser/tests/data/custom_types/db_with_list_param.yaml
Normal file
10
toscaparser/tests/data/custom_types/db_with_list_param.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_0
|
||||||
|
|
||||||
|
node_types:
|
||||||
|
tosca.nodes.DatabaseWithListParam:
|
||||||
|
derived_from: tosca.nodes.Database
|
||||||
|
properties:
|
||||||
|
list_prop:
|
||||||
|
type: list
|
||||||
|
entry_schema:
|
||||||
|
type: integer
|
@ -0,0 +1,47 @@
|
|||||||
|
tosca_definitions_version: tosca_simple_yaml_1_0
|
||||||
|
|
||||||
|
description: TOSCA simple profile with nested property names or indexes.
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- ../custom_types/wordpress.yaml
|
||||||
|
- ../custom_types/db_with_list_param.yaml
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
|
||||||
|
node_templates:
|
||||||
|
|
||||||
|
wordpress:
|
||||||
|
type: tosca.nodes.WebApplication.WordPress
|
||||||
|
requirements:
|
||||||
|
- host: server
|
||||||
|
- database_endpoint: mysql_database
|
||||||
|
interfaces:
|
||||||
|
Standard:
|
||||||
|
configure:
|
||||||
|
implementation: wordpress/wordpress_configure.sh
|
||||||
|
inputs:
|
||||||
|
wp_endpoint_protocol: { get_property: [ SELF, database_endpoint, ports, user_port, protocol ] }
|
||||||
|
wp_list_prop: { get_property: [ mysql_database, list_prop, 2 ] }
|
||||||
|
|
||||||
|
mysql_database:
|
||||||
|
type: tosca.nodes.DatabaseWithListParam
|
||||||
|
properties:
|
||||||
|
list_prop: [1,2,3]
|
||||||
|
capabilities:
|
||||||
|
database_endpoint:
|
||||||
|
properties:
|
||||||
|
ports:
|
||||||
|
user_port:
|
||||||
|
protocol: tcp
|
||||||
|
target: 50000
|
||||||
|
source: 9000
|
||||||
|
requirements:
|
||||||
|
- host: mysql_dbms
|
||||||
|
|
||||||
|
mysql_dbms:
|
||||||
|
type: tosca.nodes.DBMS
|
||||||
|
requirements:
|
||||||
|
- host: server
|
||||||
|
|
||||||
|
server:
|
||||||
|
type: tosca.nodes.Compute
|
@ -134,6 +134,19 @@ class IntrinsicFunctionsTest(TestCase):
|
|||||||
result = test.result()
|
result = test.result()
|
||||||
self.assertEqual(1, result)
|
self.assertEqual(1, result)
|
||||||
|
|
||||||
|
def test_get_property_with_nested_params(self):
|
||||||
|
tosca_tpl = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
"data/functions/tosca_nested_property_names_indexes.yaml")
|
||||||
|
webserver = self._get_node('wordpress', ToscaTemplate(tosca_tpl))
|
||||||
|
operation = self._get_operation(webserver.interfaces, 'configure')
|
||||||
|
wp_endpoint_prot = operation.inputs['wp_endpoint_protocol']
|
||||||
|
self.assertTrue(isinstance(wp_endpoint_prot, functions.GetProperty))
|
||||||
|
self.assertEqual('tcp', wp_endpoint_prot.result())
|
||||||
|
wp_list_prop = operation.inputs['wp_list_prop']
|
||||||
|
self.assertTrue(isinstance(wp_list_prop, functions.GetProperty))
|
||||||
|
self.assertEqual(3, wp_list_prop.result())
|
||||||
|
|
||||||
|
|
||||||
class GetAttributeTest(TestCase):
|
class GetAttributeTest(TestCase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user