summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshangxdy <shang.xiaodong@zte.com.cn>2016-09-14 14:36:33 +0800
committerxiaodong shang <shang.xiaodong@zte.com.cn>2016-09-19 14:23:56 +0000
commit16d01a2dea9ac5447697b44a8d37dc05cb681f71 (patch)
tree2b0cfa2aaf72b1d4e4ebef4e2ccbbb091a4f140c
parentfa44d0821c35d401be256ced90eda934b20bf8d6 (diff)
Update the upstream of tosco-parser and heat-translator to stable
release 0.6/0.5 Currently the parser is based on dev branch of upstream projects, include tosco-parser and heat-translator, for the colorado release of parser, it should be based on a stable version, so it's necessary to update the upstream version to 0.6/tosca-parser and 0.5/heat-translator. JIRA:PARSER-106 Change-Id: I8fb043068d25188c47e5648e1b66184446ac82d6 Signed-off-by: shangxdy <shang.xiaodong@zte.com.cn> (cherry picked from commit f977b94e012828cd2a905b9b841aff33c4b732f8)
-rw-r--r--tosca2heat/heat-translator/test-requirements.txt4
-rw-r--r--tosca2heat/heat-translator/tox.ini5
-rw-r--r--tosca2heat/heat-translator/translator/common/utils.py10
-rw-r--r--tosca2heat/heat-translator/translator/hot/syntax/hot_output.py7
-rw-r--r--tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py36
-rw-r--r--tosca2heat/heat-translator/translator/hot/syntax/hot_template.py1
-rw-r--r--tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py21
-rw-r--r--tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py2
-rw-r--r--tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py2
-rw-r--r--tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py13
-rw-r--r--tosca2heat/heat-translator/translator/hot/translate_node_templates.py287
-rw-r--r--tosca2heat/heat-translator/translator/hot/translate_outputs.py14
-rw-r--r--tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py386
-rw-r--r--tosca2heat/tosca-parser/setup.cfg1
-rw-r--r--tosca2heat/tosca-parser/test-requirements.txt1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/common/exception.py5
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml1730
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py3
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/entity_type.py25
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/grouptype.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py24
-rw-r--r--tosca2heat/tosca-parser/toscaparser/entity_template.py7
-rw-r--r--tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml307
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py4
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py16
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_utils.py1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/topology_template.py1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/unsupportedtype.py38
-rw-r--r--tosca2heat/tosca-parser/toscaparser/utils/urlutils.py6
29 files changed, 1502 insertions, 1457 deletions
diff --git a/tosca2heat/heat-translator/test-requirements.txt b/tosca2heat/heat-translator/test-requirements.txt
index 70a261b..17a507c 100644
--- a/tosca2heat/heat-translator/test-requirements.txt
+++ b/tosca2heat/heat-translator/test-requirements.txt
@@ -4,11 +4,11 @@
hacking<0.11,>=0.10.0
coverage>=3.6 # Apache-2.0
discover # BSD
-fixtures>=3.0.0 # Apache-2.0/BSD
+fixtures<2.0,>=1.3.1 # Apache-2.0/BSD
oslotest>=1.10.0 # Apache-2.0
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD
-sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=1.4.0 # MIT
diff --git a/tosca2heat/heat-translator/tox.ini b/tosca2heat/heat-translator/tox.ini
index 9ee67a0..be57d3e 100644
--- a/tosca2heat/heat-translator/tox.ini
+++ b/tosca2heat/heat-translator/tox.ini
@@ -27,11 +27,6 @@ commands = python setup.py build_sphinx
[testenv:debug]
commands = oslo_debug_helper -t translator/tests {posargs}
-[testenv:py27-tosca-parser-master]
-commands =
- ./run_py27-tosca-parser-master.sh
- python setup.py test --slowest --testr-args='{posargs}'
-
[flake8]
# H803 skipped on purpose per list discussion.
# E123, E125 skipped as they are invalid PEP-8.
diff --git a/tosca2heat/heat-translator/translator/common/utils.py b/tosca2heat/heat-translator/translator/common/utils.py
index 8e4b690..459b5ee 100644
--- a/tosca2heat/heat-translator/translator/common/utils.py
+++ b/tosca2heat/heat-translator/translator/common/utils.py
@@ -18,7 +18,6 @@ import numbers
import os
import re
import requests
-import six
from six.moves.urllib.parse import urlparse
import yaml
@@ -263,17 +262,12 @@ class UrlUtils(object):
def str_to_num(value):
"""Convert a string representation of a number into a numeric type."""
- if isinstance(value, numbers.Number) \
- or isinstance(value, six.integer_types) \
- or isinstance(value, float):
+ if isinstance(value, numbers.Number):
return value
try:
return int(value)
except ValueError:
- try:
- return float(value)
- except ValueError:
- return None
+ return float(value)
def check_for_env_variables():
diff --git a/tosca2heat/heat-translator/translator/hot/syntax/hot_output.py b/tosca2heat/heat-translator/translator/hot/syntax/hot_output.py
index a41208a..ad77fb3 100644
--- a/tosca2heat/heat-translator/translator/hot/syntax/hot_output.py
+++ b/tosca2heat/heat-translator/translator/hot/syntax/hot_output.py
@@ -21,8 +21,5 @@ class HotOutput(object):
self.description = description
def get_dict_output(self):
- if self.description:
- return {self.name: {'value': self.value,
- 'description': self.description}}
- else:
- return {self.name: {'value': self.value}}
+ return {self.name: {'value': self.value,
+ 'description': self.description}}
diff --git a/tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py b/tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py
index 7b83906..54e0d96 100644
--- a/tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py
+++ b/tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py
@@ -103,7 +103,7 @@ class HotResource(object):
# scenarios and cannot be fixed or hard coded here
operations_deploy_sequence = ['create', 'configure', 'start']
- operations = HotResource.get_all_operations(self.nodetemplate)
+ operations = HotResource._get_all_operations(self.nodetemplate)
# create HotResource for each operation used for deployment:
# create, start, configure
@@ -140,15 +140,7 @@ class HotResource(object):
# hosting_server is None if requirements is None
hosting_on_server = (hosting_server.name if
hosting_server else None)
- base_type = HotResource.get_base_type(
- self.nodetemplate.type_definition).type
- # handle interfaces directly defined on a compute
- if hosting_on_server is None \
- and base_type == 'tosca.nodes.Compute':
- hosting_on_server = self.name
-
- if operation.name == reserve_current and \
- base_type != 'tosca.nodes.Compute':
+ if operation.name == reserve_current:
deploy_resource = self
self.name = deploy_name
self.type = 'OS::Heat::SoftwareDeployment'
@@ -156,7 +148,7 @@ class HotResource(object):
'server': {'get_resource':
hosting_on_server},
'signal_transport': 'HEAT_SIGNAL'}
- deploy_lookup[operation] = self
+ deploy_lookup[operation.name] = self
else:
sd_config = {'config': {'get_resource': config_name},
'server': {'get_resource':
@@ -168,7 +160,7 @@ class HotResource(object):
'OS::Heat::SoftwareDeployment',
sd_config)
hot_resources.append(deploy_resource)
- deploy_lookup[operation] = deploy_resource
+ deploy_lookup[operation.name] = deploy_resource
lifecycle_inputs = self._get_lifecycle_inputs(operation)
if lifecycle_inputs:
deploy_resource.properties['input_values'] = \
@@ -178,34 +170,24 @@ class HotResource(object):
# in operations_deploy_sequence
# TODO(anyone): find some better way to encode this implicit sequence
group = {}
- op_index_max = -1
for op, hot in deploy_lookup.items():
# position to determine potential preceding nodes
- op_index = operations_deploy_sequence.index(op.name)
- if op_index > op_index_max:
- op_index_max = op_index
- for preceding_op_name in \
+ op_index = operations_deploy_sequence.index(op)
+ for preceding_op in \
reversed(operations_deploy_sequence[:op_index]):
- preceding_hot = deploy_lookup.get(
- operations.get(preceding_op_name))
+ preceding_hot = deploy_lookup.get(preceding_op)
if preceding_hot:
hot.depends_on.append(preceding_hot)
hot.depends_on_nodes.append(preceding_hot)
group[preceding_hot] = hot
break
- if op_index_max >= 0:
- last_deploy = deploy_lookup.get(operations.get(
- operations_deploy_sequence[op_index_max]))
- else:
- last_deploy = None
-
# save this dependency chain in the set of HOT resources
self.group_dependencies.update(group)
for hot in hot_resources:
hot.group_dependencies.update(group)
- return hot_resources, deploy_lookup, last_deploy
+ return hot_resources
def handle_connectsto(self, tosca_source, tosca_target, hot_source,
hot_target, config_location, operation):
@@ -353,7 +335,7 @@ class HotResource(object):
return tosca_props
@staticmethod
- def get_all_operations(node):
+ def _get_all_operations(node):
operations = {}
for operation in node.interfaces:
operations[operation.name] = operation
diff --git a/tosca2heat/heat-translator/translator/hot/syntax/hot_template.py b/tosca2heat/heat-translator/translator/hot/syntax/hot_template.py
index 0403562..4263c4d 100644
--- a/tosca2heat/heat-translator/translator/hot/syntax/hot_template.py
+++ b/tosca2heat/heat-translator/translator/hot/syntax/hot_template.py
@@ -77,7 +77,6 @@ class HotTemplate(object):
dict_output.update({self.OUTPUTS: all_outputs})
yaml.add_representer(OrderedDict, self.represent_ordereddict)
- yaml.add_representer(dict, self.represent_ordereddict)
yaml_string = yaml.dump(dict_output, default_flow_style=False)
# get rid of the '' from yaml.dump around numbers
yaml_string = yaml_string.replace('\'', '')
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py b/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py
index 743074b..408ee8b 100644
--- a/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py
+++ b/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py
@@ -16,6 +16,7 @@ from mock import patch
from toscaparser.nodetemplate import NodeTemplate
from toscaparser.tests.base import TestCase
+from toscaparser.utils.gettextutils import _
import toscaparser.utils.yamlparser
from translator.hot.tosca.tosca_compute import ToscaCompute
@@ -26,12 +27,22 @@ class ToscaComputeTest(TestCase):
nodetemplates = (toscaparser.utils.yamlparser.
simple_parse(tpl_snippet)['node_templates'])
name = list(nodetemplates.keys())[0]
- nodetemplate = NodeTemplate(name, nodetemplates)
- nodetemplate.validate()
- toscacompute = ToscaCompute(nodetemplate)
- toscacompute.handle_properties()
+ try:
+ nodetemplate = NodeTemplate(name, nodetemplates)
+ nodetemplate.validate()
+ toscacompute = ToscaCompute(nodetemplate)
+ toscacompute.handle_properties()
+ if not self._compare_properties(toscacompute.properties,
+ expectedprops):
+ raise Exception(_("Hot Properties are not"
+ " same as expected properties"))
+ except Exception:
+ # for time being rethrowing. Will be handled future based
+ # on new development in Glance and Graffiti
+ raise
- self.assertDictEqual(expectedprops, toscacompute.properties)
+ def _compare_properties(self, hotprops, expectedprops):
+ return all(item in hotprops.items() for item in expectedprops.items())
def test_node_compute_with_host_and_os_capabilities(self):
tpl_snippet = '''
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py b/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py
index 924ff9d..d4b2f44 100644
--- a/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py
+++ b/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py
@@ -67,5 +67,5 @@ class ToscaBlockStorage(HotResource):
# attribute for the matching resource. Unless there is additional
# runtime support, this should be a one to one mapping.
if attribute == 'volume_id':
- attr['get_resource'] = self.name
+ attr['get_resource'] = args[0]
return attr
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py b/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py
index 2242c2d..71b9822 100644
--- a/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py
+++ b/tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py
@@ -50,4 +50,4 @@ class ToscaBlockStorageAttachment(HotResource):
self.properties.pop('device')
def handle_life_cycle(self):
- return None, None, None
+ pass
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py b/tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py
index 16d0518..8a959d1 100644
--- a/tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py
+++ b/tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py
@@ -84,14 +84,6 @@ class ToscaCompute(HotResource):
('architecture', 'distribution', 'type', 'version')
toscatype = 'tosca.nodes.Compute'
- ALLOWED_NOVA_SERVER_PROPS = \
- ('admin_pass', 'availability_zone', 'block_device_mapping',
- 'block_device_mapping_v2', 'config_drive', 'diskConfig', 'flavor',
- 'flavor_update_policy', 'image', 'image_update_policy', 'key_name',
- 'metadata', 'name', 'networks', 'personality', 'reservation_id',
- 'scheduler_hints', 'security_groups', 'software_config_transport',
- 'user_data', 'user_data_format', 'user_data_update_policy')
-
def __init__(self, nodetemplate):
super(ToscaCompute, self).__init__(nodetemplate,
type='OS::Nova::Server')
@@ -107,8 +99,7 @@ class ToscaCompute(HotResource):
self.properties['software_config_transport'] = 'POLL_SERVER_HEAT'
tosca_props = self.get_tosca_props()
for key, value in tosca_props.items():
- if key in self.ALLOWED_NOVA_SERVER_PROPS:
- self.properties[key] = value
+ self.properties[key] = value
# To be reorganized later based on new development in Glance and Graffiti
def translate_compute_flavor_and_image(self,
@@ -264,7 +255,7 @@ class ToscaCompute(HotResource):
images = IMAGES
if translator.common.utils.check_for_env_variables():
resp = self._populate_image_dict()
- if resp and len(resp.keys()) > 0:
+ if len(resp.keys()) > 0:
images = resp
match_all = images.keys()
architecture = properties.get(self.ARCHITECTURE)
diff --git a/tosca2heat/heat-translator/translator/hot/translate_node_templates.py b/tosca2heat/heat-translator/translator/hot/translate_node_templates.py
index 4dd9556..0aefd48 100644
--- a/tosca2heat/heat-translator/translator/hot/translate_node_templates.py
+++ b/tosca2heat/heat-translator/translator/hot/translate_node_templates.py
@@ -16,8 +16,6 @@ import logging
import os
import six
-from collections import OrderedDict
-from toscaparser.functions import Concat
from toscaparser.functions import GetAttribute
from toscaparser.functions import GetInput
from toscaparser.functions import GetProperty
@@ -27,7 +25,6 @@ from toscaparser.utils.gettextutils import _
from translator.common.exception import ToscaClassAttributeError
from translator.common.exception import ToscaClassImportError
from translator.common.exception import ToscaModImportError
-from translator.common import utils
from translator.conf.config import ConfigProvider as translatorConfig
from translator.hot.syntax.hot_resource import HotResource
from translator.hot.tosca.tosca_block_storage_attachment import (
@@ -135,8 +132,6 @@ log = logging.getLogger('heat-translator')
TOSCA_TO_HOT_TYPE = _generate_type_map()
-BASE_TYPES = six.string_types + six.integer_types + (dict, OrderedDict)
-
class TranslateNodeTemplates(object):
'''Translate TOSCA NodeTemplates to Heat Resources.'''
@@ -151,9 +146,6 @@ class TranslateNodeTemplates(object):
log.debug(_('Mapping between TOSCA nodetemplate and HOT resource.'))
self.hot_lookup = {}
self.policies = self.tosca.topology_template.policies
- # stores the last deploy of generated behavior for a resource
- # useful to satisfy underlying dependencies between interfaces
- self.last_deploy_map = {}
def translate(self):
return self._translate_nodetemplates()
@@ -231,14 +223,9 @@ class TranslateNodeTemplates(object):
# into multiple HOT resources and may change their name
lifecycle_resources = []
for resource in self.hot_resources:
- expanded_resources, deploy_lookup, last_deploy = resource.\
- handle_life_cycle()
- if expanded_resources:
- lifecycle_resources += expanded_resources
- if deploy_lookup:
- self.hot_lookup.update(deploy_lookup)
- if last_deploy:
- self.last_deploy_map[resource] = last_deploy
+ expanded = resource.handle_life_cycle()
+ if expanded:
+ lifecycle_resources += expanded
self.hot_resources += lifecycle_resources
# Handle configuration from ConnectsTo relationship in the TOSCA node:
@@ -270,9 +257,7 @@ class TranslateNodeTemplates(object):
# if the source of dependency is a server and the
# relationship type is 'tosca.relationships.HostedOn',
# add dependency as properties.server
- base_type = HotResource.get_base_type(
- node_depend.type_definition)
- if base_type.type == 'tosca.nodes.Compute' and \
+ if node_depend.type == 'tosca.nodes.Compute' and \
node.related[node_depend].type == \
node.type_definition.HOSTEDON:
self.hot_lookup[node].properties['server'] = \
@@ -285,13 +270,6 @@ class TranslateNodeTemplates(object):
self.hot_lookup[node].depends_on_nodes.append(
self.hot_lookup[node_depend].top_of_chain())
- last_deploy = self.last_deploy_map.get(
- self.hot_lookup[node_depend])
- if last_deploy and \
- last_deploy not in self.hot_lookup[node].depends_on:
- self.hot_lookup[node].depends_on.append(last_deploy)
- self.hot_lookup[node].depends_on_nodes.append(last_deploy)
-
# handle hosting relationship
for resource in self.hot_resources:
resource.handle_hosting()
@@ -321,202 +299,53 @@ class TranslateNodeTemplates(object):
inputs = resource.properties.get('input_values')
if inputs:
for name, value in six.iteritems(inputs):
- inputs[name] = self.translate_param_value(value, resource)
-
- # remove resources without type defined
- # for example a SoftwareComponent without interfaces
- # would fall in this case
- to_remove = []
- for resource in self.hot_resources:
- if resource.type is None:
- to_remove.append(resource)
-
- for resource in to_remove:
- self.hot_resources.remove(resource)
+ inputs[name] = self._translate_input(value, resource)
return self.hot_resources
- def translate_param_value(self, param_value, resource):
- tosca_template = None
- if resource:
- tosca_template = resource.nodetemplate
-
+ def _translate_input(self, input_value, resource):
get_property_args = None
- if isinstance(param_value, GetProperty):
- get_property_args = param_value.args
+ if isinstance(input_value, GetProperty):
+ get_property_args = input_value.args
# to remove when the parser is fixed to return GetProperty
- elif isinstance(param_value, dict) and 'get_property' in param_value:
- get_property_args = param_value['get_property']
+ if isinstance(input_value, dict) and 'get_property' in input_value:
+ get_property_args = input_value['get_property']
if get_property_args is not None:
- tosca_target, prop_name, prop_arg = \
- self.decipher_get_operation(get_property_args,
- tosca_template)
- if tosca_target:
- prop_value = tosca_target.get_property_value(prop_name)
- if prop_value:
- prop_value = self.translate_param_value(
- prop_value, resource)
- return self._unfold_value(prop_value, prop_arg)
- get_attr_args = None
- if isinstance(param_value, GetAttribute):
- get_attr_args = param_value.result().args
- # to remove when the parser is fixed to return GetAttribute
- elif isinstance(param_value, dict) and 'get_attribute' in param_value:
- get_attr_args = param_value['get_attribute']
- if get_attr_args is not None:
+ hot_target = self._find_hot_resource_for_tosca(
+ get_property_args[0], resource)
+ if hot_target:
+ props = hot_target.get_tosca_props()
+ prop_name = get_property_args[1]
+ if prop_name in props:
+ return props[prop_name]
+ elif isinstance(input_value, GetAttribute):
# for the attribute
# get the proper target type to perform the translation
- tosca_target, attr_name, attr_arg = \
- self.decipher_get_operation(get_attr_args, tosca_template)
- attr_args = []
- if attr_arg:
- attr_args += attr_arg
- if tosca_target:
- if tosca_target in self.hot_lookup:
- attr_value = self.hot_lookup[tosca_target].\
- get_hot_attribute(attr_name, attr_args)
- attr_value = self.translate_param_value(
- attr_value, resource)
- return self._unfold_value(attr_value, attr_arg)
- elif isinstance(param_value, dict) and 'get_artifact' in param_value:
- get_artifact_args = param_value['get_artifact']
- tosca_target, artifact_name, _ = \
- self.decipher_get_operation(get_artifact_args,
- tosca_template)
-
- if tosca_target:
- artifacts = self.get_all_artifacts(tosca_target)
- if artifact_name in artifacts:
- artifact = artifacts[artifact_name]
- if artifact.get('type', None) == 'tosca.artifacts.File':
- return {'get_file': artifact.get('file')}
- get_input_args = None
- if isinstance(param_value, GetInput):
- get_input_args = param_value.args
- elif isinstance(param_value, dict) and 'get_input' in param_value:
- get_input_args = param_value['get_input']
- if get_input_args is not None:
- if isinstance(get_input_args, list) \
- and len(get_input_args) == 1:
- return {'get_param': self.translate_param_value(
- get_input_args[0], resource)}
- else:
- return {'get_param': self.translate_param_value(
- get_input_args, resource)}
- elif isinstance(param_value, dict) \
- and 'get_operation_output' in param_value:
- res = self._translate_get_operation_output_function(
- param_value['get_operation_output'], tosca_template)
- if res:
- return res
- concat_list = None
- if isinstance(param_value, Concat):
- concat_list = param_value.args
- elif isinstance(param_value, dict) and 'concat' in param_value:
- concat_list = param_value['concat']
- if concat_list is not None:
- res = self._translate_concat_function(concat_list, resource)
- if res:
- return res
-
- if isinstance(param_value, list):
- translated_list = []
- for elem in param_value:
- translated_elem = self.translate_param_value(elem, resource)
- if translated_elem:
- translated_list.append(translated_elem)
- return translated_list
-
- if isinstance(param_value, BASE_TYPES):
- return param_value
-
- return None
-
- def _translate_concat_function(self, concat_list, resource):
- str_replace_template = ''
- str_replace_params = {}
- index = 0
- for elem in concat_list:
- str_replace_template += '$s' + str(index)
- str_replace_params['$s' + str(index)] = \
- self.translate_param_value(elem, resource)
- index += 1
-
- return {'str_replace': {
- 'template': str_replace_template,
- 'params': str_replace_params
- }}
-
- def _translate_get_operation_output_function(self, args, tosca_template):
- tosca_target = self._find_tosca_node(args[0],
- tosca_template)
- if tosca_target and len(args) >= 4:
- operations = HotResource.get_all_operations(tosca_target)
- # ignore Standard interface name,
- # it is the only one supported in the translator anyway
- op_name = args[2]
- output_name = args[3]
- if op_name in operations:
- operation = operations[op_name]
- if operation in self.hot_lookup:
- matching_deploy = self.hot_lookup[operation]
- matching_config_name = matching_deploy.\
- properties['config']['get_resource']
- matching_config = self.find_hot_resource(
- matching_config_name)
- if matching_config:
- outputs = matching_config.properties.get('outputs')
- if outputs is None:
- outputs = []
- outputs.append({'name': output_name})
- matching_config.properties['outputs'] = outputs
- return {'get_attr': [
- matching_deploy.name,
- output_name
- ]}
-
- @staticmethod
- def _unfold_value(value, value_arg):
- if value_arg is not None:
- if isinstance(value, dict):
- val = value.get(value_arg)
- if val is not None:
- return val
-
- index = utils.str_to_num(value_arg)
- if isinstance(value, list) and index is not None:
- return value[index]
- return value
-
- def decipher_get_operation(self, args, current_tosca_node):
- tosca_target = self._find_tosca_node(args[0],
- current_tosca_node)
- new_target = None
- if tosca_target and len(args) > 2:
- cap_or_req_name = args[1]
- cap = tosca_target.get_capability(cap_or_req_name)
- if cap:
- new_target = cap
+ args = input_value.result().args
+ hot_target = self._find_hot_resource_for_tosca(args[0], resource)
+
+ return hot_target.get_hot_attribute(args[1], args)
+ # most of artifacts logic should move to the parser
+ elif isinstance(input_value, dict) and 'get_artifact' in input_value:
+ get_artifact_args = input_value['get_artifact']
+
+ hot_target = self._find_hot_resource_for_tosca(
+ get_artifact_args[0], resource)
+ artifacts = TranslateNodeTemplates.get_all_artifacts(
+ hot_target.nodetemplate)
+
+ if get_artifact_args[1] in artifacts:
+ artifact = artifacts[get_artifact_args[1]]
+ if artifact.get('type', None) == 'tosca.artifacts.File':
+ return {'get_file': artifact.get('file')}
+ elif isinstance(input_value, GetInput):
+ if isinstance(input_value.args, list) \
+ and len(input_value.args) == 1:
+ return {'get_param': input_value.args[0]}
else:
- for req in tosca_target.requirements:
- if cap_or_req_name in req:
- new_target = self._find_tosca_node(
- req[cap_or_req_name])
- cap = new_target.get_capability(cap_or_req_name)
- if cap:
- new_target = cap
- break
-
- if new_target:
- tosca_target = new_target
-
- prop_name = args[2]
- prop_arg = args[3] if len(args) >= 4 else None
- else:
- prop_name = args[1]
- prop_arg = args[2] if len(args) >= 3 else None
+ return {'get_param': input_value.args}
- return tosca_target, prop_name, prop_arg
+ return input_value
@staticmethod
def get_all_artifacts(nodetemplate):
@@ -591,29 +420,23 @@ class TranslateNodeTemplates(object):
if resource.name == name:
return resource
- def _find_tosca_node(self, tosca_name, current_tosca_template=None):
- tosca_node = None
- if tosca_name == 'SELF':
- tosca_node = current_tosca_template
- if tosca_name == 'HOST' and current_tosca_template:
- for req in current_tosca_template.requirements:
- if 'host' in req:
- tosca_node = self._find_tosca_node(req['host'])
-
- if tosca_node is None:
- for node in self.nodetemplates:
- if node.name == tosca_name:
- tosca_node = node
- break
- return tosca_node
+ def _find_tosca_node(self, tosca_name):
+ for node in self.nodetemplates:
+ if node.name == tosca_name:
+ return node
def _find_hot_resource_for_tosca(self, tosca_name,
current_hot_resource=None):
- current_tosca_resource = current_hot_resource.nodetemplate \
- if current_hot_resource else None
- tosca_node = self._find_tosca_node(tosca_name, current_tosca_resource)
- if tosca_node:
- return self.hot_lookup[tosca_node]
+ if tosca_name == 'SELF':
+ return current_hot_resource
+ if tosca_name == 'HOST' and current_hot_resource is not None:
+ for req in current_hot_resource.nodetemplate.requirements:
+ if 'host' in req:
+ return self._find_hot_resource_for_tosca(req['host'])
+
+ for node in self.nodetemplates:
+ if node.name == tosca_name:
+ return self.hot_lookup[node]
return None
diff --git a/tosca2heat/heat-translator/translator/hot/translate_outputs.py b/tosca2heat/heat-translator/translator/hot/translate_outputs.py
index 87ec02a..4197cdd 100644
--- a/tosca2heat/heat-translator/translator/hot/translate_outputs.py
+++ b/tosca2heat/heat-translator/translator/hot/translate_outputs.py
@@ -33,8 +33,16 @@ class TranslateOutputs(object):
def _translate_outputs(self):
hot_outputs = []
for output in self.outputs:
- hot_value = self.nodes.translate_param_value(output.value, None)
- if hot_value is not None:
- hot_outputs.append(HotOutput(output.name, hot_value,
+ if output.value.name == 'get_attribute':
+ get_parameters = output.value.args
+ hot_target = self.nodes.find_hot_resource(get_parameters[0])
+ hot_value = hot_target.get_hot_attribute(get_parameters[1],
+ get_parameters)
+ hot_outputs.append(HotOutput(output.name,
+ hot_value,
+ output.description))
+ else:
+ hot_outputs.append(HotOutput(output.name,
+ output.value,
output.description))
return hot_outputs
diff --git a/tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py b/tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py
index 3e69d7a..bd98904 100644
--- a/tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py
+++ b/tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py
@@ -23,48 +23,35 @@ from translator.tests.base import TestCase
class ToscaHotTranslationTest(TestCase):
- def _test_successful_translation(self, tosca_file, hot_file, params=None):
- if not params:
- params = {}
+ def test_hot_translate_single_server(self):
+ tosca_file = '../tests/data/tosca_single_server.yaml'
+ hot_file = '../tests/data/hot_output/hot_single_server.yaml'
+ params = {'cpus': 1}
diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
hot_file,
params)
self.assertEqual({}, diff, '<difference> : ' +
json.dumps(diff, indent=4, separators=(', ', ': ')))
- def _test_failed_translation(self, tosca_file, hot_file, params, msg,
- msg_path, error_raise, error_collect):
- if msg_path:
- path = os.path.normpath(os.path.join(
- os.path.dirname(os.path.realpath(__file__)), tosca_file))
- msg = msg % path
- self.assertRaises(
- error_raise,
- TranslationUtils.compare_tosca_translation_with_hot,
- tosca_file, hot_file, params)
- ExceptionCollector.assertExceptionMessage(error_collect, msg)
-
- def test_hot_translate_single_server(self):
- tosca_file = '../tests/data/tosca_single_server.yaml'
- hot_file = '../tests/data/hot_output/hot_single_server.yaml'
- params = {'cpus': 1}
- self._test_successful_translation(tosca_file, hot_file, params)
-
def test_hot_translate_single_server_with_defaults(self):
tosca_file = \
'../tests/data/tosca_single_server_with_defaults.yaml'
-
hot_file_with_input = '../tests/data/hot_output/' \
'hot_single_server_with_defaults_with_input.yaml'
- params1 = {'cpus': '1'}
- self._test_successful_translation(tosca_file, hot_file_with_input,
- params1)
-
hot_file_without_input = '../tests/data/hot_output/' \
'hot_single_server_with_defaults_without_input.yaml'
+
+ params1 = {'cpus': '1'}
+ diff1 = TranslationUtils.compare_tosca_translation_with_hot(
+ tosca_file, hot_file_with_input, params1)
+ self.assertEqual({}, diff1, '<difference> : ' +
+ json.dumps(diff1, indent=4, separators=(', ', ': ')))
+
params2 = {}
- self._test_successful_translation(tosca_file, hot_file_without_input,
- params2)
+ diff2 = TranslationUtils.compare_tosca_translation_with_hot(
+ tosca_file, hot_file_without_input, params2)
+ self.assertEqual({}, diff2, '<difference> : ' +
+ json.dumps(diff2, indent=4, separators=(', ', ': ')))
def test_hot_translate_wordpress_single_instance(self):
tosca_file = '../tests/data/tosca_single_instance_wordpress.yaml'
@@ -76,17 +63,29 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_helloworld(self):
tosca_file = '../tests/data/tosca_helloworld.yaml'
hot_file = '../tests/data/hot_output/hot_hello_world.yaml'
- self._test_successful_translation(tosca_file, hot_file)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ {})
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_host_assignment(self):
tosca_file = '../tests/data/test_host_assignment.yaml'
hot_file = '../tests/data/hot_output/hot_host_assignment.yaml'
- self._test_successful_translation(tosca_file, hot_file)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ {})
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_elk(self):
tosca_file = '../tests/data/tosca_elk.yaml'
@@ -94,7 +93,11 @@ class ToscaHotTranslationTest(TestCase):
params = {'github_url':
'http://github.com/paypal/rest-api-sample-app-nodejs.git',
'my_cpus': 4}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_nodejs_mongodb_two_instances(self):
tosca_file = '../tests/data/tosca_nodejs_mongodb_two_instances.yaml'
@@ -103,7 +106,11 @@ class ToscaHotTranslationTest(TestCase):
params = {'github_url':
'http://github.com/paypal/rest-api-sample-app-nodejs.git',
'my_cpus': 4}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_blockstorage_with_attachment(self):
tosca_file = '../tests/data/storage/' \
@@ -114,7 +121,11 @@ class ToscaHotTranslationTest(TestCase):
'storage_location': '/dev/vdc',
'storage_size': '2000 MB',
'storage_snapshot_id': 'ssid'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_blockstorage_with_custom_relationship_type(self):
tosca_file = '../tests/data/storage/' \
@@ -125,7 +136,11 @@ class ToscaHotTranslationTest(TestCase):
'storage_location': '/dev/vdc',
'storage_size': '1 GB',
'storage_snapshot_id': 'ssid'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_blockstorage_with_relationship_template(self):
tosca_file = '../tests/data/storage/' \
@@ -135,7 +150,11 @@ class ToscaHotTranslationTest(TestCase):
params = {'cpus': 1,
'storage_location': '/dev/vdc',
'storage_size': '1 GB'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_blockstorage_with_attachment_notation1(self):
tosca_file = '../tests/data/storage/' \
@@ -148,11 +167,19 @@ class ToscaHotTranslationTest(TestCase):
'storage_location': 'some_folder',
'storage_size': '1 GB',
'storage_snapshot_id': 'ssid'}
-
+ diff1 = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file1,
+ params)
try:
- self._test_successful_translation(tosca_file, hot_file1, params)
+ self.assertEqual({}, diff1, '<difference> : ' +
+ json.dumps(diff1, indent=4,
+ separators=(', ', ': ')))
except Exception:
- self._test_successful_translation(tosca_file, hot_file2, params)
+ diff2 = TranslationUtils.compare_tosca_translation_with_hot(
+ tosca_file, hot_file2, params)
+ self.assertEqual({}, diff2, '<difference> : ' +
+ json.dumps(diff2, indent=4,
+ separators=(', ', ': ')))
def test_hot_translate_blockstorage_with_attachment_notation2(self):
tosca_file = '../tests/data/storage/' \
@@ -165,10 +192,19 @@ class ToscaHotTranslationTest(TestCase):
'storage_location': '/dev/vdc',
'storage_size': '1 GB',
'storage_snapshot_id': 'ssid'}
+ diff1 = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file1,
+ params)
try:
- self._test_successful_translation(tosca_file, hot_file1, params)
+ self.assertEqual({}, diff1, '<difference> : ' +
+ json.dumps(diff1, indent=4,
+ separators=(', ', ': ')))
except Exception:
- self._test_successful_translation(tosca_file, hot_file2, params)
+ diff2 = TranslationUtils.compare_tosca_translation_with_hot(
+ tosca_file, hot_file2, params)
+ self.assertEqual({}, diff2, '<difference> : ' +
+ json.dumps(diff2, indent=4,
+ separators=(', ', ': ')))
def test_hot_translate_multiple_blockstorage_with_attachment(self):
tosca_file = '../tests/data/storage/' \
@@ -181,23 +217,40 @@ class ToscaHotTranslationTest(TestCase):
'storage_location': '/dev/vdc',
'storage_size': '1 GB',
'storage_snapshot_id': 'ssid'}
+ diff1 = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file1,
+ params)
try:
- self._test_successful_translation(tosca_file, hot_file1, params)
+ self.assertEqual({}, diff1, '<difference> : ' +
+ json.dumps(diff1, indent=4,
+ separators=(', ', ': ')))
except Exception:
- self._test_successful_translation(tosca_file, hot_file2, params)
+ diff2 = TranslationUtils.compare_tosca_translation_with_hot(
+ tosca_file, hot_file2, params)
+ self.assertEqual({}, diff2, '<difference> : ' +
+ json.dumps(diff2, indent=4,
+ separators=(', ', ': ')))
def test_hot_translate_single_object_store(self):
tosca_file = '../tests/data/storage/tosca_single_object_store.yaml'
hot_file = '../tests/data/hot_output/hot_single_object_store.yaml'
params = {'objectstore_name': 'myobjstore'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_one_server_one_network(self):
tosca_file = '../tests/data/network/tosca_one_server_one_network.yaml'
hot_file = '../tests/data/hot_output/network/' \
'hot_one_server_one_network.yaml'
params = {'network_name': 'private_net'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_server_on_existing_network(self):
tosca_file = '../tests/data/network/' \
@@ -205,7 +258,11 @@ class ToscaHotTranslationTest(TestCase):
hot_file = '../tests/data/hot_output/network/' \
'hot_server_on_existing_network.yaml'
params = {'network_name': 'private_net'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_two_servers_one_network(self):
tosca_file = '../tests/data/network/tosca_two_servers_one_network.yaml'
@@ -215,7 +272,11 @@ class ToscaHotTranslationTest(TestCase):
'network_cidr': '10.0.0.0/24',
'network_start_ip': '10.0.0.100',
'network_end_ip': '10.0.0.150'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_one_server_three_networks(self):
tosca_file = '../tests/data/network/' \
@@ -223,20 +284,32 @@ class ToscaHotTranslationTest(TestCase):
hot_file = '../tests/data/hot_output/network/' \
'hot_one_server_three_networks.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_software_component(self):
tosca_file = '../tests/data/tosca_software_component.yaml'
hot_file = '../tests/data/hot_output/hot_software_component.yaml'
params = {'cpus': '1',
'download_url': 'http://www.software.com/download'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_web_application(self):
tosca_file = '../tests/data/tosca_web_application.yaml'
hot_file = '../tests/data/hot_output/hot_web_application.yaml'
params = {'cpus': '2', 'context_root': 'my_web_app'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_template_with_url_import(self):
tosca_file = '../tests/data/' \
@@ -249,7 +322,11 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_template_by_url_with_local_import(self):
tosca_file = 'https://raw.githubusercontent.com/openstack/' \
@@ -263,7 +340,11 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_template_by_url_with_local_abspath_import(self):
tosca_file = 'https://raw.githubusercontent.com/openstack/' \
@@ -278,15 +359,17 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
expected_msg = _('Absolute file name "/tmp/wordpress.yaml" cannot be '
'used in a URL-based input template "https://raw.'
'githubusercontent.com/openstack/heat-translator/'
'master/translator/tests/data/tosca_single_instance_'
'wordpress_with_local_abspath_import.yaml".')
- msg_path = False
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- ImportError)
+ ExceptionCollector.assertExceptionMessage(ImportError, expected_msg)
def test_hot_translate_template_by_url_with_url_import(self):
tosca_url = 'https://raw.githubusercontent.com/openstack/' \
@@ -300,12 +383,20 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
- self._test_successful_translation(tosca_url, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_url,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_translate_hello_world_csar(self):
tosca_file = '../tests/data/csar_hello_world.zip'
hot_file = '../tests/data/hot_output/hot_hello_world.yaml'
- self._test_successful_translation(tosca_file, hot_file)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ {})
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_translate_single_instance_wordpress_csar(self):
tosca_file = '../tests/data/csar_single_instance_wordpress.zip'
@@ -317,7 +408,11 @@ class ToscaHotTranslationTest(TestCase):
'db_root_pwd': 'passw0rd',
'db_port': 3366,
'cpus': 8}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_translate_elk_csar_from_url(self):
tosca_file = 'https://github.com/openstack/heat-translator/raw/' \
@@ -326,103 +421,150 @@ class ToscaHotTranslationTest(TestCase):
params = {'github_url':
'http://github.com/paypal/rest-api-sample-app-nodejs.git',
'my_cpus': 4}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_translate_csar_not_zip(self):
tosca_file = '../tests/data/csar_not_zip.zip'
hot_file = ''
params = {}
- expected_msg = _('"%s" is not a valid zip file.')
- msg_path = True
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- ValidationError)
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
+ path = os.path.normpath(os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), tosca_file))
+ expected_msg = _('"%s" is not a valid zip file.') % path
+ ExceptionCollector.assertExceptionMessage(ValidationError,
+ expected_msg)
def test_translate_csar_metadata_not_yaml(self):
tosca_file = '../tests/data/csar_metadata_not_yaml.zip'
hot_file = ''
params = {}
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
+ path = os.path.normpath(os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), tosca_file))
expected_msg = _('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR '
- '"%s" does not contain valid YAML content.')
- msg_path = True
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- ValidationError)
+ '"%s" does not contain valid YAML content.') % path
+ ExceptionCollector.assertExceptionMessage(ValidationError,
+ expected_msg)
def test_translate_csar_wrong_metadata_file(self):
tosca_file = '../tests/data/csar_wrong_metadata_file.zip'
hot_file = ''
params = {}
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
+ path = os.path.normpath(os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), tosca_file))
expected_msg = _('"%s" is not a valid CSAR as it does not contain the '
'required file "TOSCA.meta" in the folder '
- '"TOSCA-Metadata".')
- msg_path = True
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- ValidationError)
+ '"TOSCA-Metadata".') % path
+ ExceptionCollector.assertExceptionMessage(ValidationError,
+ expected_msg)
def test_translate_csar_wordpress_invalid_import_path(self):
tosca_file = '../tests/data/csar_wordpress_invalid_import_path.zip'
hot_file = ''
params = {}
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
expected_msg = _('Import '
'"Invalid_import_path/wordpress.yaml" is not valid.')
- msg_path = False
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- ImportError)
+ ExceptionCollector.assertExceptionMessage(ImportError, expected_msg)
def test_translate_csar_wordpress_invalid_script_url(self):
tosca_file = '../tests/data/csar_wordpress_invalid_script_url.zip'
hot_file = ''
params = {}
+
+ self.assertRaises(
+ ValidationError,
+ TranslationUtils.compare_tosca_translation_with_hot,
+ tosca_file, hot_file, params)
expected_msg = _('The resource at '
'"https://raw.githubusercontent.com/openstack/'
'heat-translator/master/translator/tests/data/'
'custom_types/wordpress1.yaml" cannot be accessed.')
- msg_path = False
- self._test_failed_translation(tosca_file, hot_file, params,
- expected_msg, msg_path, ValidationError,
- URLException)
+ ExceptionCollector.assertExceptionMessage(URLException, expected_msg)
def test_hot_translate_flavor_image(self):
tosca_file = '../tests/data/test_tosca_flavor_and_image.yaml'
hot_file = '../tests/data/hot_output/hot_flavor_and_image.yaml'
- self._test_successful_translation(tosca_file, hot_file)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ {})
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_flavor_image_params(self):
tosca_file = '../tests/data/test_tosca_flavor_and_image.yaml'
hot_file = '../tests/data/hot_output/hot_flavor_and_image_params.yaml'
params = {'key_name': 'paramkey'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_custom_type(self):
tosca_file = '../tests/data/test_tosca_custom_type.yaml'
hot_file = '../tests/data/hot_output/' \
'hot_custom_type.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_custom_type_with_override(self):
tosca_file = '../tests/data/test_tosca_custom_type_with_override.yaml'
hot_file = '../tests/data/hot_output/' \
'hot_custom_type_with_override.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_custom_type_with_param_override(self):
tosca_file = '../tests/data/test_tosca_custom_type_with_override.yaml'
hot_file = '../tests/data/hot_output/' \
'hot_custom_type_with_param_override.yaml'
params = {'install_path': '/home/custom/from/cli'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_artifact(self):
tosca_file = '../tests/data/test_tosca_artifact.yaml'
hot_file = '../tests/data/hot_output/' \
'hot_artifact.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_without_tosca_os_version(self):
tosca_file = '../tests/data/' \
@@ -430,13 +572,21 @@ class ToscaHotTranslationTest(TestCase):
hot_file = '../tests/data/hot_output/' \
'hot_single_server_without_tosca_os_version.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_helloworld_with_userkey(self):
tosca_file = '../tests/data/tosca_helloworld.yaml'
hot_file = '../tests/data/hot_output/hot_hello_world_userkey.yaml'
params = {'key_name': 'userkey'}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_custom_networks_nodes_inline(self):
tosca_file = '../tests/data/network/' \
@@ -444,7 +594,11 @@ class ToscaHotTranslationTest(TestCase):
hot_file = '../tests/data/hot_output/network/' \
'hot_custom_network_nodes.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_custom_networks_nodes_imports(self):
tosca_file = '../tests/data/network/' \
@@ -452,46 +606,38 @@ class ToscaHotTranslationTest(TestCase):
hot_file = '../tests/data/hot_output/network/' \
'hot_custom_network_nodes.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_nfv_sample(self):
tosca_file = '../tests/data/test_tosca_nfv_sample.yaml'
hot_file = '../tests/data/hot_output/hot_nfv_sample.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
-
- def test_hot_translate_nfv_vRNC(self):
- tosca_file = "../tests/data/vRNC/Definitions/vRNC.yaml"
- hot_file = '../tests/data/hot_output/hot_vRNC.yaml'
- params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_translate_policy(self):
tosca_file = '../tests/data/tosca_policies.yaml'
hot_file = '../tests/data/hot_output/hot_policies.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
def test_hot_script_types(self):
tosca_file = '../tests/data/test_tosca_script_types.yaml'
hot_file = '../tests/data/hot_output/hot_script_types.yaml'
params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
-
- def test_hot_interface_on_compute(self):
- tosca_file = '../tests/data/test_tosca_interface_on_compute.yaml'
- hot_file = '../tests/data/hot_output/hot_interface_on_compute.yaml'
- params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
-
- def test_hot_get_functions_semantic(self):
- tosca_file = '../tests/data/test_tosca_get_functions_semantic.yaml'
- hot_file = '../tests/data/hot_output/hot_get_functions_semantic.yaml'
- params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
-
- def test_hot_exchange_public_ssh_key(self):
- tosca_file = '../tests/data/tosca_exchange_public_ssh_key.yaml'
- hot_file = '../tests/data/hot_output/hot_exchange_public_ssh_key.yaml'
- params = {}
- self._test_successful_translation(tosca_file, hot_file, params)
+ diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+ hot_file,
+ params)
+ self.assertEqual({}, diff, '<difference> : ' +
+ json.dumps(diff, indent=4, separators=(', ', ': ')))
diff --git a/tosca2heat/tosca-parser/setup.cfg b/tosca2heat/tosca-parser/setup.cfg
index 747d88c..c109228 100644
--- a/tosca2heat/tosca-parser/setup.cfg
+++ b/tosca2heat/tosca-parser/setup.cfg
@@ -17,6 +17,7 @@ classifier =
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.4
+ Programming Language :: Python :: 3.5
[files]
packages =
diff --git a/tosca2heat/tosca-parser/test-requirements.txt b/tosca2heat/tosca-parser/test-requirements.txt
index 70a261b..1bb6623 100644
--- a/tosca2heat/tosca-parser/test-requirements.txt
+++ b/tosca2heat/tosca-parser/test-requirements.txt
@@ -3,7 +3,6 @@
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
coverage>=3.6 # Apache-2.0
-discover # BSD
fixtures>=3.0.0 # Apache-2.0/BSD
oslotest>=1.10.0 # Apache-2.0
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
diff --git a/tosca2heat/tosca-parser/toscaparser/common/exception.py b/tosca2heat/tosca-parser/toscaparser/common/exception.py
index 34abe77..f67a277 100644
--- a/tosca2heat/tosca-parser/toscaparser/common/exception.py
+++ b/tosca2heat/tosca-parser/toscaparser/common/exception.py
@@ -67,6 +67,11 @@ class TOSCAException(Exception):
TOSCAException._FATAL_EXCEPTION_FORMAT_ERRORS = flag
+class UnsupportedTypeError(TOSCAException):
+ msg_fmt = _('Type "%(what)s" is valid TOSCA type'
+ ' but not supported at this time.')
+
+
class MissingRequiredFieldError(TOSCAException):
msg_fmt = _('%(what)s is missing required field "%(required)s".')
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml b/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml
index ede5fa5..6f3b331 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml
@@ -22,685 +22,688 @@ tosca_definitions_version: tosca_simple_yaml_1_0
# A Node Type is a reusable entity that defines the type of one or more
# Node Templates.
##########################################################################
-tosca.nodes.Root:
- description: >
- The TOSCA root node all other TOSCA base node types derive from.
- attributes:
- tosca_id:
- type: string
- tosca_name:
- type: string
- state:
- type: string
- capabilities:
- feature:
- type: tosca.capabilities.Node
- requirements:
- - dependency:
- capability: tosca.capabilities.Node
- node: tosca.nodes.Root
- relationship: tosca.relationships.DependsOn
- occurrences: [ 0, UNBOUNDED ]
- interfaces:
- Standard:
- type: tosca.interfaces.node.lifecycle.Standard
-
-tosca.nodes.Compute:
- derived_from: tosca.nodes.Root
- attributes:
- private_address:
- type: string
- public_address:
- type: string
- networks:
- type: map
- entry_schema:
- type: tosca.datatypes.network.NetworkInfo
- ports:
- type: map
- entry_schema:
- type: tosca.datatypes.network.PortInfo
- capabilities:
+node_types:
+ tosca.nodes.Root:
+ description: >
+ The TOSCA root node all other TOSCA base node types derive from.
+ attributes:
+ tosca_id:
+ type: string
+ tosca_name:
+ type: string
+ state:
+ type: string
+ capabilities:
+ feature:
+ type: tosca.capabilities.Node
+ requirements:
+ - dependency:
+ capability: tosca.capabilities.Node
+ node: tosca.nodes.Root
+ relationship: tosca.relationships.DependsOn
+ occurrences: [ 0, UNBOUNDED ]
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+
+ tosca.nodes.Compute:
+ derived_from: tosca.nodes.Root
+ attributes:
+ private_address:
+ type: string
+ public_address:
+ type: string
+ networks:
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.NetworkInfo
+ ports:
+ type: map
+ entry_schema:
+ type: tosca.datatypes.network.PortInfo
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ binding:
+ type: tosca.capabilities.network.Bindable
+ os:
+ type: tosca.capabilities.OperatingSystem
+ scalable:
+ type: tosca.capabilities.Scalable
+ requirements:
+ - local_storage:
+ capability: tosca.capabilities.Attachment
+ node: tosca.nodes.BlockStorage
+ relationship: tosca.relationships.AttachesTo
+ occurrences: [0, UNBOUNDED]
+
+ tosca.nodes.SoftwareComponent:
+ derived_from: tosca.nodes.Root
+ properties:
+ # domain-specific software component version
+ component_version:
+ type: version
+ required: false
+ description: >
+ Software component version.
+ admin_credential:
+ type: tosca.datatypes.Credential
+ required: false
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.Compute
+ relationship: tosca.relationships.HostedOn
+
+ tosca.nodes.DBMS:
+ derived_from: tosca.nodes.SoftwareComponent
+ properties:
+ port:
+ required: false
+ type: integer
+ description: >
+ The port the DBMS service will listen to for data and requests.
+ root_password:
+ required: false
+ type: string
+ description: >
+ The root password for the DBMS service.
+ capabilities:
host:
- type: tosca.capabilities.Container
- binding:
- type: tosca.capabilities.network.Bindable
- os:
- type: tosca.capabilities.OperatingSystem
- scalable:
- type: tosca.capabilities.Scalable
- requirements:
- - local_storage:
- capability: tosca.capabilities.Attachment
- node: tosca.nodes.BlockStorage
- relationship: tosca.relationships.AttachesTo
- occurrences: [0, UNBOUNDED]
+ type: tosca.capabilities.Container
+ valid_source_types: [tosca.nodes.Database]
+
+ tosca.nodes.Database:
+ derived_from: tosca.nodes.Root
+ properties:
+ user:
+ required: false
+ type: string
+ description: >
+ User account name for DB administration
+ port:
+ required: false
+ type: integer
+ description: >
+ The port the database service will use to listen for incoming data and
+ requests.
+ name:
+ required: false
+ type: string
+ description: >
+ The name of the database.
+ password:
+ required: false
+ type: string
+ description: >
+ The password for the DB user account
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.DBMS
+ relationship: tosca.relationships.HostedOn
+ capabilities:
+ database_endpoint:
+ type: tosca.capabilities.Endpoint.Database
+
+ tosca.nodes.WebServer:
+ derived_from: tosca.nodes.SoftwareComponent
+ capabilities:
+ data_endpoint:
+ type: tosca.capabilities.Endpoint
+ admin_endpoint:
+ type: tosca.capabilities.Endpoint.Admin
+ host:
+ type: tosca.capabilities.Container
+ valid_source_types: [tosca.nodes.WebApplication]
-tosca.nodes.SoftwareComponent:
- derived_from: tosca.nodes.Root
- properties:
- # domain-specific software component version
- component_version:
- type: version
- required: false
- description: >
- Software component version.
- admin_credential:
- type: tosca.datatypes.Credential
- required: false
- requirements:
- - host:
- capability: tosca.capabilities.Container
- node: tosca.nodes.Compute
- relationship: tosca.relationships.HostedOn
-
-tosca.nodes.DBMS:
- derived_from: tosca.nodes.SoftwareComponent
- properties:
- port:
- required: false
- type: integer
- description: >
- The port the DBMS service will listen to for data and requests.
- root_password:
- required: false
- type: string
- description: >
- The root password for the DBMS service.
- capabilities:
- host:
- type: tosca.capabilities.Container
- valid_source_types: [tosca.nodes.Database]
-
-tosca.nodes.Database:
- derived_from: tosca.nodes.Root
- properties:
- user:
- required: false
- type: string
- description: >
- User account name for DB administration
- port:
- required: false
- type: integer
- description: >
- The port the database service will use to listen for incoming data and
- requests.
- name:
- required: false
- type: string
- description: >
- The name of the database.
- password:
- required: false
- type: string
- description: >
- The password for the DB user account
- requirements:
- - host:
- capability: tosca.capabilities.Container
- node: tosca.nodes.DBMS
- relationship: tosca.relationships.HostedOn
- capabilities:
- database_endpoint:
- type: tosca.capabilities.Endpoint.Database
-
-tosca.nodes.WebServer:
- derived_from: tosca.nodes.SoftwareComponent
- capabilities:
- data_endpoint:
- type: tosca.capabilities.Endpoint
- admin_endpoint:
- type: tosca.capabilities.Endpoint.Admin
- host:
- type: tosca.capabilities.Container
- valid_source_types: [tosca.nodes.WebApplication]
-
-tosca.nodes.WebApplication:
- derived_from: tosca.nodes.Root
- properties:
- context_root:
- type: string
- required: false
- requirements:
- - host:
- capability: tosca.capabilities.Container
- node: tosca.nodes.WebServer
- relationship: tosca.relationships.HostedOn
- capabilities:
- app_endpoint:
- type: tosca.capabilities.Endpoint
-
-tosca.nodes.BlockStorage:
- derived_from: tosca.nodes.Root
- properties:
- size:
- type: scalar-unit.size
- constraints:
- - greater_or_equal: 1 MB
- volume_id:
- type: string
- required: false
- snapshot_id:
- type: string
- required: false
- attributes:
- volume_id:
- type: string
- capabilities:
- attachment:
- type: tosca.capabilities.Attachment
-
-tosca.nodes.network.Network:
- derived_from: tosca.nodes.Root
- description: >
- The TOSCA Network node represents a simple, logical network service.
- properties:
- ip_version:
- type: integer
- required: false
- default: 4
- constraints:
- - valid_values: [ 4, 6 ]
- description: >
- The IP version of the requested network. Valid values are 4 for ipv4
- or 6 for ipv6.
- cidr:
- type: string
- required: false
- description: >
- The cidr block of the requested network.
- start_ip:
- type: string
- required: false
- description: >
- The IP address to be used as the start of a pool of addresses within
- the full IP range derived from the cidr block.
- end_ip:
- type: string
- required: false
- description: >
- The IP address to be used as the end of a pool of addresses within
- the full IP range derived from the cidr block.
- gateway_ip:
- type: string
- required: false
- description: >
- The gateway IP address.
- network_name:
- type: string
- required: false
- description: >
- An identifier that represents an existing Network instance in the
- underlying cloud infrastructure or can be used as the name of the
- newly created network. If network_name is provided and no other
- properties are provided (with exception of network_id), then an
- existing network instance will be used. If network_name is provided
- alongside with more properties then a new network with this name will
- be created.
- network_id:
- type: string
- required: false
- description: >
- An identifier that represents an existing Network instance in the
- underlying cloud infrastructure. This property is mutually exclusive
- with all other properties except network_name. This can be used alone
- or together with network_name to identify an existing network.
- segmentation_id:
- type: string
- required: false
- description: >
- A segmentation identifier in the underlying cloud infrastructure.
- E.g. VLAN ID, GRE tunnel ID, etc..
- network_type:
- type: string
- required: false
- description: >
- It specifies the nature of the physical network in the underlying
- cloud infrastructure. Examples are flat, vlan, gre or vxlan.
- For flat and vlan types, physical_network should be provided too.
- physical_network:
- type: string
- required: false
- description: >
- It identifies the physical network on top of which the network is
- implemented, e.g. physnet1. This property is required if network_type
- is flat or vlan.
- dhcp_enabled:
- type: boolean
- required: false
- default: true
- description: >
- Indicates should DHCP service be enabled on the network or not.
- capabilities:
- link:
- type: tosca.capabilities.network.Linkable
-
-tosca.nodes.network.Port:
- derived_from: tosca.nodes.Root
- description: >
- The TOSCA Port node represents a logical entity that associates between
- Compute and Network normative types. The Port node type effectively
- represents a single virtual NIC on the Compute node instance.
- properties:
- ip_address:
- type: string
- required: false
- description: >
- Allow the user to set a static IP.
- order:
- type: integer
- required: false
- default: 0
- constraints:
- - greater_or_equal: 0
- description: >
- The order of the NIC on the compute instance (e.g. eth2).
- is_default:
- type: boolean
- required: false
- default: false
- description: >
- If is_default=true this port will be used for the default gateway
- route. Only one port that is associated to single compute node can
- set as is_default=true.
- ip_range_start:
- type: string
- required: false
- description: >
- Defines the starting IP of a range to be allocated for the compute
- instances that are associated with this Port.
- ip_range_end:
- type: string
- required: false
- description: >
- Defines the ending IP of a range to be allocated for the compute
- instances that are associated with this Port.
- attributes:
- ip_address:
- type: string
- requirements:
- - binding:
- description: >
- Binding requirement expresses the relationship between Port and
- Compute nodes. Effectively it indicates that the Port will be
- attached to specific Compute node instance
- capability: tosca.capabilities.network.Bindable
- relationship: tosca.relationships.network.BindsTo
- node: tosca.nodes.Compute
- - link:
- description: >
- Link requirement expresses the relationship between Port and Network
- nodes. It indicates which network this port will connect to.
- capability: tosca.capabilities.network.Linkable
- relationship: tosca.relationships.network.LinksTo
- node: tosca.nodes.network.Network
-
-tosca.nodes.ObjectStorage:
- derived_from: tosca.nodes.Root
- description: >
- The TOSCA ObjectStorage node represents storage that provides the ability
- to store data as objects (or BLOBs of data) without consideration for the
- underlying filesystem or devices
- properties:
- name:
- type: string
- required: true
- description: >
- The logical name of the object store (or container).
- size:
- type: scalar-unit.size
- required: false
- constraints:
- - greater_or_equal: 0 GB
- description: >
- The requested initial storage size.
- maxsize:
- type: scalar-unit.size
- required: false
- constraints:
- - greater_or_equal: 0 GB
- description: >
- The requested maximum storage size.
- capabilities:
- storage_endpoint:
- type: tosca.capabilities.Endpoint
-
-tosca.nodes.LoadBalancer:
- derived_from: tosca.nodes.Root
- properties:
- algorithm:
- type: string
- required: false
- status: experimental
- capabilities:
- client:
- type: tosca.capabilities.Endpoint.Public
- occurrences: [0, UNBOUNDED]
- description: the Floating (IP) client’s on the public network can connect to
- requirements:
- - application:
- capability: tosca.capabilities.Endpoint
- relationship: tosca.relationships.RoutesTo
+ tosca.nodes.WebApplication:
+ derived_from: tosca.nodes.Root
+ properties:
+ context_root:
+ type: string
+ required: false
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.WebServer
+ relationship: tosca.relationships.HostedOn
+ capabilities:
+ app_endpoint:
+ type: tosca.capabilities.Endpoint
+
+ tosca.nodes.BlockStorage:
+ derived_from: tosca.nodes.Root
+ properties:
+ size:
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 1 MB
+ volume_id:
+ type: string
+ required: false
+ snapshot_id:
+ type: string
+ required: false
+ attributes:
+ volume_id:
+ type: string
+ capabilities:
+ attachment:
+ type: tosca.capabilities.Attachment
+
+ tosca.nodes.network.Network:
+ derived_from: tosca.nodes.Root
+ description: >
+ The TOSCA Network node represents a simple, logical network service.
+ properties:
+ ip_version:
+ type: integer
+ required: false
+ default: 4
+ constraints:
+ - valid_values: [ 4, 6 ]
+ description: >
+ The IP version of the requested network. Valid values are 4 for ipv4
+ or 6 for ipv6.
+ cidr:
+ type: string
+ required: false
+ description: >
+ The cidr block of the requested network.
+ start_ip:
+ type: string
+ required: false
+ description: >
+ The IP address to be used as the start of a pool of addresses within
+ the full IP range derived from the cidr block.
+ end_ip:
+ type: string
+ required: false
+ description: >
+ The IP address to be used as the end of a pool of addresses within
+ the full IP range derived from the cidr block.
+ gateway_ip:
+ type: string
+ required: false
+ description: >
+ The gateway IP address.
+ network_name:
+ type: string
+ required: false
+ description: >
+ An identifier that represents an existing Network instance in the
+ underlying cloud infrastructure or can be used as the name of the
+ newly created network. If network_name is provided and no other
+ properties are provided (with exception of network_id), then an
+ existing network instance will be used. If network_name is provided
+ alongside with more properties then a new network with this name will
+ be created.
+ network_id:
+ type: string
+ required: false
+ description: >
+ An identifier that represents an existing Network instance in the
+ underlying cloud infrastructure. This property is mutually exclusive
+ with all other properties except network_name. This can be used alone
+ or together with network_name to identify an existing network.
+ segmentation_id:
+ type: string
+ required: false
+ description: >
+ A segmentation identifier in the underlying cloud infrastructure.
+ E.g. VLAN ID, GRE tunnel ID, etc..
+ network_type:
+ type: string
+ required: false
+ description: >
+ It specifies the nature of the physical network in the underlying
+ cloud infrastructure. Examples are flat, vlan, gre or vxlan.
+ For flat and vlan types, physical_network should be provided too.
+ physical_network:
+ type: string
+ required: false
+ description: >
+ It identifies the physical network on top of which the network is
+ implemented, e.g. physnet1. This property is required if network_type
+ is flat or vlan.
+ dhcp_enabled:
+ type: boolean
+ required: false
+ default: true
+ description: >
+ Indicates should DHCP service be enabled on the network or not.
+ capabilities:
+ link:
+ type: tosca.capabilities.network.Linkable
+
+ tosca.nodes.network.Port:
+ derived_from: tosca.nodes.Root
+ description: >
+ The TOSCA Port node represents a logical entity that associates between
+ Compute and Network normative types. The Port node type effectively
+ represents a single virtual NIC on the Compute node instance.
+ properties:
+ ip_address:
+ type: string
+ required: false
+ description: >
+ Allow the user to set a static IP.
+ order:
+ type: integer
+ required: false
+ default: 0
+ constraints:
+ - greater_or_equal: 0
+ description: >
+ The order of the NIC on the compute instance (e.g. eth2).
+ is_default:
+ type: boolean
+ required: false
+ default: false
+ description: >
+ If is_default=true this port will be used for the default gateway
+ route. Only one port that is associated to single compute node can
+ set as is_default=true.
+ ip_range_start:
+ type: string
+ required: false
+ description: >
+ Defines the starting IP of a range to be allocated for the compute
+ instances that are associated with this Port.
+ ip_range_end:
+ type: string
+ required: false
+ description: >
+ Defines the ending IP of a range to be allocated for the compute
+ instances that are associated with this Port.
+ attributes:
+ ip_address:
+ type: string
+ requirements:
+ - binding:
+ description: >
+ Binding requirement expresses the relationship between Port and
+ Compute nodes. Effectively it indicates that the Port will be
+ attached to specific Compute node instance
+ capability: tosca.capabilities.network.Bindable
+ relationship: tosca.relationships.network.BindsTo
+ node: tosca.nodes.Compute
+ - link:
+ description: >
+ Link requirement expresses the relationship between Port and Network
+ nodes. It indicates which network this port will connect to.
+ capability: tosca.capabilities.network.Linkable
+ relationship: tosca.relationships.network.LinksTo
+ node: tosca.nodes.network.Network
+
+ tosca.nodes.ObjectStorage:
+ derived_from: tosca.nodes.Root
+ description: >
+ The TOSCA ObjectStorage node represents storage that provides the ability
+ to store data as objects (or BLOBs of data) without consideration for the
+ underlying filesystem or devices
+ properties:
+ name:
+ type: string
+ required: true
+ description: >
+ The logical name of the object store (or container).
+ size:
+ type: scalar-unit.size
+ required: false
+ constraints:
+ - greater_or_equal: 0 GB
+ description: >
+ The requested initial storage size.
+ maxsize:
+ type: scalar-unit.size
+ required: false
+ constraints:
+ - greater_or_equal: 0 GB
+ description: >
+ The requested maximum storage size.
+ capabilities:
+ storage_endpoint:
+ type: tosca.capabilities.Endpoint
+
+ tosca.nodes.LoadBalancer:
+ derived_from: tosca.nodes.Root
+ properties:
+ algorithm:
+ type: string
+ required: false
+ status: experimental
+ capabilities:
+ client:
+ type: tosca.capabilities.Endpoint.Public
occurrences: [0, UNBOUNDED]
- description: Connection to one or more load balanced applications
-
-tosca.nodes.Container.Application:
- derived_from: tosca.nodes.Root
- requirements:
- - host:
- capability: tosca.capabilities.Container
- node: tosca.nodes.Container.Runtime
- relationship: tosca.relationships.HostedOn
-
-tosca.nodes.Container.Runtime:
- derived_from: tosca.nodes.SoftwareComponent
- capabilities:
- host:
- type: tosca.capabilities.Container
- scalable:
- type: tosca.capabilities.Scalable
-
-tosca.nodes.Container.Application.Docker:
- derived_from: tosca.nodes.Container.Application
- requirements:
- - host:
- capability: tosca.capabilities.Container.Docker
+ description: the Floating (IP) client’s on the public network can connect to
+ requirements:
+ - application:
+ capability: tosca.capabilities.Endpoint
+ relationship: tosca.relationships.RoutesTo
+ occurrences: [0, UNBOUNDED]
+ description: Connection to one or more load balanced applications
+
+ tosca.nodes.Container.Application:
+ derived_from: tosca.nodes.Root
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container
+ node: tosca.nodes.Container.Runtime
+ relationship: tosca.relationships.HostedOn
+
+ tosca.nodes.Container.Runtime:
+ derived_from: tosca.nodes.SoftwareComponent
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ scalable:
+ type: tosca.capabilities.Scalable
+
+ tosca.nodes.Container.Application.Docker:
+ derived_from: tosca.nodes.Container.Application
+ requirements:
+ - host:
+ capability: tosca.capabilities.Container.Docker
##########################################################################
# Relationship Type.
# A Relationship Type is a reusable entity that defines the type of one
# or more relationships between Node Types or Node Templates.
##########################################################################
-tosca.relationships.Root:
- description: >
- The TOSCA root Relationship Type all other TOSCA base Relationship Types
- derive from.
- attributes:
- tosca_id:
- type: string
- tosca_name:
- type: string
- interfaces:
- Configure:
- type: tosca.interfaces.relationship.Configure
-
-tosca.relationships.DependsOn:
- derived_from: tosca.relationships.Root
-
-tosca.relationships.HostedOn:
- derived_from: tosca.relationships.Root
- valid_target_types: [ tosca.capabilities.Container ]
-
-tosca.relationships.ConnectsTo:
- derived_from: tosca.relationships.Root
- valid_target_types: [ tosca.capabilities.Endpoint ]
- credential:
- type: tosca.datatypes.Credential
- required: false
-
-tosca.relationships.AttachesTo:
- derived_from: tosca.relationships.Root
- valid_target_types: [ tosca.capabilities.Attachment ]
- properties:
- location:
- required: true
- type: string
- constraints:
- - min_length: 1
- device:
+relationship_types:
+ tosca.relationships.Root:
+ description: >
+ The TOSCA root Relationship Type all other TOSCA base Relationship Types
+ derive from.
+ attributes:
+ tosca_id:
+ type: string
+ tosca_name:
+ type: string
+ interfaces:
+ Configure:
+ type: tosca.interfaces.relationship.Configure
+
+ tosca.relationships.DependsOn:
+ derived_from: tosca.relationships.Root
+
+ tosca.relationships.HostedOn:
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Container ]
+
+ tosca.relationships.ConnectsTo:
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Endpoint ]
+ credential:
+ type: tosca.datatypes.Credential
required: false
- type: string
-tosca.relationships.RoutesTo:
- derived_from: tosca.relationships.ConnectsTo
- valid_target_types: [ tosca.capabilities.Endpoint ]
+ tosca.relationships.AttachesTo:
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.Attachment ]
+ properties:
+ location:
+ required: true
+ type: string
+ constraints:
+ - min_length: 1
+ device:
+ required: false
+ type: string
-tosca.relationships.network.LinksTo:
- derived_from: tosca.relationships.DependsOn
- valid_target_types: [ tosca.capabilities.network.Linkable ]
+ tosca.relationships.RoutesTo:
+ derived_from: tosca.relationships.ConnectsTo
+ valid_target_types: [ tosca.capabilities.Endpoint ]
-tosca.relationships.network.BindsTo:
- derived_from: tosca.relationships.DependsOn
- valid_target_types: [ tosca.capabilities.network.Bindable ]
+ tosca.relationships.network.LinksTo:
+ derived_from: tosca.relationships.DependsOn
+ valid_target_types: [ tosca.capabilities.network.Linkable ]
+
+ tosca.relationships.network.BindsTo:
+ derived_from: tosca.relationships.DependsOn
+ valid_target_types: [ tosca.capabilities.network.Bindable ]
##########################################################################
# Capability Type.
# A Capability Type is a reusable entity that describes a kind of
# capability that a Node Type can declare to expose.
##########################################################################
-tosca.capabilities.Root:
- description: >
- The TOSCA root Capability Type all other TOSCA base Capability Types
- derive from.
-
-tosca.capabilities.Node:
- derived_from: tosca.capabilities.Root
-
-tosca.capabilities.Container:
- derived_from: tosca.capabilities.Root
- properties:
- num_cpus:
- required: false
- type: integer
- constraints:
- - greater_or_equal: 1
- cpu_frequency:
- required: false
- type: scalar-unit.frequency
- constraints:
- - greater_or_equal: 0.1 GHz
- disk_size:
- required: false
- type: scalar-unit.size
- constraints:
- - greater_or_equal: 0 MB
- mem_size:
- required: false
- type: scalar-unit.size
- constraints:
- - greater_or_equal: 0 MB
-
-tosca.capabilities.Endpoint:
- derived_from: tosca.capabilities.Root
- properties:
- protocol:
- type: string
- required: true
- default: tcp
- port:
- type: tosca.datatypes.network.PortDef
- required: false
- secure:
- type: boolean
- required: false
- default: false
- url_path:
- type: string
- required: false
- port_name:
- type: string
- required: false
- network_name:
- type: string
- required: false
- initiator:
- type: string
- required: false
- default: source
- constraints:
- - valid_values: [source, target, peer]
- ports:
- type: map
- required: false
- constraints:
- - min_length: 1
- entry_schema:
- type: tosca.datatypes.network.PortSpec
- attributes:
- ip_address:
- type: string
-
-tosca.capabilities.Endpoint.Admin:
- derived_from: tosca.capabilities.Endpoint
- properties:
- secure:
- type: boolean
- default: true
- constraints:
- - equal: true
-
-tosca.capabilities.Endpoint.Public:
- derived_from: tosca.capabilities.Endpoint
- properties:
- # Change the default network_name to use the first public network found
- network_name:
- type: string
- default: PUBLIC
- constraints:
- - equal: PUBLIC
- floating:
- description: >
- Indicates that the public address should be allocated from a pool of
- floating IPs that are associated with the network.
- type: boolean
- default: false
- status: experimental
- dns_name:
- description: The optional name to register with DNS
- type: string
- required: false
- status: experimental
-
-tosca.capabilities.Scalable:
- derived_from: tosca.capabilities.Root
- properties:
- min_instances:
- type: integer
- required: true
- default: 1
- description: >
- This property is used to indicate the minimum number of instances
- that should be created for the associated TOSCA Node Template by
- a TOSCA orchestrator.
- max_instances:
- type: integer
- required: true
- default: 1
- description: >
- This property is used to indicate the maximum number of instances
- that should be created for the associated TOSCA Node Template by
- a TOSCA orchestrator.
- default_instances:
- type: integer
- required: false
- description: >
- An optional property that indicates the requested default number
- of instances that should be the starting number of instances a
- TOSCA orchestrator should attempt to allocate.
- The value for this property MUST be in the range between the values
- set for min_instances and max_instances properties.
-
-tosca.capabilities.Endpoint.Database:
- derived_from: tosca.capabilities.Endpoint
-
-tosca.capabilities.Attachment:
- derived_from: tosca.capabilities.Root
-
-tosca.capabilities.network.Linkable:
- derived_from: tosca.capabilities.Root
- description: >
- A node type that includes the Linkable capability indicates that it can
- be pointed by tosca.relationships.network.LinksTo relationship type, which
- represents an association relationship between Port and Network node types.
-
-tosca.capabilities.network.Bindable:
- derived_from: tosca.capabilities.Root
- description: >
- A node type that includes the Bindable capability indicates that it can
- be pointed by tosca.relationships.network.BindsTo relationship type, which
- represents a network association relationship between Port and Compute node
- types.
-
-tosca.capabilities.OperatingSystem:
- derived_from: tosca.capabilities.Root
- properties:
- architecture:
- required: false
- type: string
- description: >
- The host Operating System (OS) architecture.
- type:
- required: false
- type: string
- description: >
- The host Operating System (OS) type.
- distribution:
- required: false
- type: string
- description: >
- The host Operating System (OS) distribution. Examples of valid values
- for an “type” of “Linux” would include:
- debian, fedora, rhel and ubuntu.
- version:
- required: false
- type: version
- description: >
- The host Operating System version.
-
-tosca.capabilities.Container.Docker:
- derived_from: tosca.capabilities.Container
- properties:
- version:
- type: list
- required: false
- entry_schema:
+capability_types:
+ tosca.capabilities.Root:
+ description: >
+ The TOSCA root Capability Type all other TOSCA base Capability Types
+ derive from.
+
+ tosca.capabilities.Node:
+ derived_from: tosca.capabilities.Root
+
+ tosca.capabilities.Container:
+ derived_from: tosca.capabilities.Root
+ properties:
+ num_cpus:
+ required: false
+ type: integer
+ constraints:
+ - greater_or_equal: 1
+ cpu_frequency:
+ required: false
+ type: scalar-unit.frequency
+ constraints:
+ - greater_or_equal: 0.1 GHz
+ disk_size:
+ required: false
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 MB
+ mem_size:
+ required: false
+ type: scalar-unit.size
+ constraints:
+ - greater_or_equal: 0 MB
+
+ tosca.capabilities.Endpoint:
+ derived_from: tosca.capabilities.Root
+ properties:
+ protocol:
+ type: string
+ required: true
+ default: tcp
+ port:
+ type: tosca.datatypes.network.PortDef
+ required: false
+ secure:
+ type: boolean
+ required: false
+ default: false
+ url_path:
+ type: string
+ required: false
+ port_name:
+ type: string
+ required: false
+ network_name:
+ type: string
+ required: false
+ initiator:
+ type: string
+ required: false
+ default: source
+ constraints:
+ - valid_values: [source, target, peer]
+ ports:
+ type: map
+ required: false
+ constraints:
+ - min_length: 1
+ entry_schema:
+ type: tosca.datatypes.network.PortSpec
+ attributes:
+ ip_address:
+ type: string
+
+ tosca.capabilities.Endpoint.Admin:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ secure:
+ type: boolean
+ default: true
+ constraints:
+ - equal: true
+
+ tosca.capabilities.Endpoint.Public:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ # Change the default network_name to use the first public network found
+ network_name:
+ type: string
+ default: PUBLIC
+ constraints:
+ - equal: PUBLIC
+ floating:
+ description: >
+ Indicates that the public address should be allocated from a pool of
+ floating IPs that are associated with the network.
+ type: boolean
+ default: false
+ status: experimental
+ dns_name:
+ description: The optional name to register with DNS
+ type: string
+ required: false
+ status: experimental
+
+ tosca.capabilities.Scalable:
+ derived_from: tosca.capabilities.Root
+ properties:
+ min_instances:
+ type: integer
+ required: true
+ default: 1
+ description: >
+ This property is used to indicate the minimum number of instances
+ that should be created for the associated TOSCA Node Template by
+ a TOSCA orchestrator.
+ max_instances:
+ type: integer
+ required: true
+ default: 1
+ description: >
+ This property is used to indicate the maximum number of instances
+ that should be created for the associated TOSCA Node Template by
+ a TOSCA orchestrator.
+ default_instances:
+ type: integer
+ required: false
+ description: >
+ An optional property that indicates the requested default number
+ of instances that should be the starting number of instances a
+ TOSCA orchestrator should attempt to allocate.
+ The value for this property MUST be in the range between the values
+ set for min_instances and max_instances properties.
+
+ tosca.capabilities.Endpoint.Database:
+ derived_from: tosca.capabilities.Endpoint
+
+ tosca.capabilities.Attachment:
+ derived_from: tosca.capabilities.Root
+
+ tosca.capabilities.network.Linkable:
+ derived_from: tosca.capabilities.Root
+ description: >
+ A node type that includes the Linkable capability indicates that it can
+ be pointed by tosca.relationships.network.LinksTo relationship type, which
+ represents an association relationship between Port and Network node types.
+
+ tosca.capabilities.network.Bindable:
+ derived_from: tosca.capabilities.Root
+ description: >
+ A node type that includes the Bindable capability indicates that it can
+ be pointed by tosca.relationships.network.BindsTo relationship type, which
+ represents a network association relationship between Port and Compute node
+ types.
+
+ tosca.capabilities.OperatingSystem:
+ derived_from: tosca.capabilities.Root
+ properties:
+ architecture:
+ required: false
+ type: string
+ description: >
+ The host Operating System (OS) architecture.
+ type:
+ required: false
+ type: string
+ description: >
+ The host Operating System (OS) type.
+ distribution:
+ required: false
+ type: string
+ description: >
+ The host Operating System (OS) distribution. Examples of valid values
+ for an “type” of “Linux” would include:
+ debian, fedora, rhel and ubuntu.
+ version:
+ required: false
type: version
- description: >
- The Docker version capability.
- publish_all:
- type: boolean
- default: false
- required: false
- description: >
- Indicates that all ports (ranges) listed in the dockerfile
- using the EXPOSE keyword be published.
- publish_ports:
- type: list
- entry_schema:
- type: PortSpec
- required: false
- description: >
- List of ports mappings from source (Docker container)
- to target (host) ports to publish.
- expose_ports:
- type: list
- entry_schema:
- type: PortSpec
- required: false
- description: >
- List of ports mappings from source (Docker container) to expose
- to other Docker containers (not accessible outside host).
- volumes:
- type: list
- entry_schema:
+ description: >
+ The host Operating System version.
+
+ tosca.capabilities.Container.Docker:
+ derived_from: tosca.capabilities.Container
+ properties:
+ version:
+ type: list
+ required: false
+ entry_schema:
+ type: version
+ description: >
+ The Docker version capability.
+ publish_all:
+ type: boolean
+ default: false
+ required: false
+ description: >
+ Indicates that all ports (ranges) listed in the dockerfile
+ using the EXPOSE keyword be published.
+ publish_ports:
+ type: list
+ entry_schema:
+ type: PortSpec
+ required: false
+ description: >
+ List of ports mappings from source (Docker container)
+ to target (host) ports to publish.
+ expose_ports:
+ type: list
+ entry_schema:
+ type: PortSpec
+ required: false
+ description: >
+ List of ports mappings from source (Docker container) to expose
+ to other Docker containers (not accessible outside host).
+ volumes:
+ type: list
+ entry_schema:
+ type: string
+ required: false
+ description: >
+ The dockerfile VOLUME command which is used to enable access
+ from the Docker container to a directory on the host machine.
+ host_id:
type: string
- required: false
- description: >
- The dockerfile VOLUME command which is used to enable access
- from the Docker container to a directory on the host machine.
- host_id:
- type: string
- required: false
- description: >
- The optional identifier of an existing host resource
- that should be used to run this container on.
- volume_id:
- type: string
- required: false
- description: >
- The optional identifier of an existing storage volume (resource)
- that should be used to create the container's mount point(s) on.
+ required: false
+ description: >
+ The optional identifier of an existing host resource
+ that should be used to run this container on.
+ volume_id:
+ type: string
+ required: false
+ description: >
+ The optional identifier of an existing storage volume (resource)
+ that should be used to create the container's mount point(s) on.
##########################################################################
# Interfaces Type.
@@ -708,129 +711,131 @@ tosca.capabilities.Container.Docker:
# definitions for a modelable entity (e.g., a Node or Relationship Type)
# as defined within the TOSCA Simple Profile specification.
##########################################################################
-tosca.interfaces.node.lifecycle.Standard:
- create:
- description: Standard lifecycle create operation.
- configure:
- description: Standard lifecycle configure operation.
- start:
- description: Standard lifecycle start operation.
- stop:
- description: Standard lifecycle stop operation.
- delete:
- description: Standard lifecycle delete operation.
-
-tosca.interfaces.relationship.Configure:
- pre_configure_source:
- description: Operation to pre-configure the source endpoint.
- pre_configure_target:
- description: Operation to pre-configure the target endpoint.
- post_configure_source:
- description: Operation to post-configure the source endpoint.
- post_configure_target:
- description: Operation to post-configure the target endpoint.
- add_target:
- description: Operation to add a target node.
- remove_target:
- description: Operation to remove a target node.
- add_source: >
- description: Operation to notify the target node of a source node which
- is now available via a relationship.
- description:
- target_changed: >
- description: Operation to notify source some property or attribute of the
- target changed
+interface_types:
+ tosca.interfaces.node.lifecycle.Standard:
+ create:
+ description: Standard lifecycle create operation.
+ configure:
+ description: Standard lifecycle configure operation.
+ start:
+ description: Standard lifecycle start operation.
+ stop:
+ description: Standard lifecycle stop operation.
+ delete:
+ description: Standard lifecycle delete operation.
+
+ tosca.interfaces.relationship.Configure:
+ pre_configure_source:
+ description: Operation to pre-configure the source endpoint.
+ pre_configure_target:
+ description: Operation to pre-configure the target endpoint.
+ post_configure_source:
+ description: Operation to post-configure the source endpoint.
+ post_configure_target:
+ description: Operation to post-configure the target endpoint.
+ add_target:
+ description: Operation to add a target node.
+ remove_target:
+ description: Operation to remove a target node.
+ add_source: >
+ description: Operation to notify the target node of a source node which
+ is now available via a relationship.
+ description:
+ target_changed: >
+ description: Operation to notify source some property or attribute of the
+ target changed
##########################################################################
# Data Type.
# A Datatype is a complex data type declaration which contains other
# complex or simple data types.
##########################################################################
-tosca.datatypes.Root:
- description: >
- The TOSCA root Data Type all other TOSCA base Data Types derive from
-
-tosca.datatypes.network.NetworkInfo:
- derived_from: tosca.datatypes.Root
- properties:
- network_name:
- type: string
- network_id:
- type: string
- addresses:
- type: list
- entry_schema:
- type: string
-
-tosca.datatypes.network.PortInfo:
- derived_from: tosca.datatypes.Root
- properties:
- port_name:
- type: string
- port_id:
- type: string
- network_id:
- type: string
- mac_address:
- type: string
- addresses:
- type: list
- entry_schema:
- type: string
-
-tosca.datatypes.network.PortDef:
- derived_from: tosca.datatypes.Root
- type: integer
- constraints:
- - in_range: [ 1, 65535 ]
-
-tosca.datatypes.network.PortSpec:
- derived_from: tosca.datatypes.Root
- properties:
- protocol:
- type: string
- required: true
- default: tcp
- constraints:
- - valid_values: [ udp, tcp, igmp ]
- target:
- type: PortDef
- required: false
- target_range:
- type: range
- required: false
- constraints:
- - in_range: [ 1, 65535 ]
- source:
- type: PortDef
- required: false
- source_range:
- type: range
- required: false
- constraints:
- - in_range: [ 1, 65535 ]
-
-tosca.datatypes.Credential:
- derived_from: tosca.datatypes.Root
- properties:
- protocol:
- type: string
- required: false
- token_type:
- type: string
- default: password
- required: true
- token:
- type: string
- required: true
- keys:
- type: map
- entry_schema:
+data_types:
+ tosca.datatypes.Root:
+ description: >
+ The TOSCA root Data Type all other TOSCA base Data Types derive from
+
+ tosca.datatypes.network.NetworkInfo:
+ derived_from: tosca.datatypes.Root
+ properties:
+ network_name:
type: string
- required: false
- user:
- type: string
- required: false
+ network_id:
+ type: string
+ addresses:
+ type: list
+ entry_schema:
+ type: string
+
+ tosca.datatypes.network.PortInfo:
+ derived_from: tosca.datatypes.Root
+ properties:
+ port_name:
+ type: string
+ port_id:
+ type: string
+ network_id:
+ type: string
+ mac_address:
+ type: string
+ addresses:
+ type: list
+ entry_schema:
+ type: string
+
+ tosca.datatypes.network.PortDef:
+ derived_from: tosca.datatypes.Root
+ type: integer
+ constraints:
+ - in_range: [ 1, 65535 ]
+
+ tosca.datatypes.network.PortSpec:
+ derived_from: tosca.datatypes.Root
+ properties:
+ protocol:
+ type: string
+ required: true
+ default: tcp
+ constraints:
+ - valid_values: [ udp, tcp, igmp ]
+ target:
+ type: PortDef
+ required: false
+ target_range:
+ type: range
+ required: false
+ constraints:
+ - in_range: [ 1, 65535 ]
+ source:
+ type: PortDef
+ required: false
+ source_range:
+ type: range
+ required: false
+ constraints:
+ - in_range: [ 1, 65535 ]
+
+ tosca.datatypes.Credential:
+ derived_from: tosca.datatypes.Root
+ properties:
+ protocol:
+ type: string
+ required: false
+ token_type:
+ type: string
+ default: password
+ required: true
+ token:
+ type: string
+ required: true
+ keys:
+ type: map
+ entry_schema:
+ type: string
+ required: false
+ user:
+ type: string
+ required: false
##########################################################################
# Artifact Type.
@@ -838,56 +843,57 @@ tosca.datatypes.Credential:
# files which Node Types or Node Templates can have dependent relationships
# and used during operations such as during installation or deployment.
##########################################################################
-tosca.artifacts.Root:
- description: >
- The TOSCA Artifact Type all other TOSCA Artifact Types derive from
- properties:
- version: version
-
-tosca.artifacts.File:
- derived_from: tosca.artifacts.Root
-
-tosca.artifacts.Deployment:
- derived_from: tosca.artifacts.Root
- description: TOSCA base type for deployment artifacts
-
-tosca.artifacts.Deployment.Image:
- derived_from: tosca.artifacts.Deployment
-
-tosca.artifacts.Deployment.Image.VM:
- derived_from: tosca.artifacts.Deployment.Image
-
-tosca.artifacts.Implementation:
- derived_from: tosca.artifacts.Root
- description: TOSCA base type for implementation artifacts
-
-tosca.artifacts.Implementation.Bash:
- derived_from: tosca.artifacts.Implementation
- description: Script artifact for the Unix Bash shell
- mime_type: application/x-sh
- file_ext: [ sh ]
-
-tosca.artifacts.Implementation.Python:
- derived_from: tosca.artifacts.Implementation
- description: Artifact for the interpreted Python language
- mime_type: application/x-python
- file_ext: [ py ]
-
-tosca.artifacts.Deployment.Image.Container.Docker:
- derived_from: tosca.artifacts.Deployment.Image
- description: Docker container image
-
-tosca.artifacts.Deployment.Image.VM.ISO:
- derived_from: tosca.artifacts.Deployment.Image
- description: Virtual Machine (VM) image in ISO disk format
- mime_type: application/octet-stream
- file_ext: [ iso ]
-
-tosca.artifacts.Deployment.Image.VM.QCOW2:
- derived_from: tosca.artifacts.Deployment.Image
- description: Virtual Machine (VM) image in QCOW v2 standard disk format
- mime_type: application/octet-stream
- file_ext: [ qcow2 ]
+artifact_types:
+ tosca.artifacts.Root:
+ description: >
+ The TOSCA Artifact Type all other TOSCA Artifact Types derive from
+ properties:
+ version: version
+
+ tosca.artifacts.File:
+ derived_from: tosca.artifacts.Root
+
+ tosca.artifacts.Deployment:
+ derived_from: tosca.artifacts.Root
+ description: TOSCA base type for deployment artifacts
+
+ tosca.artifacts.Deployment.Image:
+ derived_from: tosca.artifacts.Deployment
+
+ tosca.artifacts.Deployment.Image.VM:
+ derived_from: tosca.artifacts.Deployment.Image
+
+ tosca.artifacts.Implementation:
+ derived_from: tosca.artifacts.Root
+ description: TOSCA base type for implementation artifacts
+
+ tosca.artifacts.Implementation.Bash:
+ derived_from: tosca.artifacts.Implementation
+ description: Script artifact for the Unix Bash shell
+ mime_type: application/x-sh
+ file_ext: [ sh ]
+
+ tosca.artifacts.Implementation.Python:
+ derived_from: tosca.artifacts.Implementation
+ description: Artifact for the interpreted Python language
+ mime_type: application/x-python
+ file_ext: [ py ]
+
+ tosca.artifacts.Deployment.Image.Container.Docker:
+ derived_from: tosca.artifacts.Deployment.Image
+ description: Docker container image
+
+ tosca.artifacts.Deployment.Image.VM.ISO:
+ derived_from: tosca.artifacts.Deployment.Image
+ description: Virtual Machine (VM) image in ISO disk format
+ mime_type: application/octet-stream
+ file_ext: [ iso ]
+
+ tosca.artifacts.Deployment.Image.VM.QCOW2:
+ derived_from: tosca.artifacts.Deployment.Image
+ description: Virtual Machine (VM) image in QCOW v2 standard disk format
+ mime_type: application/octet-stream
+ file_ext: [ qcow2 ]
##########################################################################
# Policy Type.
@@ -895,38 +901,39 @@ tosca.artifacts.Deployment.Image.VM.QCOW2:
# an implied relationship and need to be orchestrated or managed together
# to achieve some result.
##########################################################################
-tosca.policies.Root:
- description: The TOSCA Policy Type all other TOSCA Policy Types derive from.
-
-tosca.policies.Placement:
- derived_from: tosca.policies.Root
- description: The TOSCA Policy Type definition that is used to govern
- placement of TOSCA nodes or groups of nodes.
-
-tosca.policies.Placement.Colocate:
- derived_from: tosca.policies.Placement
- description: The TOSCA Policy Type definition that is used to govern
- colocate placement of TOSCA nodes or groups of nodes.
-
-tosca.policies.Placement.Antilocate:
- derived_from: tosca.policies.Placement
- description: The TOSCA Policy Type definition that is used to govern
- anti-locate placement of TOSCA nodes or groups of nodes.
-
-tosca.policies.Scaling:
- derived_from: tosca.policies.Root
- description: The TOSCA Policy Type definition that is used to govern
- scaling of TOSCA nodes or groups of nodes.
-
-tosca.policies.Update:
- derived_from: tosca.policies.Root
- description: The TOSCA Policy Type definition that is used to govern
- update of TOSCA nodes or groups of nodes.
-
-tosca.policies.Performance:
- derived_from: tosca.policies.Root
- description: The TOSCA Policy Type definition that is used to declare
- performance requirements for TOSCA nodes or groups of nodes.
+policy_types:
+ tosca.policies.Root:
+ description: The TOSCA Policy Type all other TOSCA Policy Types derive from.
+
+ tosca.policies.Placement:
+ derived_from: tosca.policies.Root
+ description: The TOSCA Policy Type definition that is used to govern
+ placement of TOSCA nodes or groups of nodes.
+
+ tosca.policies.Placement.Colocate:
+ derived_from: tosca.policies.Placement
+ description: The TOSCA Policy Type definition that is used to govern
+ colocate placement of TOSCA nodes or groups of nodes.
+
+ tosca.policies.Placement.Antilocate:
+ derived_from: tosca.policies.Placement
+ description: The TOSCA Policy Type definition that is used to govern
+ anti-locate placement of TOSCA nodes or groups of nodes.
+
+ tosca.policies.Scaling:
+ derived_from: tosca.policies.Root
+ description: The TOSCA Policy Type definition that is used to govern
+ scaling of TOSCA nodes or groups of nodes.
+
+ tosca.policies.Update:
+ derived_from: tosca.policies.Root
+ description: The TOSCA Policy Type definition that is used to govern
+ update of TOSCA nodes or groups of nodes.
+
+ tosca.policies.Performance:
+ derived_from: tosca.policies.Root
+ description: The TOSCA Policy Type definition that is used to declare
+ performance requirements for TOSCA nodes or groups of nodes.
##########################################################################
# Group Type.
@@ -934,8 +941,9 @@ tosca.policies.Performance:
# implied membership relationship and may need to be orchestrated or
# managed together to achieve some result.
##########################################################################
-tosca.groups.Root:
- description: The TOSCA Group Type all other TOSCA Group Types derive from
- interfaces:
- Standard:
- type: tosca.interfaces.node.lifecycle.Standard
+group_types:
+ tosca.groups.Root:
+ description: The TOSCA Group Type all other TOSCA Group Types derive from
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py b/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py
index 887e99a..bf379fc 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py
@@ -31,7 +31,6 @@ class ArtifactTypeDef(StatefulEntityType):
parent_artif = self.parent_type.type if self.parent_type else None
if parent_artif:
while parent_artif != 'tosca.artifacts.Root':
- # only support normative artifact, shall be modified future
artifacts[parent_artif] = self.TOSCA_DEF[parent_artif]
parent_artif = artifacts[parent_artif]['derived_from']
return artifacts
@@ -44,8 +43,6 @@ class ArtifactTypeDef(StatefulEntityType):
partifact_entity = self.derived_from(self.defs)
if partifact_entity:
return ArtifactTypeDef(partifact_entity, self.custom_def)
- else:
- return None
def get_artifact(self, name):
'''Return the definition of an artifact field by name.'''
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
index 9b9787b..d7fcb18 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
@@ -29,6 +29,11 @@ class EntityType(object):
('derived_from', 'properties', 'attributes', 'requirements',
'interfaces', 'capabilities', 'type', 'artifacts')
+ TOSCA_DEF_SECTIONS = ['node_types', 'data_types', 'artifact_types',
+ 'group_types', 'relationship_types',
+ 'capability_types', 'interface_types',
+ 'policy_types']
+
'''TOSCA definition file.'''
TOSCA_DEF_FILE = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
@@ -36,7 +41,15 @@ class EntityType(object):
loader = toscaparser.utils.yamlparser.load_yaml
- TOSCA_DEF = loader(TOSCA_DEF_FILE)
+ TOSCA_DEF_LOAD_AS_IS = loader(TOSCA_DEF_FILE)
+
+ # Map of definition with pre-loaded values of TOSCA_DEF_FILE_SECTIONS
+ TOSCA_DEF = {}
+ for section in TOSCA_DEF_SECTIONS:
+ if section in TOSCA_DEF_LOAD_AS_IS.keys():
+ value = TOSCA_DEF_LOAD_AS_IS[section]
+ for key in value.keys():
+ TOSCA_DEF[key] = value[key]
RELATIONSHIP_TYPE = (DEPENDSON, HOSTEDON, CONNECTSTO, ATTACHESTO,
LINKSTO, BINDSTO) = \
@@ -148,5 +161,11 @@ def update_definitions(version):
extension_defs_file = exttools.get_defs_file(version)
loader = toscaparser.utils.yamlparser.load_yaml
-
- EntityType.TOSCA_DEF.update(loader(extension_defs_file))
+ nfv_def_file = loader(extension_defs_file)
+ nfv_def = {}
+ for section in EntityType.TOSCA_DEF_SECTIONS:
+ if section in nfv_def_file.keys():
+ value = nfv_def_file[section]
+ for key in value.keys():
+ nfv_def[key] = value[key]
+ EntityType.TOSCA_DEF.update(nfv_def)
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
index 5587f05..02c285a 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
@@ -59,8 +59,6 @@ class GroupType(StatefulEntityType):
pgroup_entity = self.derived_from(self.defs)
if pgroup_entity:
return GroupType(pgroup_entity, self.custom_def)
- else:
- return None
@property
def description(self):
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py b/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
index 47496f7..be9933e 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
@@ -15,6 +15,7 @@ from toscaparser.common.exception import InvalidTypeError
from toscaparser.elements.attribute_definition import AttributeDef
from toscaparser.elements.entity_type import EntityType
from toscaparser.elements.property_definition import PropertyDef
+from toscaparser.unsupportedtype import UnsupportedType
class StatefulEntityType(EntityType):
@@ -31,17 +32,20 @@ class StatefulEntityType(EntityType):
def __init__(self, entitytype, prefix, custom_def=None):
entire_entitytype = entitytype
- if not entitytype.startswith(self.TOSCA):
- entire_entitytype = prefix + entitytype
- if entire_entitytype in list(self.TOSCA_DEF.keys()):
- self.defs = self.TOSCA_DEF[entire_entitytype]
- entitytype = entire_entitytype
- elif custom_def and entitytype in list(custom_def.keys()):
- self.defs = custom_def[entitytype]
- else:
+ if UnsupportedType.validate_type(entire_entitytype):
self.defs = None
- ExceptionCollector.appendException(
- InvalidTypeError(what=entitytype))
+ else:
+ if not entitytype.startswith(self.TOSCA):
+ entire_entitytype = prefix + entitytype
+ if entire_entitytype in list(self.TOSCA_DEF.keys()):
+ self.defs = self.TOSCA_DEF[entire_entitytype]
+ entitytype = entire_entitytype
+ elif custom_def and entitytype in list(custom_def.keys()):
+ self.defs = custom_def[entitytype]
+ else:
+ self.defs = None
+ ExceptionCollector.appendException(
+ InvalidTypeError(what=entitytype))
self.type = entitytype
def get_properties_def_objects(self):
diff --git a/tosca2heat/tosca-parser/toscaparser/entity_template.py b/tosca2heat/tosca-parser/toscaparser/entity_template.py
index 7488c33..7ce8cec 100644
--- a/tosca2heat/tosca-parser/toscaparser/entity_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/entity_template.py
@@ -21,6 +21,7 @@ from toscaparser.elements.nodetype import NodeType
from toscaparser.elements.policytype import PolicyType
from toscaparser.elements.relationshiptype import RelationshipType
from toscaparser.properties import Property
+from toscaparser.unsupportedtype import UnsupportedType
from toscaparser.utils.gettextutils import _
@@ -44,8 +45,9 @@ class EntityTemplate(object):
self.entity_tpl = template
self.custom_def = custom_def
self._validate_field(self.entity_tpl)
+ type = self.entity_tpl.get('type')
+ UnsupportedType.validate_type(type)
if entity_name == 'node_type':
- type = self.entity_tpl.get('type')
self.type_definition = NodeType(type, custom_def) \
if type is not None else None
if entity_name == 'relationship_type':
@@ -57,10 +59,10 @@ class EntityTemplate(object):
type = self.entity_tpl['relationship']
else:
type = self.entity_tpl['type']
+ UnsupportedType.validate_type(type)
self.type_definition = RelationshipType(type,
None, custom_def)
if entity_name == 'policy_type':
- type = self.entity_tpl.get('type')
if not type:
msg = (_('Policy definition of "%(pname)s" must have'
' a "type" ''attribute.') % dict(pname=name))
@@ -69,7 +71,6 @@ class EntityTemplate(object):
self.type_definition = PolicyType(type, custom_def)
if entity_name == 'group_type':
- type = self.entity_tpl.get('type')
self.type_definition = GroupType(type, custom_def) \
if type is not None else None
self._properties = None
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml
index dc986e5..365d70e 100644
--- a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml
@@ -22,94 +22,94 @@ tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
# A Node Type is a reusable entity that defines the type of one or more
# Node Templates.
##########################################################################
+node_types:
+ tosca.nodes.nfv.VNF:
+ derived_from: tosca.nodes.Root # Or should this be its own top - level type?
+ properties:
+ id:
+ type: string
+ description: ID of this VNF
+ vendor:
+ type: string
+ description: name of the vendor who generate this VNF
+ version:
+ type: version
+ description: version of the software for this VNF
+ requirements:
+ - virtualLink:
+ capability: tosca.capabilities.nfv.VirtualLinkable
+ relationship: tosca.relationships.nfv.VirtualLinksTo
+ node: tosca.nodes.nfv.VL
+
+ tosca.nodes.nfv.VDU:
+ derived_from: tosca.nodes.Compute
+ capabilities:
+ high_availability:
+ type: tosca.capabilities.nfv.HA
+ virtualbinding:
+ type: tosca.capabilities.nfv.VirtualBindable
+ monitoring_parameter:
+ type: tosca.capabilities.nfv.Metric
+ requirements:
+ - high_availability:
+ capability: tosca.capabilities.nfv.HA
+ relationship: tosca.relationships.nfv.HA
+ node: tosca.nodes.nfv.VDU
+ occurrences: [ 0, 1 ]
+
+ tosca.nodes.nfv.CP:
+ derived_from: tosca.nodes.network.Port
+ properties:
+ type:
+ type: string
+ required: false
+ requirements:
+ - virtualLink:
+ capability: tosca.capabilities.nfv.VirtualLinkable
+ relationship: tosca.relationships.nfv.VirtualLinksTo
+ node: tosca.nodes.nfv.VL
+ - virtualBinding:
+ capability: tosca.capabilities.nfv.VirtualBindable
+ relationship: tosca.relationships.nfv.VirtualBindsTo
+ node: tosca.nodes.nfv.VDU
+ attributes:
+ address:
+ type: string
-tosca.nodes.nfv.VNF:
- derived_from: tosca.nodes.Root # Or should this be its own top - level type?
- properties:
- id:
- type: string
- description: ID of this VNF
- vendor:
- type: string
- description: name of the vendor who generate this VNF
- version:
- type: version
- description: version of the software for this VNF
- requirements:
- - virtualLink:
- capability: tosca.capabilities.nfv.VirtualLinkable
- relationship: tosca.relationships.nfv.VirtualLinksTo
- node: tosca.nodes.nfv.VL
-
-tosca.nodes.nfv.VDU:
- derived_from: tosca.nodes.Compute
- capabilities:
- high_availability:
- type: tosca.capabilities.nfv.HA
- virtualbinding:
- type: tosca.capabilities.nfv.VirtualBindable
- monitoring_parameter:
- type: tosca.capabilities.nfv.Metric
- requirements:
- - high_availability:
- capability: tosca.capabilities.nfv.HA
- relationship: tosca.relationships.nfv.HA
- node: tosca.nodes.nfv.VDU
- occurrences: [ 0, 1 ]
-
-tosca.nodes.nfv.CP:
- derived_from: tosca.nodes.network.Port
- properties:
- type:
- type: string
- required: false
- requirements:
- - virtualLink:
- capability: tosca.capabilities.nfv.VirtualLinkable
- relationship: tosca.relationships.nfv.VirtualLinksTo
- node: tosca.nodes.nfv.VL
- - virtualBinding:
- capability: tosca.capabilities.nfv.VirtualBindable
- relationship: tosca.relationships.nfv.VirtualBindsTo
- node: tosca.nodes.nfv.VDU
- attributes:
- address:
- type: string
-
-tosca.nodes.nfv.VL:
- derived_from: tosca.nodes.network.Network
- properties:
- vendor:
- type: string
- required: true
- description: name of the vendor who generate this VL
- capabilities:
- virtual_linkable:
- type: tosca.capabilities.nfv.VirtualLinkable
-
-tosca.nodes.nfv.VL.ELine:
- derived_from: tosca.nodes.nfv.VL
- capabilities:
- virtual_linkable:
- occurrences: 2
-
-tosca.nodes.nfv.VL.ELAN:
- derived_from: tosca.nodes.nfv.VL
-
-tosca.nodes.nfv.VL.ETree:
- derived_from: tosca.nodes.nfv.VL
-
-tosca.nodes.nfv.FP:
- derived_from: tosca.nodes.Root
- properties:
- policy:
- type: string
- required: false
- description: name of the vendor who generate this VL
- requirements:
- - forwarder:
- capability: tosca.capabilities.nfv.Forwarder
- relationship: tosca.relationships.nfv.ForwardsTo
+ tosca.nodes.nfv.VL:
+ derived_from: tosca.nodes.network.Network
+ properties:
+ vendor:
+ type: string
+ required: true
+ description: name of the vendor who generate this VL
+ capabilities:
+ virtual_linkable:
+ type: tosca.capabilities.nfv.VirtualLinkable
+
+ tosca.nodes.nfv.VL.ELine:
+ derived_from: tosca.nodes.nfv.VL
+ capabilities:
+ virtual_linkable:
+ occurrences: 2
+
+ tosca.nodes.nfv.VL.ELAN:
+ derived_from: tosca.nodes.nfv.VL
+
+ tosca.nodes.nfv.VL.ETree:
+ derived_from: tosca.nodes.nfv.VL
+
+ tosca.nodes.nfv.FP:
+ derived_from: tosca.nodes.Root
+ properties:
+ policy:
+ type: string
+ required: false
+ description: name of the vendor who generate this VL
+ requirements:
+ - forwarder:
+ capability: tosca.capabilities.nfv.Forwarder
+ relationship: tosca.relationships.nfv.ForwardsTo
##########################################################################
# Relationship Type.
@@ -117,25 +117,26 @@ tosca.nodes.nfv.FP:
# or more relationships between Node Types or Node Templates.
##########################################################################
-tosca.relationships.nfv.VirtualLinksTo:
- derived_from: tosca.relationships.network.LinksTo
- valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]
+relationship_types:
+ tosca.relationships.nfv.VirtualLinksTo:
+ derived_from: tosca.relationships.network.LinksTo
+ valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]
-tosca.relationships.nfv.VirtualBindsTo:
- derived_from: tosca.relationships.network.BindsTo
- valid_target_types: [ tosca.capabilities.nfv.VirtualBindable ]
+ tosca.relationships.nfv.VirtualBindsTo:
+ derived_from: tosca.relationships.network.BindsTo
+ valid_target_types: [ tosca.capabilities.nfv.VirtualBindable ]
-tosca.relationships.nfv.HA:
- derived_from: tosca.relationships.Root
- valid_target_types: [ tosca.capabilities.nfv.HA ]
+ tosca.relationships.nfv.HA:
+ derived_from: tosca.relationships.Root
+ valid_target_types: [ tosca.capabilities.nfv.HA ]
-tosca.relationships.nfv.Monitor:
- derived_from: tosca.relationships.ConnectsTo
- valid_target_types: [ tosca.capabilities.nfv.Metric ]
+ tosca.relationships.nfv.Monitor:
+ derived_from: tosca.relationships.ConnectsTo
+ valid_target_types: [ tosca.capabilities.nfv.Metric ]
-tosca.relationships.nfv.ForwardsTo:
- derived_from: tosca.relationships.root
- valid_target_types: [ tosca.capabilities.nfv.Forwarder]
+ tosca.relationships.nfv.ForwardsTo:
+ derived_from: tosca.relationships.root
+ valid_target_types: [ tosca.capabilities.nfv.Forwarder]
##########################################################################
# Capability Type.
@@ -143,27 +144,28 @@ tosca.relationships.nfv.ForwardsTo:
# capability that a Node Type can declare to expose.
##########################################################################
-tosca.capabilities.nfv.VirtualLinkable:
- derived_from: tosca.capabilities.network.Linkable
+capability_types:
+ tosca.capabilities.nfv.VirtualLinkable:
+ derived_from: tosca.capabilities.network.Linkable
-tosca.capabilities.nfv.VirtualBindable:
- derived_from: tosca.capabilities.network.Bindable
+ tosca.capabilities.nfv.VirtualBindable:
+ derived_from: tosca.capabilities.network.Bindable
-tosca.capabilities.nfv.HA:
- derived_from: tosca.capabilities.Root
- valid_source_types: [ tosca.nodes.nfv.VDU ]
+ tosca.capabilities.nfv.HA:
+ derived_from: tosca.capabilities.Root
+ valid_source_types: [ tosca.nodes.nfv.VDU ]
-tosca.capabilities.nfv.HA.ActiveActive:
- derived_from: tosca.capabilities.nfv.HA
+ tosca.capabilities.nfv.HA.ActiveActive:
+ derived_from: tosca.capabilities.nfv.HA
-tosca.capabilities.nfv.HA.ActivePassive:
- derived_from: tosca.capabilities.nfv.HA
+ tosca.capabilities.nfv.HA.ActivePassive:
+ derived_from: tosca.capabilities.nfv.HA
-tosca.capabilities.nfv.Metric:
- derived_from: tosca.capabilities.Root
+ tosca.capabilities.nfv.Metric:
+ derived_from: tosca.capabilities.Root
-tosca.capabilities.nfv.Forwarder:
- derived_from: tosca.capabilities.Root
+ tosca.capabilities.nfv.Forwarder:
+ derived_from: tosca.capabilities.Root
##########################################################################
# Interfaces Type.
@@ -196,42 +198,43 @@ tosca.capabilities.nfv.Forwarder:
# Group Type
#
##########################################################################
-tosca.groups.nfv.VNFFG:
- derived_from: tosca.groups.Root
-
- properties:
- vendor:
- type: string
- required: true
- description: name of the vendor who generate this VNFFG
-
- version:
- type: string
- required: true
- description: version of this VNFFG
-
- number_of_endpoints:
- type: integer
- required: true
- description: count of the external endpoints included in this VNFFG
-
- dependent_virtual_link:
- type: list
- entry_schema:
- type: string
- required: true
- description: Reference to a VLD used in this Forwarding Graph
+group_types:
+ tosca.groups.nfv.VNFFG:
+ derived_from: tosca.groups.Root
- connection_point:
- type: list
- entry_schema:
+ properties:
+ vendor:
type: string
- required: true
- description: Reference to Connection Points forming the VNFFG
+ required: true
+ description: name of the vendor who generate this VNFFG
- constituent_vnfs:
- type: list
- entry_schema:
+ version:
type: string
- required: true
- description: Reference to a list of VNFD used in this VNF Forwarding Graph
+ required: true
+ description: version of this VNFFG
+
+ number_of_endpoints:
+ type: integer
+ required: true
+ description: count of the external endpoints included in this VNFFG
+
+ dependent_virtual_link:
+ type: list
+ entry_schema:
+ type: string
+ required: true
+ description: Reference to a VLD used in this Forwarding Graph
+
+ connection_point:
+ type: list
+ entry_schema:
+ type: string
+ required: true
+ description: Reference to Connection Points forming the VNFFG
+
+ constituent_vnfs:
+ type: list
+ entry_schema:
+ type: string
+ required: true
+ description: Reference to a list of VNFD used in this VNF Forwarding Graph
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
index e229d2f..e87b672 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
@@ -706,6 +706,8 @@ class ToscaTemplateTest(TestCase):
tosca = ToscaTemplate(tosca_tpl)
for policy in tosca.topology_template.policies:
+ self.assertTrue(
+ policy.is_derived_from("tosca.policies.Root"))
if policy.name == 'my_compute_placement_policy':
self.assertEqual('tosca.policies.Placement', policy.type)
self.assertEqual(['my_server_1', 'my_server_2'],
@@ -726,6 +728,8 @@ class ToscaTemplateTest(TestCase):
tosca = ToscaTemplate(tosca_tpl)
for policy in tosca.topology_template.policies:
+ self.assertTrue(
+ policy.is_derived_from("tosca.policies.Root"))
if policy.name == 'my_groups_placement':
self.assertEqual('mycompany.mytypes.myScalingPolicy',
policy.type)
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
index 57daf7e..5a8f37a 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
@@ -98,6 +98,22 @@ class ToscaTemplateValidationTest(TestCase):
'field "derived1_from". Refer to the definition to '
'verify valid values.'))
+ def test_unsupported_type(self):
+ tpl_snippet = '''
+ node_templates:
+ invalid_type:
+ type: tosca.test.invalidtype
+ properties:
+ size: { get_input: storage_size }
+ snapshot_id: { get_input: storage_snapshot_id }
+ '''
+ tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+ err = self.assertRaises(exception.UnsupportedTypeError,
+ TopologyTemplate, tpl, None)
+ expectedmessage = _('Type "tosca.test.invalidtype" is valid'
+ ' TOSCA type but not supported at this time.')
+ self.assertEqual(expectedmessage, err.__str__())
+
def test_inputs(self):
tpl_snippet1 = '''
inputs:
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_utils.py b/tosca2heat/tosca-parser/toscaparser/tests/test_utils.py
index 215fa0a..fca024d 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_utils.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_utils.py
@@ -29,6 +29,7 @@ class UrlUtilsTest(TestCase):
self.assertFalse(self.url_utils.validate_url("github.com"))
self.assertFalse(self.url_utils.validate_url("123"))
self.assertFalse(self.url_utils.validate_url("a/b/c"))
+ self.assertTrue(self.url_utils.validate_url("file:///dir/file.ext"))
def test_urlutils_join_url(self):
self.assertEqual(
diff --git a/tosca2heat/tosca-parser/toscaparser/topology_template.py b/tosca2heat/tosca-parser/toscaparser/topology_template.py
index 100a06b..d7fd443 100644
--- a/tosca2heat/tosca-parser/toscaparser/topology_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/topology_template.py
@@ -26,6 +26,7 @@ from toscaparser.substitution_mappings import SubstitutionMappings
from toscaparser.tpl_relationship_graph import ToscaGraph
from toscaparser.utils.gettextutils import _
+
# Topology template key names
SECTIONS = (DESCRIPTION, INPUTS, NODE_TEMPLATES,
RELATIONSHIP_TEMPLATES, OUTPUTS, GROUPS,
diff --git a/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py b/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py
new file mode 100644
index 0000000..0d2f1d6
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py
@@ -0,0 +1,38 @@
+# 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 ExceptionCollector
+from toscaparser.common.exception import UnsupportedTypeError
+from toscaparser.utils.gettextutils import _
+
+log = logging.getLogger('tosca')
+
+
+class UnsupportedType(object):
+
+ un_supported_types = ['tosca.test.invalidtype',
+ 'tosca.nodes.Storage.ObjectStorage',
+ 'tosca.nodes.Storage.BlockStorage']
+
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def validate_type(entitytype):
+ if entitytype in UnsupportedType.un_supported_types:
+ ExceptionCollector.appendException(UnsupportedTypeError(
+ what=_('%s')
+ % entitytype))
+ return True
+ else:
+ return False
diff --git a/tosca2heat/tosca-parser/toscaparser/utils/urlutils.py b/tosca2heat/tosca-parser/toscaparser/utils/urlutils.py
index 34b6032..546acca 100644
--- a/tosca2heat/tosca-parser/toscaparser/utils/urlutils.py
+++ b/tosca2heat/tosca-parser/toscaparser/utils/urlutils.py
@@ -35,7 +35,11 @@ class UrlUtils(object):
URL.
"""
parsed = urlparse(path)
- return bool(parsed.scheme) and bool(parsed.netloc)
+ if parsed.scheme == 'file':
+ # If the url uses the file scheme netloc will be ""
+ return True
+ else:
+ return bool(parsed.scheme) and bool(parsed.netloc)
@staticmethod
def join_url(url, relative_path):