summaryrefslogtreecommitdiffstats
path: root/tosca2heat/tosca-parser
diff options
context:
space:
mode:
Diffstat (limited to 'tosca2heat/tosca-parser')
-rw-r--r--tosca2heat/tosca-parser/README.rst9
-rw-r--r--tosca2heat/tosca-parser/doc/source/conf.py1
-rw-r--r--tosca2heat/tosca-parser/doc/source/installation.rst15
-rw-r--r--tosca2heat/tosca-parser/requirements.txt8
-rw-r--r--tosca2heat/tosca-parser/setup.cfg3
-rw-r--r--tosca2heat/tosca-parser/test-requirements.txt6
-rw-r--r--tosca2heat/tosca-parser/tools/tox_install.sh30
-rw-r--r--tosca2heat/tosca-parser/toscaparser/__init__.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml11
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/constraints.py8
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/entity_type.py7
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/grouptype.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/interfaces.py13
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/nodetype.py6
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/policytype.py5
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/portspectype.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py16
-rw-r--r--tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py3
-rw-r--r--tosca2heat/tosca-parser/toscaparser/entity_template.py1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0_0.yaml (renamed from tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml)0
-rw-r--r--tosca2heat/tosca-parser/toscaparser/extensions/nfv/tosca_simple_profile_for_nfv_1_0_0.py (renamed from tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py)2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/functions.py110
-rw-r--r--tosca2heat/tosca-parser/toscaparser/imports.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/nodetemplate.py74
-rw-r--r--tosca2heat/tosca-parser/toscaparser/parameters.py11
-rw-r--r--tosca2heat/tosca-parser/toscaparser/policy.py6
-rw-r--r--tosca2heat/tosca-parser/toscaparser/shell.py40
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/base.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csarbin17488 -> 17490 bytes
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zipbin17488 -> 17490 bytes
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml44
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_interface.yaml20
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml4
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml23
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml25
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml23
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml19
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml75
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/node_filter/test_node_filter.yaml18
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_defs.yaml183
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml261
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml95
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/relationship/test_custom_relationship.yaml48
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/repositories/test_repositories_definition.yaml23
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml26
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/requirements/test_requirements.yaml67
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/test_endpoint_on_compute.yaml21
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml3
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/test_normative_type_properties_override.yaml37
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml4
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml70
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml31
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml31
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml6
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/data/tosca_test_get_operation_output.yaml19
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py2
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_functions.py57
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py6
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_shell.py10
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py80
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py9
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py58
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py235
-rw-r--r--tosca2heat/tosca-parser/toscaparser/topology_template.py32
-rw-r--r--tosca2heat/tosca-parser/toscaparser/tosca_template.py16
-rw-r--r--tosca2heat/tosca-parser/toscaparser/unsupportedtype.py12
-rw-r--r--tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py1
-rw-r--r--tosca2heat/tosca-parser/toscaparser/utils/validateutils.py2
76 files changed, 1888 insertions, 215 deletions
diff --git a/tosca2heat/tosca-parser/README.rst b/tosca2heat/tosca-parser/README.rst
index d80d75b..0f94072 100644
--- a/tosca2heat/tosca-parser/README.rst
+++ b/tosca2heat/tosca-parser/README.rst
@@ -1,3 +1,12 @@
+========================
+Team and repository tags
+========================
+
+.. image:: http://governance.openstack.org/badges/tosca-parser.svg
+ :target: http://governance.openstack.org/reference/tags/index.html
+
+.. Change things from this point on
+
===============
TOSCA Parser
===============
diff --git a/tosca2heat/tosca-parser/doc/source/conf.py b/tosca2heat/tosca-parser/doc/source/conf.py
index e461246..d5d9189 100644
--- a/tosca2heat/tosca-parser/doc/source/conf.py
+++ b/tosca2heat/tosca-parser/doc/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# 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
diff --git a/tosca2heat/tosca-parser/doc/source/installation.rst b/tosca2heat/tosca-parser/doc/source/installation.rst
index f3805a5..5476d41 100644
--- a/tosca2heat/tosca-parser/doc/source/installation.rst
+++ b/tosca2heat/tosca-parser/doc/source/installation.rst
@@ -2,8 +2,17 @@
Installation
============
-You can clone the project and use it as below::
+PyPI Installation
+-----------------
+Tosca-Parser can be installed via a PyPI package. Refer to https://pypi.python.org/pypi/tosca-parser for available packages.
+The latest release can be simply installed by running the following command::
- git clone https://github.com/openstack/tosca-parser
+ sudo pip install tosca-parser
+
+Manual Installation
+-------------------
+You can manually install the latest code available at the TOSCA-Parser github repository by following these steps::
-Tosca-Parser can be installed via PyPI package as well. Refer to https://pypi.python.org/pypi/tosca-parser for available packages. \ No newline at end of file
+ git clone https://github.com/openstack/tosca-parser
+ cd tosca-parser
+ sudo python setup.py install
diff --git a/tosca2heat/tosca-parser/requirements.txt b/tosca2heat/tosca-parser/requirements.txt
index b30cc51..45a19f0 100644
--- a/tosca2heat/tosca-parser/requirements.txt
+++ b/tosca2heat/tosca-parser/requirements.txt
@@ -1,10 +1,10 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr>=1.6 # Apache-2.0
+pbr>=1.8 # Apache-2.0
Babel>=2.3.4 # BSD
-cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0
-PyYAML>=3.1.0 # MIT
+cliff>=2.3.0 # Apache-2.0
+PyYAML>=3.10.0 # MIT
python-dateutil>=2.4.2 # BSD
six>=1.9.0 # MIT
-requests>=2.10.0 # Apache-2.0
+requests!=2.12.2,!=2.13.0,>=2.10.0 # Apache-2.0
diff --git a/tosca2heat/tosca-parser/setup.cfg b/tosca2heat/tosca-parser/setup.cfg
index c109228..77e1b2e 100644
--- a/tosca2heat/tosca-parser/setup.cfg
+++ b/tosca2heat/tosca-parser/setup.cfg
@@ -1,11 +1,12 @@
[metadata]
name = tosca-parser
+url = https://launchpad.net/tosca-parser
summary = Parser for TOSCA Simple Profile in YAML.
description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
-home-page = http://www.openstack.org/
+home-page = http://docs.openstack.org/developer/tosca-parser/
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
diff --git a/tosca2heat/tosca-parser/test-requirements.txt b/tosca2heat/tosca-parser/test-requirements.txt
index 1bb6623..d4b59c3 100644
--- a/tosca2heat/tosca-parser/test-requirements.txt
+++ b/tosca2heat/tosca-parser/test-requirements.txt
@@ -2,12 +2,12 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
-coverage>=3.6 # Apache-2.0
+coverage>=4.0 # Apache-2.0
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
+oslosphinx>=4.7.0 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD
-sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
+sphinx>=1.5.1 # 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/tosca-parser/tools/tox_install.sh b/tosca2heat/tosca-parser/tools/tox_install.sh
new file mode 100644
index 0000000..e61b63a
--- /dev/null
+++ b/tosca2heat/tosca-parser/tools/tox_install.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+# Client constraint file contains this client version pin that is in conflict
+# with installing the client from source. We should remove the version pin in
+# the constraints file before applying it for from-source installation.
+
+CONSTRAINTS_FILE="$1"
+shift 1
+
+set -e
+
+# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
+# published to logs.openstack.org for easy debugging.
+localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
+
+if [[ "$CONSTRAINTS_FILE" != http* ]]; then
+ CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
+fi
+# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
+curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
+
+pip install -c"$localfile" openstack-requirements
+
+# This is the main purpose of the script: Allow local installation of
+# the current repo. It is listed in constraints file and thus any
+# install will be constrained and we need to unconstrain it.
+edit-constraints "$localfile" -- "$CLIENT_NAME"
+
+pip install -c"$localfile" -U "$@"
+exit $?
diff --git a/tosca2heat/tosca-parser/toscaparser/__init__.py b/tosca2heat/tosca-parser/toscaparser/__init__.py
index d6fa60c..d9745ed 100644
--- a/tosca2heat/tosca-parser/toscaparser/__init__.py
+++ b/tosca2heat/tosca-parser/toscaparser/__init__.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
# 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
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 6f3b331..9f3369e 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml
@@ -70,6 +70,8 @@ node_types:
type: tosca.capabilities.OperatingSystem
scalable:
type: tosca.capabilities.Scalable
+ endpoint:
+ type: tosca.capabilities.Endpoint.Admin
requirements:
- local_storage:
capability: tosca.capabilities.Attachment
@@ -527,6 +529,7 @@ capability_types:
network_name:
type: string
required: false
+ default: PRIVATE
initiator:
type: string
required: false
@@ -671,7 +674,7 @@ capability_types:
publish_ports:
type: list
entry_schema:
- type: PortSpec
+ type: tosca.datatypes.network.PortSpec
required: false
description: >
List of ports mappings from source (Docker container)
@@ -679,7 +682,7 @@ capability_types:
expose_ports:
type: list
entry_schema:
- type: PortSpec
+ type: tosca.datatypes.network.PortSpec
required: false
description: >
List of ports mappings from source (Docker container) to expose
@@ -799,7 +802,7 @@ data_types:
constraints:
- valid_values: [ udp, tcp, igmp ]
target:
- type: PortDef
+ type: tosca.datatypes.network.PortDef
required: false
target_range:
type: range
@@ -807,7 +810,7 @@ data_types:
constraints:
- in_range: [ 1, 65535 ]
source:
- type: PortDef
+ type: tosca.datatypes.network.PortDef
required: false
source_range:
type: range
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py b/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py
index 865690e..54cd9fe 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py
@@ -44,7 +44,7 @@ class CapabilityTypeDef(StatefulEntityType):
for prop, schema in props.items():
# add parent property if not overridden by children type
if not self.properties or \
- prop not in self.properties.keys():
+ prop not in self.properties.keys():
properties.append(PropertyDef(prop, None, schema))
return properties
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/constraints.py b/tosca2heat/tosca-parser/toscaparser/elements/constraints.py
index 8594b85..70863bc 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/constraints.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/constraints.py
@@ -27,10 +27,10 @@ class Schema(collections.Mapping):
KEYS = (
TYPE, REQUIRED, DESCRIPTION,
- DEFAULT, CONSTRAINTS, ENTRYSCHEMA
+ DEFAULT, CONSTRAINTS, ENTRYSCHEMA, STATUS
) = (
'type', 'required', 'description',
- 'default', 'constraints', 'entry_schema'
+ 'default', 'constraints', 'entry_schema', 'status'
)
PROPERTY_TYPES = (
@@ -86,6 +86,10 @@ class Schema(collections.Mapping):
return self.schema.get(self.DEFAULT)
@property
+ def status(self):
+ return self.schema.get(self.STATUS, '')
+
+ @property
def constraints(self):
if not self.constraints_list:
constraint_schemata = self.schema.get(self.CONSTRAINTS)
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
index d7fcb18..9fd6c4d 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/entity_type.py
@@ -93,7 +93,7 @@ class EntityType(object):
return False
def entity_value(self, defs, key):
- if key in defs:
+ if defs and key in defs:
return defs[key]
def get_value(self, ndtype, defs=None, parent=None):
@@ -102,7 +102,7 @@ class EntityType(object):
if not hasattr(self, 'defs'):
return None
defs = self.defs
- if ndtype in defs:
+ if defs and ndtype in defs:
# copy the value to avoid that next operations add items in the
# item definitions
value = copy.copy(defs[ndtype])
@@ -110,7 +110,7 @@ class EntityType(object):
p = self
if p:
while p:
- if ndtype in p.defs:
+ if p.defs and ndtype in p.defs:
# get the parent value
parent_value = p.defs[ndtype]
if value:
@@ -159,7 +159,6 @@ class EntityType(object):
def update_definitions(version):
exttools = ExtTools()
extension_defs_file = exttools.get_defs_file(version)
-
loader = toscaparser.utils.yamlparser.load_yaml
nfv_def_file = loader(extension_defs_file)
nfv_def = {}
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
index 02c285a..4e58d64 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
@@ -87,7 +87,7 @@ class GroupType(StatefulEntityType):
'metadata' % (meta_data.get('type'))))
for entry_schema, entry_schema_type in meta_data.items():
if isinstance(entry_schema_type, dict) and not \
- entry_schema_type.get('type') == 'string':
+ entry_schema_type.get('type') == 'string':
ExceptionCollector.appendException(
InvalidTypeError(what='"%s" defined in group for '
'metadata "%s"'
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/interfaces.py b/tosca2heat/tosca-parser/toscaparser/elements/interfaces.py
index 88fb8ab..47ec90a 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/interfaces.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/interfaces.py
@@ -22,6 +22,9 @@ SECTIONS = (LIFECYCLE, CONFIGURE, LIFECYCLE_SHORTNAME,
INTERFACEVALUE = (IMPLEMENTATION, INPUTS) = ('implementation', 'inputs')
+INTERFACE_DEF_RESERVED_WORDS = ['type', 'inputs', 'derived_from', 'version',
+ 'description']
+
class InterfacesDef(StatefulEntityType):
'''TOSCA built-in interfaces type.'''
@@ -40,8 +43,16 @@ class InterfacesDef(StatefulEntityType):
interfacetype = LIFECYCLE
if interfacetype == CONFIGURE_SHORTNAME:
interfacetype = CONFIGURE
+ if hasattr(self.ntype, 'interfaces') \
+ and self.ntype.interfaces \
+ and interfacetype in self.ntype.interfaces:
+ interfacetype = self.ntype.interfaces[interfacetype]['type']
if node_type:
- self.defs = self.TOSCA_DEF[interfacetype]
+ if self.node_template and self.node_template.custom_def \
+ and interfacetype in self.node_template.custom_def:
+ self.defs = self.node_template.custom_def[interfacetype]
+ else:
+ self.defs = self.TOSCA_DEF[interfacetype]
if value:
if isinstance(self.value, dict):
for i, j in self.value.items():
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/nodetype.py b/tosca2heat/tosca-parser/toscaparser/elements/nodetype.py
index f5e4eb0..7d68c0b 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/nodetype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/nodetype.py
@@ -98,10 +98,6 @@ class NodeType(StatefulEntityType):
provided capability.
'''
- # All types,include normative and custom types, here will
- # be substituted because the global moification of TOSCA_DEF
- self.TOSCA_DEF.update(self.custom_def)
-
# Filter the node types
node_types = [node_type for node_type in self.TOSCA_DEF.keys()
if node_type.startswith(self.NODE_PREFIX) and
@@ -141,8 +137,6 @@ class NodeType(StatefulEntityType):
'''Return a list of capability objects.'''
typecapabilities = []
caps = self.get_value(self.CAPABILITIES, None, True)
- if caps is None:
- caps = self.get_value(self.CAPABILITIES, None, True)
if caps:
# 'name' is symbolic name of the capability
# 'value' is a dict { 'type': <capability type name> }
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/policytype.py b/tosca2heat/tosca-parser/toscaparser/elements/policytype.py
index 8fbb0f0..a922d26 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/policytype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/policytype.py
@@ -20,9 +20,10 @@ from toscaparser.utils.validateutils import TOSCAVersionProperty
class PolicyType(StatefulEntityType):
'''TOSCA built-in policies type.'''
- SECTIONS = (DERIVED_FROM, METADATA, PROPERTIES, VERSION, DESCRIPTION, TARGETS) = \
+ SECTIONS = (DERIVED_FROM, METADATA, PROPERTIES, VERSION, DESCRIPTION,
+ TARGETS, TRIGGERS, TYPE) = \
('derived_from', 'metadata', 'properties', 'version',
- 'description', 'targets')
+ 'description', 'targets', 'triggers', 'type')
def __init__(self, ptype, custom_def=None):
super(PolicyType, self).__init__(ptype, self.POLICY_PREFIX,
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/portspectype.py b/tosca2heat/tosca-parser/toscaparser/elements/portspectype.py
index d32e97e..0218305 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/portspectype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/portspectype.py
@@ -58,7 +58,7 @@ class PortSpec(object):
# verify one of the specified values is set
if source is None and source_range is None and \
- target is None and target_range is None:
+ target is None and target_range is None:
ExceptionCollector.appendException(
InvalidTypeAdditionalRequirementsError(
type=PortSpec.TYPE_URI))
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py b/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py
index 25440ca..8eefbea 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py
@@ -10,16 +10,25 @@
# License for the specific language governing permissions and limitations
# under the License.
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import UnknownFieldError
from toscaparser.elements.statefulentitytype import StatefulEntityType
class RelationshipType(StatefulEntityType):
'''TOSCA built-in relationship type.'''
+ SECTIONS = (DERIVED_FROM, VALID_TARGET_TYPES, INTERFACES,
+ ATTRIBUTES, PROPERTIES, DESCRIPTION, VERSION,
+ CREDENTIAL) = ('derived_from', 'valid_target_types',
+ 'interfaces', 'attributes', 'properties',
+ 'description', 'version', 'credential')
+
def __init__(self, type, capability_name=None, custom_def=None):
super(RelationshipType, self).__init__(type, self.RELATIONSHIP_PREFIX,
custom_def)
self.capability_name = capability_name
self.custom_def = custom_def
+ self._validate_keys()
@property
def parent_type(self):
@@ -31,3 +40,10 @@ class RelationshipType(StatefulEntityType):
@property
def valid_target_types(self):
return self.entity_value(self.defs, 'valid_target_types')
+
+ def _validate_keys(self):
+ for key in self.defs.keys():
+ if key not in self.SECTIONS:
+ ExceptionCollector.appendException(
+ UnknownFieldError(what='Relationshiptype "%s"' % self.type,
+ field=key))
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py b/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
index be9933e..2f221b3 100644
--- a/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
+++ b/tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py
@@ -35,6 +35,9 @@ class StatefulEntityType(EntityType):
if UnsupportedType.validate_type(entire_entitytype):
self.defs = None
else:
+ if entitytype.startswith(self.TOSCA + ":"):
+ entitytype = entitytype[(len(self.TOSCA) + 1):]
+ entire_entitytype = prefix + entitytype
if not entitytype.startswith(self.TOSCA):
entire_entitytype = prefix + entitytype
if entire_entitytype in list(self.TOSCA_DEF.keys()):
diff --git a/tosca2heat/tosca-parser/toscaparser/entity_template.py b/tosca2heat/tosca-parser/toscaparser/entity_template.py
index 7ce8cec..cc3d620 100644
--- a/tosca2heat/tosca-parser/toscaparser/entity_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/entity_template.py
@@ -68,7 +68,6 @@ class EntityTemplate(object):
' a "type" ''attribute.') % dict(pname=name))
ExceptionCollector.appendException(
ValidationError(msg))
-
self.type_definition = PolicyType(type, custom_def)
if entity_name == 'group_type':
self.type_definition = GroupType(type, custom_def) \
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_0.yaml
index 365d70e..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_0.yaml
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tosca_simple_profile_for_nfv_1_0_0.py
index 0c7c2b9..24eabab 100644
--- a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py
+++ b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tosca_simple_profile_for_nfv_1_0_0.py
@@ -14,6 +14,6 @@
VERSION = 'tosca_simple_profile_for_nfv_1_0_0'
-DEFS_FILE = "TOSCA_nfv_definition_1_0.yaml"
+DEFS_FILE = "TOSCA_nfv_definition_1_0_0.yaml"
SECTIONS = ('metadata')
diff --git a/tosca2heat/tosca-parser/toscaparser/functions.py b/tosca2heat/tosca-parser/toscaparser/functions.py
index 1b64416..d498229 100644
--- a/tosca2heat/tosca-parser/toscaparser/functions.py
+++ b/tosca2heat/tosca-parser/toscaparser/functions.py
@@ -14,6 +14,7 @@
import abc
import six
+import toscaparser.elements.interfaces
from toscaparser.common.exception import ExceptionCollector
from toscaparser.common.exception import UnknownInputError
@@ -22,12 +23,14 @@ from toscaparser.elements.constraints import Schema
from toscaparser.elements.datatype import DataType
from toscaparser.elements.entity_type import EntityType
from toscaparser.elements.relationshiptype import RelationshipType
+from toscaparser.elements.statefulentitytype import StatefulEntityType
from toscaparser.utils.gettextutils import _
GET_PROPERTY = 'get_property'
GET_ATTRIBUTE = 'get_attribute'
GET_INPUT = 'get_input'
+GET_OPERATION_OUTPUT = 'get_operation_output'
CONCAT = 'concat'
TOKEN = 'token'
@@ -143,6 +146,8 @@ class GetAttribute(Function):
self._find_node_template_containing_attribute()
else:
node_tpl = self._find_node_template(self.args[0])
+ if node_tpl is None:
+ return
index = 2
attrs = node_tpl.type_definition.get_attributes_def()
found = [attrs[self.args[1]]] if self.args[1] in attrs else []
@@ -202,10 +207,13 @@ class GetAttribute(Function):
"""
return self._find_node_template_containing_attribute()
+ # Attributes can be explicitly created as part of the type definition
+ # or a property name can be implicitly used as an attribute name
def _find_node_template_containing_attribute(self):
node_tpl = self._find_node_template(self.args[0])
if node_tpl and \
- not self._attribute_exists_in_type(node_tpl.type_definition):
+ not self._attribute_exists_in_type(node_tpl.type_definition) \
+ and self.attribute_name not in node_tpl.get_properties():
ExceptionCollector.appendException(
KeyError(_('Attribute "%(att)s" was not found in node '
'template "%(ntpl)s".') %
@@ -229,7 +237,7 @@ class GetAttribute(Function):
target_type = target_node.type_definition
for capability in target_type.get_capabilities_objects():
if capability.type in \
- hosted_on_rel['valid_target_types']:
+ hosted_on_rel['valid_target_types']:
if self._attribute_exists_in_type(target_type):
return target_node
return self._find_host_containing_attribute(
@@ -609,6 +617,88 @@ class GetProperty(Function):
return None
+class GetOperationOutput(Function):
+ def validate(self):
+ if len(self.args) == 4:
+ self._find_node_template(self.args[0])
+ interface_name = self._find_interface_name(self.args[1])
+ self._find_operation_name(interface_name, self.args[2])
+ else:
+ ExceptionCollector.appendException(
+ ValueError(_('Illegal arguments for function "{0}". Expected '
+ 'arguments: "template_name","interface_name",'
+ '"operation_name","output_variable_name"'
+ ).format(GET_OPERATION_OUTPUT)))
+ return
+
+ def _find_interface_name(self, interface_name):
+ if interface_name in toscaparser.elements.interfaces.SECTIONS:
+ return interface_name
+ else:
+ ExceptionCollector.appendException(
+ ValueError(_('Enter a valid interface name'
+ ).format(GET_OPERATION_OUTPUT)))
+ return
+
+ def _find_operation_name(self, interface_name, operation_name):
+ if(interface_name == 'Configure' or
+ interface_name == 'tosca.interfaces.node.relationship.Configure'):
+ if(operation_name in
+ StatefulEntityType.
+ interfaces_relationship_configure_operations):
+ return operation_name
+ else:
+ ExceptionCollector.appendException(
+ ValueError(_('Enter an operation of Configure interface'
+ ).format(GET_OPERATION_OUTPUT)))
+ return
+ elif(interface_name == 'Standard' or
+ interface_name == 'tosca.interfaces.node.lifecycle.Standard'):
+ if(operation_name in
+ StatefulEntityType.interfaces_node_lifecycle_operations):
+ return operation_name
+ else:
+ ExceptionCollector.appendException(
+ ValueError(_('Enter an operation of Standard interface'
+ ).format(GET_OPERATION_OUTPUT)))
+ return
+ else:
+ ExceptionCollector.appendException(
+ ValueError(_('Enter a valid operation name'
+ ).format(GET_OPERATION_OUTPUT)))
+ return
+
+ def _find_node_template(self, node_template_name):
+ if node_template_name == TARGET:
+ if not isinstance(self.context.type_definition, RelationshipType):
+ ExceptionCollector.appendException(
+ KeyError(_('"TARGET" keyword can only be used in context'
+ ' to "Relationships" target node')))
+ return
+ return self.context.target
+ if node_template_name == SOURCE:
+ if not isinstance(self.context.type_definition, RelationshipType):
+ ExceptionCollector.appendException(
+ KeyError(_('"SOURCE" keyword can only be used in context'
+ ' to "Relationships" source node')))
+ return
+ return self.context.source
+ name = self.context.name \
+ if node_template_name == SELF and \
+ not isinstance(self.context, list) \
+ else node_template_name
+ for node_template in self.tosca_tpl.nodetemplates:
+ if node_template.name == name:
+ return node_template
+ ExceptionCollector.appendException(
+ KeyError(_(
+ 'Node template "{0}" was not found.'
+ ).format(node_template_name)))
+
+ def result(self):
+ return self
+
+
class Concat(Function):
"""Validate the function and provide an instance of the function
@@ -687,6 +777,7 @@ function_mappings = {
GET_PROPERTY: GetProperty,
GET_INPUT: GetInput,
GET_ATTRIBUTE: GetAttribute,
+ GET_OPERATION_OUTPUT: GetOperationOutput,
CONCAT: Concat,
TOKEN: Token
}
@@ -724,11 +815,12 @@ def get_function(tosca_tpl, node_template, raw_function):
parsing was unsuccessful.
"""
if is_function(raw_function):
- func_name = list(raw_function.keys())[0]
- if func_name in function_mappings:
- func = function_mappings[func_name]
- func_args = list(raw_function.values())[0]
- if not isinstance(func_args, list):
- func_args = [func_args]
- return func(tosca_tpl, node_template, func_name, func_args)
+ if isinstance(raw_function, dict):
+ func_name = list(raw_function.keys())[0]
+ if func_name in function_mappings:
+ func = function_mappings[func_name]
+ func_args = list(raw_function.values())[0]
+ if not isinstance(func_args, list):
+ func_args = [func_args]
+ return func(tosca_tpl, node_template, func_name, func_args)
return raw_function
diff --git a/tosca2heat/tosca-parser/toscaparser/imports.py b/tosca2heat/tosca-parser/toscaparser/imports.py
index 451c952..b69bf4d 100644
--- a/tosca2heat/tosca-parser/toscaparser/imports.py
+++ b/tosca2heat/tosca-parser/toscaparser/imports.py
@@ -221,7 +221,7 @@ class ImportsLoader(object):
dir_path = os.path.dirname(os.path.abspath(
self.path))
if file_path[0] != '' and dir_path.endswith(
- file_path[0]):
+ file_path[0]):
import_template = dir_path + "/" +\
file_path[2]
if not os.path.isfile(import_template):
diff --git a/tosca2heat/tosca-parser/toscaparser/nodetemplate.py b/tosca2heat/tosca-parser/toscaparser/nodetemplate.py
index 10eae33..ca855ad 100644
--- a/tosca2heat/tosca-parser/toscaparser/nodetemplate.py
+++ b/tosca2heat/tosca-parser/toscaparser/nodetemplate.py
@@ -22,6 +22,7 @@ from toscaparser.common.exception import ValidationError
from toscaparser.dataentity import DataEntity
from toscaparser.elements.interfaces import CONFIGURE
from toscaparser.elements.interfaces import CONFIGURE_SHORTNAME
+from toscaparser.elements.interfaces import INTERFACE_DEF_RESERVED_WORDS
from toscaparser.elements.interfaces import InterfacesDef
from toscaparser.elements.interfaces import LIFECYCLE
from toscaparser.elements.interfaces import LIFECYCLE_SHORTNAME
@@ -54,7 +55,7 @@ class NodeTemplate(EntityTemplate):
def relationships(self):
if not self._relationships:
requires = self.requirements
- if requires:
+ if requires and isinstance(requires, list):
for r in requires:
for r1, value in r.items():
explicit = self._get_explicit_relationship(r, value)
@@ -206,13 +207,15 @@ class NodeTemplate(EntityTemplate):
TypeMismatchError(
what='"requirements" of template "%s"' % self.name,
type='list'))
- for req in requires:
- for r1, value in req.items():
- if isinstance(value, dict):
- self._validate_requirements_keys(value)
- self._validate_requirements_properties(value)
- allowed_reqs.append(r1)
- self._common_validate_field(req, allowed_reqs, 'requirements')
+ else:
+ for req in requires:
+ for r1, value in req.items():
+ if isinstance(value, dict):
+ self._validate_requirements_keys(value)
+ self._validate_requirements_properties(value)
+ allowed_reqs.append(r1)
+ self._common_validate_field(req, allowed_reqs,
+ 'requirements')
def _validate_requirements_properties(self, requirements):
# TODO(anyone): Only occurrences property of the requirements is
@@ -229,7 +232,7 @@ class NodeTemplate(EntityTemplate):
for value in occurrences:
DataEntity.validate_datatype('integer', value)
if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \
- or occurrences[1] == 0:
+ or occurrences[1] == 0:
ExceptionCollector.appendException(
InvalidPropertyValueError(what=(occurrences)))
@@ -245,23 +248,42 @@ class NodeTemplate(EntityTemplate):
ifaces = self.type_definition.get_value(self.INTERFACES,
self.entity_tpl)
if ifaces:
- for i in ifaces:
- for name, value in ifaces.items():
- if name in (LIFECYCLE, LIFECYCLE_SHORTNAME):
- self._common_validate_field(
- value, InterfacesDef.
- interfaces_node_lifecycle_operations,
- 'interfaces')
- elif name in (CONFIGURE, CONFIGURE_SHORTNAME):
- self._common_validate_field(
- value, InterfacesDef.
- interfaces_relationship_configure_operations,
- 'interfaces')
- else:
- ExceptionCollector.appendException(
- UnknownFieldError(
- what='"interfaces" of template "%s"' %
- self.name, field=name))
+ for name, value in ifaces.items():
+ if name in (LIFECYCLE, LIFECYCLE_SHORTNAME):
+ self._common_validate_field(
+ value, InterfacesDef.
+ interfaces_node_lifecycle_operations,
+ 'interfaces')
+ elif name in (CONFIGURE, CONFIGURE_SHORTNAME):
+ self._common_validate_field(
+ value, InterfacesDef.
+ interfaces_relationship_configure_operations,
+ 'interfaces')
+ elif name in self.type_definition.interfaces.keys():
+ self._common_validate_field(
+ value,
+ self._collect_custom_iface_operations(name),
+ 'interfaces')
+ else:
+ ExceptionCollector.appendException(
+ UnknownFieldError(
+ what='"interfaces" of template "%s"' %
+ self.name, field=name))
+
+ def _collect_custom_iface_operations(self, name):
+ allowed_operations = []
+ nodetype_iface_def = self.type_definition.interfaces[name]
+ allowed_operations.extend(nodetype_iface_def.keys())
+ if 'type' in nodetype_iface_def:
+ iface_type = nodetype_iface_def['type']
+ if iface_type in self.type_definition.custom_def:
+ iface_type_def = self.type_definition.custom_def[iface_type]
+ else:
+ iface_type_def = self.type_definition.TOSCA_DEF[iface_type]
+ allowed_operations.extend(iface_type_def.keys())
+ allowed_operations = [op for op in allowed_operations if
+ op not in INTERFACE_DEF_RESERVED_WORDS]
+ return allowed_operations
def _validate_fields(self, nodetemplate):
for name in nodetemplate.keys():
diff --git a/tosca2heat/tosca-parser/toscaparser/parameters.py b/tosca2heat/tosca-parser/toscaparser/parameters.py
index ca8e697..787db00 100644
--- a/tosca2heat/tosca-parser/toscaparser/parameters.py
+++ b/tosca2heat/tosca-parser/toscaparser/parameters.py
@@ -27,9 +27,10 @@ log = logging.getLogger('tosca')
class Input(object):
- INPUTFIELD = (TYPE, DESCRIPTION, DEFAULT, CONSTRAINTS, REQUIRED,
- STATUS) = ('type', 'description', 'default',
- 'constraints', 'required', 'status')
+ INPUTFIELD = (TYPE, DESCRIPTION, DEFAULT, CONSTRAINTS, REQUIRED, STATUS,
+ ENTRY_SCHEMA) = ('type', 'description', 'default',
+ 'constraints', 'required', 'status',
+ 'entry_schema')
def __init__(self, name, schema_dict):
self.name = name
@@ -58,6 +59,10 @@ class Input(object):
def constraints(self):
return self.schema.constraints
+ @property
+ def status(self):
+ return self.schema.status
+
def validate(self, value=None):
if value is not None:
self._validate_value(value)
diff --git a/tosca2heat/tosca-parser/toscaparser/policy.py b/tosca2heat/tosca-parser/toscaparser/policy.py
index 61c09ec..fedbeb4 100644
--- a/tosca2heat/tosca-parser/toscaparser/policy.py
+++ b/tosca2heat/tosca-parser/toscaparser/policy.py
@@ -29,7 +29,8 @@ log = logging.getLogger('tosca')
class Policy(EntityTemplate):
'''Policies defined in Topology template.'''
- def __init__(self, name, policy, targets, targets_type, custom_def=None):
+ def __init__(self, name, policy, targets=None, targets_type=None,
+ custom_def=None):
super(Policy, self).__init__(name,
policy,
'policy_type',
@@ -41,6 +42,9 @@ class Policy(EntityTemplate):
self.targets_list = targets
self.targets_type = targets_type
self.triggers = self._triggers(policy.get(TRIGGERS))
+ self.properties = None
+ if 'properties' in policy:
+ self.properties = policy['properties']
self._validate_keys()
@property
diff --git a/tosca2heat/tosca-parser/toscaparser/shell.py b/tosca2heat/tosca-parser/toscaparser/shell.py
index b41c024..1d98f1a 100644
--- a/tosca2heat/tosca-parser/toscaparser/shell.py
+++ b/tosca2heat/tosca-parser/toscaparser/shell.py
@@ -11,6 +11,7 @@
# under the License.
+import argparse
import os
import sys
@@ -40,19 +41,20 @@ e.g.
class ParserShell(object):
- def _validate(self, args):
- if len(args) < 1:
- msg = _('The program requires a template or a CSAR file as an '
- 'argument. Please refer to the usage documentation.')
- raise ValueError(msg)
- if "--template-file=" not in args[0]:
- msg = _('The program expects "--template-file" as the first '
- 'argument. Please refer to the usage documentation.')
- raise ValueError(msg)
-
- def main(self, args):
- self._validate(args)
- path = args[0].split('--template-file=')[1]
+ def get_parser(self, argv):
+ parser = argparse.ArgumentParser(prog="tosca-parser")
+
+ parser.add_argument('--template-file',
+ metavar='<filename>',
+ required=True,
+ help=_('YAML template or CSAR file to parse.'))
+
+ return parser
+
+ def main(self, argv):
+ parser = self.get_parser(argv)
+ (args, extra_args) = parser.parse_known_args(argv)
+ path = args.template_file
if os.path.isfile(path):
self.parse(path)
elif toscaparser.utils.urlutils.UrlUtils.validate_url(path):
@@ -88,6 +90,18 @@ class ParserShell(object):
for node in nodetemplates:
print("\t" + node.name)
+ # example of retrieving policy object
+ '''if hasattr(tosca, 'policies'):
+ policies = tosca.policies
+ if policies:
+ print("policies:")
+ for policy in policies:
+ print("\t" + policy.name)
+ if policy.triggers:
+ print("\ttriggers:")
+ for trigger in policy.triggers:
+ print("\ttrigger name:" + trigger.name)'''
+
if hasattr(tosca, 'outputs'):
outputs = tosca.outputs
if outputs:
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/base.py b/tosca2heat/tosca-parser/toscaparser/tests/base.py
index f6ff8d1..2619889 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/base.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/base.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
# Copyright 2010-2011 OpenStack Foundation
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csar b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csar
index 5fae801..a514dc6 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csar
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csar
Binary files differ
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zip b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zip
index 5fae801..0d860d4 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zip
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zip
Binary files differ
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml
new file mode 100644
index 0000000..3fd4466
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml
@@ -0,0 +1,44 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ TOSCA simple profile with mysql docker container.
+
+# Repositories to retrieve code artifacts from
+repositories:
+ docker_hub: https://registry.hub.docker.com/
+
+topology_template:
+
+ inputs:
+ mysql_root_pwd:
+ type: string
+ description: Root password for MySQL.
+
+ node_templates:
+ # The MYSQL container based on official MySQL image in Docker hub
+ mysql_container:
+ type: tosca.nodes.Container.Application.Docker
+ requirements:
+ - host: mysql_runtime
+ artifacts:
+ my_image:
+ file: mysql
+ type: tosca.artifacts.Deployment.Image.Container.Docker
+ repository: docker_hub
+ interfaces:
+ Standard:
+ create:
+ implementation: my_image
+ inputs:
+ MYSQL_ROOT_PASSWORD: { get_input: mysql_root_pwd }
+
+ # The properties of the runtime to host the container
+ mysql_runtime:
+ type: tosca.nodes.Container.Runtime
+ capabilities:
+ host:
+ properties:
+ num_cpus: 1
+ disk_size: 10 GB
+ mem_size: 2 MB
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml
index f23a8a1..909a297 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml
@@ -1,6 +1,6 @@
tosca_definitions_version: tosca_simple_yaml_1_0
-description: Compute node type with capability with an atribute of type list
+description: Compute node type with capability with an attribute of type list
capability_types:
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_interface.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_interface.yaml
new file mode 100644
index 0000000..2d9bec4
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_interface.yaml
@@ -0,0 +1,20 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ This template contains custom defined interface type
+ and a node type which uses this custom interface
+
+interface_types:
+ tosca.interfaces.CustomInterface:
+ derived_from: tosca.interfaces.Root
+ CustomOp:
+ CustomOp2:
+
+node_types:
+ tosca.nodes.CustomInterfaceTest:
+ derived_from: tosca.nodes.WebApplication
+ interfaces:
+ CustomInterface:
+ type: tosca.interfaces.CustomInterface
+ CustomOp3:
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml
index 70d0b0f..c8e4532 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml
@@ -32,3 +32,7 @@ policy_types:
type: map
entry_schema:
type: string
+relationship_types1:
+relationship_types:
+ test.relation.connects:
+ derived_from4: tosca.relationships.ConnectsTo
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml
new file mode 100644
index 0000000..6155595
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Test template demonstrating usage of nested dsl_definitions value.
+
+dsl_definitions:
+ caps: &caps
+ host:
+ properties:
+ disk_size: 10 GB
+ num_cpus: 2
+ mem_size: 4096 MB
+ os:
+ properties:
+ architecture: x86_64
+ type: Linux
+ distribution: Ubuntu
+ version: 14.04
+
+topology_template:
+ node_templates:
+ my_server:
+ type: tosca.nodes.Compute
+ capabilities: *caps \ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml
index 923305c..34c1c33 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml
@@ -26,3 +26,5 @@ topology_template:
outputs:
ip_address:
value: { get_attribute: [ unknown_node_template, private_address ] }
+ network:
+ value: { get_attribute: [ unknown_node_template, networks, public ] }
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml
new file mode 100644
index 0000000..a269005
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml
@@ -0,0 +1,25 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ Attribute can be defined explicitly as part of type definition
+ or implicitly via property. This TOSCA template tests validation
+ of attribute name implicitly created as a property and referenced
+ via get_attribute function.
+
+node_types:
+ ServerNode:
+ derived_from: SoftwareComponent
+ properties:
+ notification_port:
+ type: integer
+
+topology_template:
+ node_templates:
+ my_server:
+ type: ServerNode
+ properties:
+ notification_port: 8000
+
+ outputs:
+ ip_address:
+ value: { get_attribute: [ my_server, notification_port ] } \ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml
index 1e5f5e6..1ca69ca 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml
@@ -23,7 +23,6 @@ topology_template:
db_root_pwd:
type: string
description: Root password for MySQL.
- default: '12345678'
db_port:
type: PortDef
description: Port for the MySQL database.
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml
new file mode 100644
index 0000000..c23917c
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ TOSCA simple profile with valid custom interface and operations.
+
+imports:
+ - ../custom_types/custom_interface.yaml
+
+topology_template:
+
+ node_templates:
+ customInterfaceTest:
+ type: tosca.nodes.CustomInterfaceTest
+ interfaces:
+ CustomInterface:
+ CustomOp: # operation from interface_type with additional inputs
+ inputs:
+ param:
+ type: string
+ CustomOp3: # operation from node_type with additional inputs
+ inputs:
+ param3:
+ type: string
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml
new file mode 100644
index 0000000..d56ad9c
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ TOSCA simple profile with invalid custom operation.
+
+imports:
+ - ../custom_types/custom_interface.yaml
+
+topology_template:
+
+ node_templates:
+ customInterfaceTest:
+ type: tosca.nodes.CustomInterfaceTest
+ interfaces:
+ CustomInterface:
+ CustomOp4: # invalid operation
+ inputs:
+ param3:
+ type: string
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml
new file mode 100644
index 0000000..2fcdb48
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml
@@ -0,0 +1,75 @@
+# Note: this could eventually be translated to a Neutron Load Balancer
+# However, in Heat/HOT the preferred way of doing this is creating an Autoscale Group
+#
+#heat_template_version: 2015-04-30 ...
+#resources:
+#load_bal_resource:
+# type: OS::Neutron::Pool
+# properties:
+# admin_state_up: Boolean
+# description: String
+# lb_method: String
+# monitors: [Value, Value, ...]
+# name: String
+# protocol: String
+# provider: String
+# subnet: String
+# vip: {
+# "description": String,
+# "name": String,
+# "connection_limit": Integer,
+# "protocol_port": Integer,
+# "subnet": String,
+# "address": String,
+# "admin_state_up": Boolean,
+# "session_persistence":
+# {
+# "cookie_name": String,
+# "type": String}
+# }
+#
+# example from: https://gist.github.com/therve/9231701
+#
+#resources:
+# web_server_group:
+# type: AWS::AutoScaling::AutoScalingGroup
+# properties:
+# AvailabilityZones: [nova]
+# LaunchConfigurationName: {get_resource: launch_config}
+# MinSize: 1
+# MaxSize: 3
+# LoadBalancerNames:
+# - {get_resource: mylb}
+# mypool:
+# type: OS::Neutron::Pool
+# properties:
+# protocol: HTTP
+# monitors: [{get_resource: mymonitor}]
+# subnet_id: {get_param: subnet_id}
+# lb_method: ROUND_ROBIN
+# vip:
+# protocol_port: 80
+# mylb:
+# type: OS::Neutron::LoadBalancer
+# properties:
+# protocol_port: 80
+# pool_id: {get_resource: mypool}
+
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a load balancer with predefined endpoint properties.
+
+topology_template:
+ node_templates:
+ simple_load_balancer:
+ type: tosca.nodes.LoadBalancer
+ capabilities:
+ # properties:
+ # algorithm: DEFAULT (define new keyword, ROUND_ROBIN?)
+ # Client, public facing endpoint
+ client:
+ properties:
+ network_name: PUBLIC
+ floating: true
+ dns_name: http://mycompany.com/
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/node_filter/test_node_filter.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/node_filter/test_node_filter.yaml
new file mode 100644
index 0000000..3dd8e26
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/node_filter/test_node_filter.yaml
@@ -0,0 +1,18 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template with requirements against hosting infrastructure.
+
+topology_template:
+
+ node_templates:
+ test:
+ type: tosca.nodes.DBMS
+ requirements:
+ - host:
+ node_filter:
+ capabilities:
+ - host:
+ properties:
+ - num_cpus: { in_range: [ 1, 4 ] }
+ - mem_size: { greater_or_equal: 2 GB }
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_defs.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_defs.yaml
new file mode 100644
index 0000000..96b0d45
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_defs.yaml
@@ -0,0 +1,183 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+data_types:
+ tosca.datatypes.tacker.ActionMap:
+ properties:
+ trigger:
+ type: string
+ required: true
+ action:
+ type: string
+ required: true
+ params:
+ type: map
+ entry_schema:
+ type: string
+ required: false
+
+ tosca.datatypes.tacker.MonitoringParams:
+ properties:
+ monitoring_delay:
+ type: int
+ required: false
+ count:
+ type: int
+ required: false
+ interval:
+ type: int
+ required: false
+ timeout:
+ type: int
+ required: false
+ retry:
+ type: int
+ required: false
+ port:
+ type: int
+ required: false
+
+ tosca.datatypes.tacker.MonitoringType:
+ properties:
+ name:
+ type: string
+ required: true
+ actions:
+ type: map
+ required: true
+ parameters:
+ type: tosca.datatypes.tacker.MonitoringParams
+ required: false
+
+ tosca.datatypes.compute_properties:
+ properties:
+ num_cpus:
+ type: integer
+ required: false
+ mem_size:
+ type: string
+ required: false
+ disk_size:
+ type: string
+ required: false
+ mem_page_size:
+ type: string
+ required: false
+ numa_node_count:
+ type: integer
+ constraints:
+ - greater_or_equal: 2
+ required: false
+ numa_nodes:
+ type: map
+ required: false
+ cpu_allocation:
+ type: map
+ required: false
+
+policy_types:
+ tosca.policies.tacker.Placement:
+ derived_from: tosca.policies.Root
+
+ tosca.policies.tacker.Failure:
+ derived_from: tosca.policies.Root
+ action:
+ type: string
+
+ tosca.policies.tacker.Failure.Respawn:
+ derived_from: tosca.policies.tacker.Failure
+ action: respawn
+
+ tosca.policies.tacker.Failure.Terminate:
+ derived_from: tosca.policies.tacker.Failure
+ action: log_and_kill
+
+ tosca.policies.tacker.Failure.Log:
+ derived_from: tosca.policies.tacker.Failure
+ action: log
+
+ tosca.policies.tacker.Monitoring:
+ derived_from: tosca.policies.Root
+ properties:
+ name:
+ type: string
+ required: true
+ parameters:
+ type: map
+ entry_schema:
+ type: string
+ required: false
+ actions:
+ type: map
+ entry_schema:
+ type: string
+ required: true
+
+ tosca.policies.tacker.Monitoring.NoOp:
+ derived_from: tosca.policies.tacker.Monitoring
+ properties:
+ name: noop
+
+ tosca.policies.tacker.Monitoring.Ping:
+ derived_from: tosca.policies.tacker.Monitoring
+ properties:
+ name: ping
+
+ tosca.policies.tacker.Monitoring.HttpPing:
+ derived_from: tosca.policies.tacker.Monitoring.Ping
+ properties:
+ name: http-ping
+
+ tosca.policies.tacker.Alarming:
+ derived_from: tosca.policies.Monitoring
+ triggers:
+ resize_compute:
+ event_type:
+ type: map
+ entry_schema:
+ type: string
+ required: true
+ metrics:
+ type: string
+ required: true
+ condition:
+ type: map
+ entry_schema:
+ type: string
+ required: false
+ action:
+ type: map
+ entry_schema:
+ type: string
+ required: true
+
+ tosca.policies.tacker.Scaling:
+ derived_from: tosca.policies.Scaling
+ description: Defines policy for scaling the given targets.
+ properties:
+ increment:
+ type: integer
+ required: true
+ description: Number of nodes to add or remove during the scale out/in.
+ targets:
+ type: list
+ entry_schema:
+ type: string
+ required: true
+ description: List of Scaling nodes.
+ min_instances:
+ type: integer
+ required: true
+ description: Minimum number of instances to scale in.
+ max_instances:
+ type: integer
+ required: true
+ description: Maximum number of instances to scale out.
+ default_instances:
+ type: integer
+ required: true
+ description: Initial number of instances.
+ cooldown:
+ type: integer
+ required: false
+ default: 120
+ description: Wait time (in seconds) between consecutive scaling operations. During the cooldown period...
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml
new file mode 100644
index 0000000..1387509
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml
@@ -0,0 +1,261 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+data_types:
+ tosca.nfv.datatypes.pathType:
+ properties:
+ forwarder:
+ type: string
+ required: true
+ capability:
+ type: string
+ required: true
+
+ tosca.nfv.datatypes.aclType:
+ properties:
+ eth_type:
+ type: string
+ required: false
+ eth_src:
+ type: string
+ required: false
+ eth_dst:
+ type: string
+ required: false
+ vlan_id:
+ type: integer
+ constraints:
+ - in_range: [ 1, 4094 ]
+ required: false
+ vlan_pcp:
+ type: integer
+ constraints:
+ - in_range: [ 0, 7 ]
+ required: false
+ mpls_label:
+ type: integer
+ constraints:
+ - in_range: [ 16, 1048575]
+ required: false
+ mpls_tc:
+ type: integer
+ constraints:
+ - in_range: [ 0, 7 ]
+ required: false
+ ip_dscp:
+ type: integer
+ constraints:
+ - in_range: [ 0, 63 ]
+ required: false
+ ip_ecn:
+ type: integer
+ constraints:
+ - in_range: [ 0, 3 ]
+ required: false
+ ip_src_prefix:
+ type: string
+ required: false
+ ip_dst_prefix:
+ type: string
+ required: false
+ ip_proto:
+ type: integer
+ constraints:
+ - in_range: [ 1, 254 ]
+ required: false
+ destination_port_range:
+ type: string
+ required: false
+ source_port_range:
+ type: string
+ required: false
+ network_src_port_id:
+ type: string
+ required: false
+ network_dst_port_id:
+ type: string
+ required: false
+ network_id:
+ type: string
+ required: false
+ network_name:
+ type: string
+ required: false
+ tenant_id:
+ type: string
+ required: false
+ icmpv4_type:
+ type: integer
+ constraints:
+ - in_range: [ 0, 254 ]
+ required: false
+ icmpv4_code:
+ type: integer
+ constraints:
+ - in_range: [ 0, 15 ]
+ required: false
+ arp_op:
+ type: integer
+ constraints:
+ - in_range: [ 1, 25 ]
+ required: false
+ arp_spa:
+ type: string
+ required: false
+ arp_tpa:
+ type: string
+ required: false
+ arp_sha:
+ type: string
+ required: false
+ arp_tha:
+ type: string
+ required: false
+ ipv6_src:
+ type: string
+ required: false
+ ipv6_dst:
+ type: string
+ required: false
+ ipv6_flabel:
+ type: integer
+ constraints:
+ - in_range: [ 0, 1048575]
+ required: false
+ icmpv6_type:
+ type: integer
+ constraints:
+ - in_range: [ 0, 255]
+ required: false
+ icmpv6_code:
+ type: integer
+ constraints:
+ - in_range: [ 0, 7]
+ required: false
+ ipv6_nd_target:
+ type: string
+ required: false
+ ipv6_nd_sll:
+ type: string
+ required: false
+ ipv6_nd_tll:
+ type: string
+ required: false
+
+ tosca.nfv.datatypes.policyType:
+ properties:
+ type:
+ type: string
+ required: false
+ constraints:
+ - valid_values: [ ACL ]
+ criteria:
+ type: list
+ required: true
+ entry_schema:
+ type: tosca.nfv.datatypes.aclType
+
+node_types:
+ tosca.nodes.nfv.VDU.Tacker:
+ derived_from: tosca.nodes.nfv.VDU
+ capabilities:
+ nfv_compute:
+ type: tosca.datatypes.compute_properties
+ properties:
+ name:
+ type: string
+ required: false
+ image:
+# type: tosca.artifacts.Deployment.Image.VM
+ type: string
+ required: false
+ flavor:
+ type: string
+ required: false
+ availability_zone:
+ type: string
+ required: false
+ metadata:
+ type: map
+ entry_schema:
+ type: string
+ required: false
+ config_drive:
+ type: boolean
+ default: false
+ required: false
+
+ placement_policy:
+# type: tosca.policies.tacker.Placement
+ type: string
+ required: false
+
+ monitoring_policy:
+# type: tosca.policies.tacker.Monitoring
+# type: tosca.datatypes.tacker.MonitoringType
+ type: map
+ required: false
+
+ config:
+ type: string
+ required: false
+
+ mgmt_driver:
+ type: string
+ default: noop
+ required: false
+
+ service_type:
+ type: string
+ required: false
+
+ user_data:
+ type: string
+ required: false
+
+ user_data_format:
+ type: string
+ required: false
+
+ key_name:
+ type: string
+ required: false
+
+ tosca.nodes.nfv.CP.Tacker:
+ derived_from: tosca.nodes.nfv.CP
+ properties:
+ mac_address:
+ type: string
+ required: false
+ name:
+ type: string
+ required: false
+ management:
+ type: boolean
+ required: false
+ anti_spoofing_protection:
+ type: boolean
+ required: false
+ security_groups:
+ type: list
+ required: false
+ type:
+ type: string
+ required: false
+ constraints:
+ - valid_values: [ sriov, vnic ]
+
+ tosca.nodes.nfv.FP.Tacker:
+ derived_from: tosca.nodes.Root
+ properties:
+ id:
+ type: integer
+ required: false
+ policy:
+ type: tosca.nfv.datatypes.policyType
+ required: true
+ description: policy to use to match traffic for this FP
+ path:
+ type: list
+ required: true
+ entry_schema:
+ type: tosca.nfv.datatypes.pathType
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml
new file mode 100644
index 0000000..452dbb5
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml
@@ -0,0 +1,95 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+description: sample-tosca-vnfd-scaling
+
+imports:
+ - tacker_defs.yaml
+ - tacker_nfv_defs.yaml
+
+metadata:
+ template_name: sample-tosca-vnfd-scaling
+
+topology_template:
+ node_templates:
+ VDU1:
+ type: tosca.nodes.nfv.VDU.Tacker
+ properties:
+ image: cirros-0.3.4-x86_64-uec
+ mgmt_driver: noop
+ availability_zone: nova
+ flavor: m1.tiny
+
+ CP1:
+ type: tosca.nodes.nfv.CP.Tacker
+ properties:
+ management: true
+ order: 0
+ anti_spoofing_protection: false
+ requirements:
+ - virtualLink:
+ node: VL1
+ - virtualBinding:
+ node: VDU1
+
+ VDU2:
+ type: tosca.nodes.nfv.VDU.Tacker
+ properties:
+ image: cirros-0.3.4-x86_64-uec
+ mgmt_driver: noop
+ availability_zone: nova
+ flavor: m1.tiny
+
+ CP2:
+ type: tosca.nodes.nfv.CP.Tacker
+ properties:
+ management: true
+ order: 0
+ anti_spoofing_protection: false
+ requirements:
+ - virtualLink:
+ node: VL1
+ - virtualBinding:
+ node: VDU2
+
+ VL1:
+ type: tosca.nodes.nfv.VL
+ properties:
+ network_name: net_mgmt
+ vendor: Tacker
+
+ policies:
+ - SP1:
+ type: tosca.policies.tacker.Scaling
+ targets: [VDU1]
+ properties:
+ increment: 1
+ cooldown: 120
+ min_instances: 1
+ max_instances: 2
+ default_instances: 1
+
+ - SP2:
+ type: tosca.policies.tacker.Scaling
+ targets: [VDU2]
+ properties:
+ increment: 1
+ cooldown: 120
+ min_instances: 1
+ max_instances: 2
+ default_instances: 1
+
+ - ALRM1:
+ type: tosca.policies.tacker.Monitoring
+ triggers:
+ resize_compute:
+ event_type:
+ type: tosca.events.resource.utilization
+ implementation: ceilometer
+ condition:
+ constraint: 50
+ period: 600
+ evaluations: 1
+ method: avg
+ action:
+ resize_compute:
+ action_name: SP1
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml
index 92bebe5..47f7870 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml
@@ -66,7 +66,7 @@ topology_template:
requirement: host
capability: Container
condition:
- constraint: utilization greater_than 50%
+ constraint: { greater_than: 50 }
period: 60
evaluations: 1
method: average
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/relationship/test_custom_relationship.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/relationship/test_custom_relationship.yaml
new file mode 100644
index 0000000..81b92b4
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/relationship/test_custom_relationship.yaml
@@ -0,0 +1,48 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Test template for deploying a single server with predefined properties and custom relationship types
+
+imports:
+ - ../custom_types/custom_relationship_type_defs.yaml
+
+topology_template:
+ node_templates:
+ server1:
+ type: tosca.nodes.HACompute
+ capabilities:
+ # Host container properties
+ host:
+ properties:
+ num_cpus: 2
+ disk_size: 10 GB
+ mem_size: 512 MB
+ # Guest Operating System properties
+ os:
+ properties:
+ # host Operating System image properties
+ architecture: x86_64
+ type: Linux
+ distribution: RHEL
+ version: 6.5
+ requirements:
+ - high_availability: server2
+
+ server2:
+ type: tosca.nodes.HACompute
+ capabilities:
+ # Host container properties
+ host:
+ properties:
+ num_cpus: 2
+ disk_size: 10 GB
+ mem_size: 512 MB
+ # Guest Operating System properties
+ os:
+ properties:
+ # host Operating System image properties
+ architecture: x86_64
+ type: Linux
+ distribution: RHEL
+ version: 6.5
+ requirements:
+ - high_availability: server1
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/test_repositories_definition.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/test_repositories_definition.yaml
new file mode 100644
index 0000000..c2856c8
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/test_repositories_definition.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+repositories:
+ some_repository:
+ description: Some repo
+ url: https://raw.githubusercontent.com/openstack/tosca-parser/master/toscaparser/tests/data/custom_types/
+ credential: #type: Credential
+ token_type: basic_auth
+ token: myusername:mypassword
+imports:
+ - some_import:
+ file: compute_with_prop.yaml
+ repository: some_repository
+
+description: >
+ TOSCA test for testing repositories definition
+
+ node_templates:
+
+ server:
+ type: tosca.nodes.ComputeWithProp
+ properties:
+ test: yes
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml
new file mode 100644
index 0000000..0001d06
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml
@@ -0,0 +1,26 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile with repositories validation and imports.
+
+repositories:
+ repo_code0: https://raw.githubusercontent.com/nandinivemula/intern
+ repo_code1:
+ description: My project's code Repository in github usercontent.
+ url: https://raw.githubusercontent.com/nandinivemula/intern/master
+ credential: #type: Credential
+ token_type: basic_auth
+ token: myusername:mypassword
+
+ repo_code2:
+ description: My Project's code Repository in github.
+ url: https://github.com/nandinivemula/intern/master
+ credential: #type: Credential
+ token_type: basic_auth
+ token: myusername:mypassword
+
+imports:
+ - sample_import:
+ file: tosca_repository_import.yaml
+ repository: repo_code1
+ namespace_uri: https://github.com/nandinivemula/intern
+ namespace_prefix: intern
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/requirements/test_requirements.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/requirements/test_requirements.yaml
new file mode 100644
index 0000000..bb67577
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/requirements/test_requirements.yaml
@@ -0,0 +1,67 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ Test Requirements.
+
+imports:
+ - ../custom_types/wordpress.yaml
+
+topology_template:
+ node_templates:
+ my_app:
+ description: >
+ Specify multiple requirement via node and relationship keyword,
+ as an explicit relationship. Also demonstrates relationship with
+ type keyword and without it as an in-line reference.
+ type: tosca.nodes.WebApplication.WordPress
+ requirements:
+ - req1:
+ node: my_webserver
+ relationship: tosca.relationships.HostedOn
+ - req2:
+ node: mysql_database
+ relationship:
+ type: tosca.relationships.ConnectsTo
+ mysql_database:
+ description: Specify requirement via a capability as an implicit relationship.
+ type: tosca.nodes.Database
+ requirements:
+ - host:
+ node: my_dbms
+ relationship: tosca.relationships.HostedOn
+ my_dbms:
+ type: tosca.nodes.DBMS
+ my_webserver:
+ type: tosca.nodes.WebServer
+ my_server:
+ description: >
+ Specify requirement via a relationship template, as an explicit relationship.
+ type: tosca.nodes.Compute
+ capabilities:
+ host:
+ properties:
+ num_cpus: 2
+ disk_size: 10 GB
+ mem_size: 4 MB
+ os:
+ properties:
+ # host Operating System image properties
+ architecture: x86_64
+ type: linux
+ distribution: rhel
+ version: 6.5
+ requirements:
+ - req1:
+ node: my_storage
+ relationship: storage_attachment
+ my_storage:
+ type: tosca.nodes.BlockStorage
+ properties:
+ size: 1 GiB
+ snapshot_id: id
+
+ relationship_templates:
+ storage_attachment:
+ type: tosca.relationships.AttachesTo
+ properties:
+ location: /temp
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_endpoint_on_compute.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_endpoint_on_compute.yaml
new file mode 100644
index 0000000..cf2ec94
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/test_endpoint_on_compute.yaml
@@ -0,0 +1,21 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+topology_template:
+ node_templates:
+ server:
+ type: tosca.nodes.Compute
+ capabilities:
+ host:
+ properties:
+ disk_size: 10 GB
+ num_cpus: 1
+ mem_size: 4096 MB
+ os:
+ properties:
+ architecture: x86_64
+ type: Linux
+ distribution: Ubuntu
+ version: 14.04
+ endpoint:
+ properties:
+ network_name: PUBLIC
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml
index ccae4eb..479a1ec 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml
@@ -35,6 +35,9 @@ topology_template:
default: 3306
node_templates:
+ xyz:
+ type: tosca.nodes.XYZ
+
wordpress:
type: tosca.nodes.WebApplication.WordPress
requirement:
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_normative_type_properties_override.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_normative_type_properties_override.yaml
new file mode 100644
index 0000000..3c3e272
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/test_normative_type_properties_override.yaml
@@ -0,0 +1,37 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ Test template for deploying a server with custom properties for image,
+ flavor and key_name. This template provides an example of how to
+ override TOSCA normative type's (e.g. Compute) properties. Here new
+ properties are injected in the tosca.nodes.myserver which derives from
+ tosca.nodes.Compute. Note that tosca.nodes.myserver can not be a name of
+ another normative type (e.g. tosca.nodes.WebServer or tosca.nodes.nfv.VDU)
+ because that will create conflict while resolving type definition by the
+ TOSCA Parser.
+
+node_types:
+ tosca.nodes.myserver:
+ derived_from: tosca.nodes.Compute
+ properties:
+ key_name:
+ type: string
+ image:
+ type: string
+ flavor:
+ type: string
+
+topology_template:
+ inputs:
+ key_name:
+ type: string
+ default: inputkey
+
+ node_templates:
+ my_server:
+ type: tosca.nodes.myserver
+ properties:
+ flavor: m1.medium
+ image: rhel-6.5-test-image
+ key_name:
+ get_input: key_name
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml
index 77829c6..ba5eac1 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml
@@ -27,8 +27,10 @@ node_types:
properties:
mq_server_ip:
type: string
+ required: False
receiver_port:
type: integer
+ required: False
attributes:
receiver_ip:
type: string
@@ -51,8 +53,10 @@ node_types:
properties:
admin_user:
type: string
+ required: False
pool_size:
type: integer
+ required: False
capabilities:
message_receiver:
type: example.capabilities.Receiver
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml
new file mode 100644
index 0000000..718022a
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml
@@ -0,0 +1,70 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+ Template showing an example TOSCA type to demonstrate usage
+ of output in the substitution mappings.
+
+node_types:
+ example.app:
+ derived_from: tosca.nodes.WebApplication
+ properties:
+ mq_server_ip:
+ type: string
+ required: False
+ receiver_port:
+ type: integer
+ required: False
+ attributes:
+ receiver_ip:
+ type: string
+ receiver_port:
+ type: integer
+
+topology_template:
+ inputs:
+ mq_server_ip:
+ type: string
+ description: IP address of the message queuing server to receive messages from.
+ default: 127.0.0.1
+ receiver_port:
+ type: integer
+ description: Port to be used for receiving messages.
+ default: 8080
+ my_cpus:
+ type: integer
+ description: Number of CPUs for the server.
+ default: 2
+ constraints:
+ - valid_values: [ 1, 2, 4, 8 ]
+
+ substitution_mappings:
+ node_type: example.app
+
+ node_templates:
+ app:
+ type: example.app
+ properties:
+ mq_server_ip: { get_input: mq_server_ip }
+ receiver_port: { get_input: receiver_port }
+ requirements:
+ - host:
+ node: websrv
+ websrv:
+ type: tosca.nodes.WebServer
+ requirements:
+ - host:
+ node: server
+ server:
+ type: tosca.nodes.Compute
+ capabilities:
+ host:
+ properties:
+ disk_size: 10 GB
+ num_cpus: { get_input: my_cpus }
+ mem_size: 4096 MB
+ os:
+ properties:
+ architecture: x86_64
+ type: Linux
+ distribution: Ubuntu
+ version: 14.04
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml
new file mode 100644
index 0000000..ef21811
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml
@@ -0,0 +1,31 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+ - test_example_app_substitution_mappings.yaml
+
+topology_template:
+ description: >
+ Test template showing valid output section containing attribute defined
+ in the substitution mappings in the imported yaml file.
+
+ inputs:
+ mq_server_ip:
+ type: string
+ default: 127.0.0.1
+ description: IP address of the message queuing server to receive messages from.
+ mq_server_port:
+ type: integer
+ default: 8080
+ description: Port to be used for receiving messages.
+
+ node_templates:
+ substitute_app:
+ type: example.app
+ properties:
+ mq_server_ip: { get_input: mq_server_ip }
+ receiver_port: { get_input: mq_server_port }
+
+ outputs:
+ receiver_ip:
+ description: private IP address of the message receiver application
+ value: { get_attribute: [ substitute_app, my_cpu_output ] } \ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml
new file mode 100644
index 0000000..766ca87
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml
@@ -0,0 +1,31 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+ - test_example_app_substitution_mappings.yaml
+
+topology_template:
+ description: >
+ Test template showing valid output section containing attribute defined
+ in the substitution mappings in the imported yaml file.
+
+ inputs:
+ mq_server_ip:
+ type: string
+ default: 127.0.0.1
+ description: IP address of the message queuing server to receive messages from.
+ mq_server_port:
+ type: integer
+ default: 8080
+ description: Port to be used for receiving messages.
+
+ node_templates:
+ sustitute_app:
+ type: example.app
+ properties:
+ mq_server_ip: { get_input: mq_server_ip }
+ receiver_port: { get_input: mq_server_port }
+
+ outputs:
+ receiver_ip:
+ description: private IP address of the message receiver application
+ value: { get_attribute: [ sustitute_app, receiver_ip ] } \ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml
index 9c3fef4..257beb8 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml
@@ -37,3 +37,9 @@ topology_template:
metadata:
user1: 1001
user2: 1003
+ relationship_templates:
+ my_custom_rel:
+ type: test.relation.connects
+ interfaces:
+ Configure:
+ pre_configure_source: scripts/wp_db_configure.sh
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml
index f605b05..9e686ab 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml
@@ -29,7 +29,6 @@ topology_template:
db_root_pwd:
type: string
description: Root password for MySQL.
- default: '12345678'
db_port:
type: PortDef
description: Port for the MySQL database.
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml
index 9a57eb0..6caac11 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml
@@ -31,7 +31,6 @@ topology_template:
db_root_pwd:
type: string
description: Root password for MySQL.
- default: '12345678'
db_port:
type: PortDef
description: Port for the MySQL database.
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
index 5d41749..e5f1580 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
@@ -29,7 +29,6 @@ topology_template:
db_root_pwd:
type: string
description: Root password for MySQL.
- default: '12345678'
db_port:
type: PortDef
description: Port for the MySQL database.
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_test_get_operation_output.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_test_get_operation_output.yaml
new file mode 100644
index 0000000..f47f33c
--- /dev/null
+++ b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_test_get_operation_output.yaml
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile to test the GET OPERATION OUTPUT functionality
+
+imports:
+ - custom_types/compute_with_prop.yaml
+
+topology_template:
+
+ node_templates:
+
+ front_end:
+ type: tosca.nodes.ComputeWithProp
+ interfaces:
+ Standard:
+ create:
+ implementation: nodejs/create.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end,Standard,create,data_dir]}
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py b/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py
index 71de0c2..9ae85d5 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py
@@ -21,7 +21,7 @@ class CustomRelationshipTypesTest(TestCase):
'''TOSCA template.'''
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/test_custom_relationships.yaml")
+ "data/relationship/test_custom_relationship.yaml")
tosca = ToscaTemplate(tosca_tpl)
def test_version(self):
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_functions.py b/tosca2heat/tosca-parser/toscaparser/tests/test_functions.py
index 81de909..fa60140 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_functions.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_functions.py
@@ -24,7 +24,8 @@ class IntrinsicFunctionsTest(TestCase):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_single_instance_wordpress.yaml")
- params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user'}
+ params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+ 'db_root_pwd': '12345678'}
tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
def _get_node(self, node_name, tosca=None):
@@ -56,7 +57,7 @@ class IntrinsicFunctionsTest(TestCase):
wordpress = self._get_node('wordpress')
operation = self._get_operation(wordpress.interfaces, 'configure')
wp_db_password = operation.inputs['wp_db_password']
- self.assertTrue(isinstance(wp_db_password, functions.GetProperty))
+ self.assertIsInstance(wp_db_password, functions.GetProperty)
result = wp_db_password.result()
self.assertEqual('wp_pass', result)
@@ -64,7 +65,7 @@ class IntrinsicFunctionsTest(TestCase):
wordpress = self._get_node('wordpress')
operation = self._get_operation(wordpress.interfaces, 'configure')
wp_db_user = operation.inputs['wp_db_user']
- self.assertTrue(isinstance(wp_db_user, functions.GetProperty))
+ self.assertIsInstance(wp_db_user, functions.GetProperty)
result = wp_db_user.result()
self.assertEqual('my_db_user', result)
@@ -83,7 +84,7 @@ class IntrinsicFunctionsTest(TestCase):
props = mysql_dbms.get_properties()
for key in props.keys():
prop = props[key]
- self.assertTrue(isinstance(prop.value, functions.GetInput))
+ self.assertIsInstance(prop.value, functions.GetInput)
expected_inputs.remove(prop.value.input_name)
self.assertListEqual(expected_inputs, [])
@@ -116,21 +117,24 @@ class IntrinsicFunctionsTest(TestCase):
self.assertEqual(3306, dbms_port.result())
dbms_root_password = self._get_property(mysql_dbms,
'root_password')
- self.assertEqual(dbms_root_password.result(), "12345678")
+ self.assertEqual(dbms_root_password.result(), '12345678')
def test_get_property_with_host(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/functions/test_get_property_with_host.yaml")
mysql_database = self._get_node('mysql_database',
- ToscaTemplate(tosca_tpl))
+ ToscaTemplate(tosca_tpl,
+ parsed_params={
+ 'db_root_pwd': '123'
+ }))
operation = self._get_operation(mysql_database.interfaces, 'configure')
db_port = operation.inputs['db_port']
- self.assertTrue(isinstance(db_port, functions.GetProperty))
+ self.assertIsInstance(db_port, functions.GetProperty)
result = db_port.result()
self.assertEqual(3306, result)
test = operation.inputs['test']
- self.assertTrue(isinstance(test, functions.GetProperty))
+ self.assertIsInstance(test, functions.GetProperty)
result = test.result()
self.assertEqual(1, result)
@@ -138,30 +142,37 @@ class IntrinsicFunctionsTest(TestCase):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/functions/tosca_nested_property_names_indexes.yaml")
- webserver = self._get_node('wordpress', ToscaTemplate(tosca_tpl))
+ webserver = self._get_node('wordpress',
+ ToscaTemplate(tosca_tpl,
+ parsed_params={
+ 'db_root_pwd': '1234'}))
operation = self._get_operation(webserver.interfaces, 'configure')
wp_endpoint_prot = operation.inputs['wp_endpoint_protocol']
- self.assertTrue(isinstance(wp_endpoint_prot, functions.GetProperty))
+ self.assertIsInstance(wp_endpoint_prot, functions.GetProperty)
self.assertEqual('tcp', wp_endpoint_prot.result())
wp_list_prop = operation.inputs['wp_list_prop']
- self.assertTrue(isinstance(wp_list_prop, functions.GetProperty))
+ self.assertIsInstance(wp_list_prop, functions.GetProperty)
self.assertEqual(3, wp_list_prop.result())
def test_get_property_with_capabilties_inheritance(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/functions/test_capabilties_inheritance.yaml")
- some_node = self._get_node('some_node', ToscaTemplate(tosca_tpl))
+ some_node = self._get_node('some_node',
+ ToscaTemplate(tosca_tpl,
+ parsed_params={
+ 'db_root_pwd': '1234'}))
operation = self._get_operation(some_node.interfaces, 'configure')
some_input = operation.inputs['some_input']
- self.assertTrue(isinstance(some_input, functions.GetProperty))
+ self.assertIsInstance(some_input, functions.GetProperty)
self.assertEqual('someval', some_input.result())
def test_get_property_source_target_keywords(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/functions/test_get_property_source_target_keywords.yaml")
- tosca = ToscaTemplate(tosca_tpl)
+ tosca = ToscaTemplate(tosca_tpl,
+ parsed_params={'db_root_pwd': '1234'})
for node in tosca.nodetemplates:
for relationship, trgt in node.relationships.items():
@@ -171,10 +182,10 @@ class IntrinsicFunctionsTest(TestCase):
operation = self._get_operation(rel_template.interfaces,
'pre_configure_source')
target_test = operation.inputs['target_test']
- self.assertTrue(isinstance(target_test, functions.GetProperty))
+ self.assertIsInstance(target_test, functions.GetProperty)
self.assertEqual(1, target_test.result())
source_port = operation.inputs['source_port']
- self.assertTrue(isinstance(source_port, functions.GetProperty))
+ self.assertIsInstance(source_port, functions.GetProperty)
self.assertEqual(3306, source_port.result())
@@ -184,7 +195,8 @@ class GetAttributeTest(TestCase):
return ToscaTemplate(os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'data',
- filename))
+ filename),
+ parsed_params={'db_root_pwd': '1234'})
def _get_operation(self, interfaces, operation):
return [
@@ -283,7 +295,8 @@ class GetAttributeTest(TestCase):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/functions/test_get_attribute_source_target_keywords.yaml")
- tosca = ToscaTemplate(tosca_tpl)
+ tosca = ToscaTemplate(tosca_tpl,
+ parsed_params={'db_root_pwd': '12345678'})
for node in tosca.nodetemplates:
for relationship, trgt in node.relationships.items():
@@ -293,14 +306,18 @@ class GetAttributeTest(TestCase):
operation = self._get_operation(rel_template.interfaces,
'pre_configure_source')
target_test = operation.inputs['target_test']
- self.assertTrue(isinstance(target_test, functions.GetAttribute))
+ self.assertIsInstance(target_test, functions.GetAttribute)
source_port = operation.inputs['source_port']
- self.assertTrue(isinstance(source_port, functions.GetAttribute))
+ self.assertIsInstance(source_port, functions.GetAttribute)
def test_get_attribute_with_nested_params(self):
self._load_template(
'functions/test_get_attribute_with_nested_params.yaml')
+ def test_implicit_attribute(self):
+ self.assertIsNotNone(self._load_template(
+ 'functions/test_get_implicit_attribute.yaml'))
+
class ConcatTest(TestCase):
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py b/tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py
index fcd1c83..09a24b6 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py
@@ -243,7 +243,7 @@ class GetNumFromScalarUnitSizeNegative(TestCase):
(ScalarUnit_Size(self.InputMemSize).
get_num_from_scalar_unit(self.UserInputUnit))
except Exception as error:
- self.assertTrue(isinstance(error, ValueError))
+ self.assertIsInstance(error, ValueError)
self.assertEqual(_('The unit "qB" is not valid. Valid units are '
'"[\'B\', \'GB\', \'GiB\', \'KiB\', \'MB\', '
'\'MiB\', \'TB\', \'TiB\', \'kB\']".'),
@@ -260,7 +260,7 @@ class GetNumFromScalarUnitFrequencyNegative(TestCase):
(ScalarUnit_Frequency(self.InputFrequency).
get_num_from_scalar_unit(self.UserInputUnit))
except Exception as error:
- self.assertTrue(isinstance(error, ValueError))
+ self.assertIsInstance(error, ValueError)
self.assertEqual(_('The unit "Jz" is not valid. Valid units are '
'"[\'GHz\', \'Hz\', \'MHz\', \'kHz\']".'),
error.__str__())
@@ -276,7 +276,7 @@ class GetNumFromScalarUnitTimeNegative(TestCase):
(ScalarUnit_Time(self.InputTime).
get_num_from_scalar_unit(self.UserInputUnit))
except Exception as error:
- self.assertTrue(isinstance(error, ValueError))
+ self.assertIsInstance(error, ValueError)
self.assertEqual(_('"Jz" is not a valid scalar-unit.'),
error.__str__())
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_shell.py b/tosca2heat/tosca-parser/toscaparser/tests/test_shell.py
index e0b5a4e..bb163ff 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_shell.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_shell.py
@@ -29,16 +29,10 @@ class ShellTest(TestCase):
"data/test_multiple_validation_errors.yaml")
def test_missing_arg(self):
- error = self.assertRaises(ValueError, shell.main, '')
- err_msg = _('The program requires a template or a CSAR file as an '
- 'argument. Please refer to the usage documentation.')
- self.assertEqual(err_msg, str(error))
+ self.assertRaises(SystemExit, shell.main, '')
def test_invalid_arg(self):
- error = self.assertRaises(ValueError, shell.main, 'parse me')
- err_msg = _('The program expects "--template-file" as the first '
- 'argument. Please refer to the usage documentation.')
- self.assertEqual(err_msg, str(error))
+ self.assertRaises(SystemExit, shell.main, 'parse me')
def test_template_not_exist(self):
error = self.assertRaises(
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py b/tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py
index 0c26b67..3aabc9b 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py
@@ -220,48 +220,48 @@ class TopologyTemplateTest(TestCase):
self.assertEqual(expected_message, err.__str__())
def test_invalid_nodetype(self):
- tpl_snippet = '''
- substitution_mappings:
- node_type: example.DatabaseSubsystem1
- capabilities:
- database_endpoint: [ db_app, database_endpoint ]
- requirements:
- receiver1: [ tran_app, receiver1 ]
- '''
- sub_mappings = (toscaparser.utils.yamlparser.
- simple_parse(tpl_snippet))['substitution_mappings']
- custom_defs = self._get_custom_types()
- expected_message = _('Node type "example.DatabaseSubsystem1" '
- 'is not a valid type.')
- err = self.assertRaises(
- exception.InvalidNodeTypeError,
- lambda: SubstitutionMappings(sub_mappings, None, None,
- None, None, custom_defs))
- self.assertEqual(expected_message, err.__str__())
+ tpl_snippet = '''
+ substitution_mappings:
+ node_type: example.DatabaseSubsystem1
+ capabilities:
+ database_endpoint: [ db_app, database_endpoint ]
+ requirements:
+ receiver1: [ tran_app, receiver1 ]
+ '''
+ sub_mappings = (toscaparser.utils.yamlparser.
+ simple_parse(tpl_snippet))['substitution_mappings']
+ custom_defs = self._get_custom_types()
+ expected_message = _('Node type "example.DatabaseSubsystem1" '
+ 'is not a valid type.')
+ err = self.assertRaises(
+ exception.InvalidNodeTypeError,
+ lambda: SubstitutionMappings(sub_mappings, None, None,
+ None, None, custom_defs))
+ self.assertEqual(expected_message, err.__str__())
def test_system_with_input_validation(self):
- tpl_path0 = os.path.join(
- os.path.dirname(os.path.abspath(__file__)),
- "data/topology_template/validate/system_invalid_input.yaml")
- tpl_path1 = os.path.join(
- os.path.dirname(os.path.abspath(__file__)),
- "data/topology_template/validate/"
- "queuingsubsystem_invalid_input.yaml")
- errormsg = _('SubstitutionMappings with node_type '
- 'example.QueuingSubsystem is missing '
- 'required input definition of input "server_port".')
-
- # It's invalid in nested template.
- self.assertRaises(exception.ValidationError,
- lambda: ToscaTemplate(tpl_path0))
- exception.ExceptionCollector.assertExceptionMessage(
- exception.MissingRequiredInputError, errormsg)
-
- # Subtemplate deploy standaolone is also invalid.
- self.assertRaises(exception.ValidationError,
- lambda: ToscaTemplate(tpl_path1))
- exception.ExceptionCollector.assertExceptionMessage(
- exception.MissingRequiredInputError, errormsg)
+ tpl_path0 = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/topology_template/validate/system_invalid_input.yaml")
+ tpl_path1 = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/topology_template/validate/"
+ "queuingsubsystem_invalid_input.yaml")
+ errormsg = _('SubstitutionMappings with node_type '
+ 'example.QueuingSubsystem is missing '
+ 'required input definition of input "server_port".')
+
+ # It's invalid in nested template.
+ self.assertRaises(exception.ValidationError,
+ lambda: ToscaTemplate(tpl_path0))
+ exception.ExceptionCollector.assertExceptionMessage(
+ exception.MissingRequiredInputError, errormsg)
+
+ # Subtemplate deploy standaolone is also invalid.
+ self.assertRaises(exception.ValidationError,
+ lambda: ToscaTemplate(tpl_path1))
+ exception.ExceptionCollector.assertExceptionMessage(
+ exception.MissingRequiredInputError, errormsg)
def test_system_with_unknown_output_validation(self):
tpl_path0 = os.path.join(
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py
index 358bf28..2e97b0e 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py
@@ -60,7 +60,7 @@ class ToscaDefTest(TestCase):
def test_group(self):
self.assertEqual(group_type.type, "tosca.groups.Root")
- self.assertEqual(group_type.parent_type, None)
+ self.assertIsNone(group_type.parent_type)
self.assertIn(ifaces.LIFECYCLE_SHORTNAME, group_type.interfaces)
def test_capabilities(self):
@@ -71,6 +71,7 @@ class ToscaDefTest(TestCase):
# we SHOULD test symbolic capability names as well
self.assertEqual(
['tosca.capabilities.Container',
+ 'tosca.capabilities.Endpoint.Admin',
'tosca.capabilities.Node',
'tosca.capabilities.OperatingSystem',
'tosca.capabilities.Scalable',
@@ -184,12 +185,12 @@ class ToscaDefTest(TestCase):
relation, node in network_port_type.relationship.items()])
def test_interfaces(self):
- self.assertEqual(compute_type.interfaces, None)
+ self.assertIsNone(compute_type.interfaces)
root_node = NodeType('tosca.nodes.Root')
self.assertIn(ifaces.LIFECYCLE_SHORTNAME, root_node.interfaces)
def test_artifacts(self):
- self.assertEqual(artif_root_type.parent_type, None)
+ self.assertIsNone(artif_root_type.parent_type)
self.assertEqual('tosca.artifacts.Root',
artif_file_type.parent_type.type)
self.assertEqual({}, artif_file_type.parent_artifacts)
@@ -284,7 +285,7 @@ class ToscaDefTest(TestCase):
key=lambda x: str(x)))
def test_policies(self):
- self.assertEqual(policy_root_type.parent_type, None)
+ self.assertIsNone(policy_root_type.parent_type)
self.assertEqual('tosca.policies.Root',
policy_placement_type.parent_type.type)
self.assertEqual({}, policy_placement_type.parent_policies)
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
index e87b672..77232df 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py
@@ -30,13 +30,15 @@ class ToscaTemplateTest(TestCase):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_single_instance_wordpress.yaml")
- tosca = ToscaTemplate(tosca_tpl)
+ params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+ 'db_root_pwd': '12345678'}
+ tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
tosca_elk_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_elk.yaml")
tosca_repo_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/tosca_repositories_test_definition.yaml")
+ "data/repositories/tosca_repositories_test_definition.yaml")
def test_version(self):
self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0")
@@ -145,8 +147,6 @@ class ToscaTemplateTest(TestCase):
wordpress_node.is_derived_from("tosca.nodes.Root"))
self.assertFalse(
wordpress_node.is_derived_from("tosca.policies.Root"))
- self.assertFalse(
- wordpress_node.is_derived_from("tosca.groups.Root"))
def test_outputs(self):
self.assertEqual(
@@ -174,14 +174,14 @@ class ToscaTemplateTest(TestCase):
self.assertEqual(3, len(interface.inputs))
TestCase.skip(self, 'bug #1440247')
wp_db_port = interface.inputs['wp_db_port']
- self.assertTrue(isinstance(wp_db_port, GetProperty))
+ self.assertIsInstance(wp_db_port, GetProperty)
self.assertEqual('get_property', wp_db_port.name)
self.assertEqual(['SELF',
'database_endpoint',
'port'],
wp_db_port.args)
result = wp_db_port.result()
- self.assertTrue(isinstance(result, GetInput))
+ self.assertIsInstance(result, GetInput)
else:
raise AssertionError(
'Unexpected interface: {0}'.format(interface.name))
@@ -200,6 +200,7 @@ class ToscaTemplateTest(TestCase):
compute_type = NodeType(tpl.type)
self.assertEqual(
sorted(['tosca.capabilities.Container',
+ 'tosca.capabilities.Endpoint.Admin',
'tosca.capabilities.Node',
'tosca.capabilities.OperatingSystem',
'tosca.capabilities.network.Bindable',
@@ -286,7 +287,7 @@ class ToscaTemplateTest(TestCase):
"""
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/test_requirements.yaml")
+ "data/requirements/test_requirements.yaml")
tosca = ToscaTemplate(tosca_tpl)
for node_tpl in tosca.nodetemplates:
if node_tpl.name == 'my_app':
@@ -438,14 +439,17 @@ class ToscaTemplateTest(TestCase):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_single_instance_wordpress.yaml")
- tosca = ToscaTemplate(tosca_tpl)
+ params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+ 'db_root_pwd': '12345678'}
+ tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
self.assertTrue(tosca.topology_template.custom_defs)
def test_local_template_with_url_import(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_single_instance_wordpress_with_url_import.yaml")
- tosca = ToscaTemplate(tosca_tpl)
+ tosca = ToscaTemplate(tosca_tpl,
+ parsed_params={'db_root_pwd': '123456'})
self.assertTrue(tosca.topology_template.custom_defs)
def test_url_template_with_local_relpath_import(self):
@@ -576,6 +580,10 @@ class ToscaTemplateTest(TestCase):
exception.ExceptionCollector.assertExceptionMessage(
exception.MissingRequiredFieldError, err9_msg)
+ err10_msg = _('Type "tosca.nodes.XYZ" is not a valid type.')
+ exception.ExceptionCollector.assertExceptionMessage(
+ exception.InvalidTypeError, err10_msg)
+
def test_invalid_section_names(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
@@ -673,9 +681,10 @@ class ToscaTemplateTest(TestCase):
"data/tosca_single_instance_wordpress.yaml")
yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
-
+ params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+ 'db_root_pwd': '12345678'}
self.assertRaises(exception.ValidationError, ToscaTemplate, None,
- None, False, yaml_dict_tpl)
+ params, False, yaml_dict_tpl)
err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
'cannot be used in a pre-parsed input template.'))
exception.ExceptionCollector.assertExceptionMessage(ImportError,
@@ -747,7 +756,7 @@ class ToscaTemplateTest(TestCase):
def test_node_filter(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/test_node_filter.yaml")
+ "data/node_filter/test_node_filter.yaml")
ToscaTemplate(tosca_tpl)
def test_attributes_inheritance(self):
@@ -759,7 +768,7 @@ class ToscaTemplateTest(TestCase):
def test_repositories_definition(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/test_repositories_definition.yaml")
+ "data/repositories/test_repositories_definition.yaml")
ToscaTemplate(tosca_tpl)
def test_custom_caps_def(self):
@@ -819,5 +828,26 @@ class ToscaTemplateTest(TestCase):
def test_containers(self):
tosca_tpl = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
- "data/test_containers.yaml")
+ "data/containers/test_container_docker_mysql.yaml")
ToscaTemplate(tosca_tpl, parsed_params={"mysql_root_pwd": "12345678"})
+
+ def test_endpoint_on_compute(self):
+ tosca_tpl = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/test_endpoint_on_compute.yaml")
+ ToscaTemplate(tosca_tpl)
+
+ def test_nested_dsl_def(self):
+ tosca_tpl = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/dsl_definitions/test_nested_dsl_def.yaml")
+ self.assertIsNotNone(ToscaTemplate(tosca_tpl))
+
+ def test_multiple_policies(self):
+ tosca_tpl = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/policies/test_tosca_nfv_multiple_policies.yaml")
+ tosca = ToscaTemplate(tosca_tpl)
+ self.assertEqual(
+ ['ALRM1', 'SP1', 'SP2'],
+ sorted([policy.name for policy in tosca.policies]))
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
index 5a8f37a..911867f 100644
--- a/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
+++ b/tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py
@@ -35,8 +35,28 @@ class ToscaTemplateValidationTest(TestCase):
tpl_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"data/tosca_single_instance_wordpress.yaml")
+ params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+ 'db_root_pwd': '12345678'}
+ self.assertIsNotNone(ToscaTemplate(tpl_path, params))
+
+ def test_custom_interface_allowed(self):
+ tpl_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/interfaces/test_custom_interface_in_template.yaml")
self.assertIsNotNone(ToscaTemplate(tpl_path))
+ def test_custom_interface_invalid_operation(self):
+ tpl_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/interfaces/test_custom_interface_invalid_operation.yaml")
+ self.assertRaises(exception.ValidationError,
+ ToscaTemplate, tpl_path)
+ exception.ExceptionCollector.assertExceptionMessage(
+ exception.UnknownFieldError,
+ _('"interfaces" of template "customInterfaceTest" '
+ 'contains unknown field "CustomOp4". '
+ 'Refer to the definition to verify valid values.'))
+
def test_first_level_sections(self):
tpl_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
@@ -97,6 +117,117 @@ class ToscaTemplateValidationTest(TestCase):
_('Policy "mycompany.mytypes.myScalingPolicy" contains unknown '
'field "derived1_from". Refer to the definition to '
'verify valid values.'))
+ exception.ExceptionCollector.assertExceptionMessage(
+ exception.UnknownFieldError,
+ _('Relationshiptype "test.relation.connects" contains unknown '
+ 'field "derived_from4". Refer to the definition to '
+ 'verify valid values.'))
+
+ def test_getoperation_IncorrectValue(self):
+ # test case 1
+ tpl_snippet = '''
+ node_templates:
+ front_end:
+ type: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ create:
+ implementation: scripts/frontend/create.sh
+ configure:
+ implementation: scripts/frontend/configure.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end,Standard1,
+ create,data_dir]}
+ '''
+ tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+ err = self.assertRaises(ValueError,
+ TopologyTemplate, tpl, None)
+ expectedmessage = _('Enter a valid interface name')
+ self.assertEqual(expectedmessage, err.__str__())
+ # test case 2
+ tpl_snippet2 = '''
+ node_templates:
+ front_end:
+ type: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ create:
+ implementation: scripts/frontend/create.sh
+ configure:
+ implementation: scripts/frontend/configure.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end1,Standard,
+ create,data_dir]}
+ '''
+ tpl2 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet2))
+ err2 = self.assertRaises(KeyError,
+ TopologyTemplate, tpl2, None)
+ expectedmessage2 = _('\'Node template "front_end1" was not found.\'')
+ self.assertEqual(expectedmessage2, err2.__str__())
+ # test case 3
+ tpl_snippet3 = '''
+ node_templates:
+ front_end:
+ type: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ create:
+ implementation: scripts/frontend/create.sh
+ configure:
+ implementation: scripts/frontend/configure.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end,Standard,
+ get_target,data_dir]}
+ '''
+ tpl3 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet3))
+ err3 = self.assertRaises(ValueError,
+ TopologyTemplate, tpl3, None)
+ expectedmessage3 = _('Enter an operation of Standard interface')
+ self.assertEqual(expectedmessage3, err3.__str__())
+ # test case 4
+ tpl_snippet4 = '''
+ node_templates:
+ front_end:
+ type: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ create:
+ implementation: scripts/frontend/create.sh
+ configure:
+ implementation: scripts/frontend/configure.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end,Configure,
+ create,data_dir]}
+ '''
+ tpl4 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet4))
+ err4 = self.assertRaises(ValueError,
+ TopologyTemplate, tpl4, None)
+ expectedmessage4 = _('Enter an operation of Configure interface')
+ self.assertEqual(expectedmessage4, err4.__str__())
+ # test case 5
+ tpl_snippet5 = '''
+ node_templates:
+ front_end:
+ type: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ create:
+ implementation: scripts/frontend/create.sh
+ configure:
+ implementation: scripts/frontend/configure.sh
+ inputs:
+ data_dir: {get_operation_output: [front_end,Standard,
+ create]}
+ '''
+ tpl5 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet5))
+ err5 = self.assertRaises(ValueError,
+ TopologyTemplate, tpl5, None)
+ expectedmessage5 = _('Illegal arguments for function'
+ ' "get_operation_output".'
+ ' Expected arguments: "template_name",'
+ '"interface_name",'
+ '"operation_name","output_variable_name"')
+ self.assertEqual(expectedmessage5, err5.__str__())
def test_unsupported_type(self):
tpl_snippet = '''
@@ -135,6 +266,15 @@ class ToscaTemplateValidationTest(TestCase):
required: yes
status: supported
'''
+ tpl_snippet3 = '''
+ inputs:
+ some_list:
+ type: list
+ description: List of items
+ entry_schema:
+ type: string
+ default: []
+ '''
inputs1 = (toscaparser.utils.yamlparser.
simple_parse(tpl_snippet1)['inputs'])
name1, attrs1 = list(inputs1.items())[0]
@@ -144,14 +284,13 @@ class ToscaTemplateValidationTest(TestCase):
try:
Input(name1, attrs1)
except Exception as err:
- # err=self.assertRaises(exception.UnknownFieldError,
- # input1.validate)
self.assertEqual(_('Input "cpus" contains unknown field '
'"constraint". Refer to the definition to '
'verify valid values.'),
err.__str__())
input2 = Input(name2, attrs2)
self.assertTrue(input2.required)
+ toscaparser.utils.yamlparser.simple_parse(tpl_snippet3)['inputs']
def _imports_content_test(self, tpl_snippet, path, custom_type_def):
imports = (toscaparser.utils.yamlparser.
@@ -366,7 +505,7 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
try:
output.validate()
except Exception as err:
- self.assertTrue(isinstance(err, exception.UnknownFieldError))
+ self.assertIsInstance(err, exception.UnknownFieldError)
self.assertEqual(_('Output "server_address" contains unknown '
'field "descriptions". Refer to the definition '
'to verify valid values.'),
@@ -1456,7 +1595,7 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
requirement: host
capability: Container
condition:
- constraint: utilization greater_than 50%
+ constraint: { greater_than: 50 }
period: 60
evaluations: 1
method : average
@@ -1555,3 +1694,91 @@ heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
'unknown field "oss". Refer to the definition '
'to verify valid values.')
self.assertEqual(expectedmessage, err.__str__())
+
+ def test_qualified_name(self):
+ tpl_snippet_full_name = '''
+ node_templates:
+ supported_type:
+ type: tosca.nodes.Compute
+ '''
+ tpl = (
+ toscaparser.utils.yamlparser.simple_parse(
+ tpl_snippet_full_name))
+ TopologyTemplate(tpl, None)
+
+ tpl_snippet_short_name = '''
+ node_templates:
+ supported_type:
+ type: Compute
+ '''
+ tpl = (
+ toscaparser.utils.yamlparser.simple_parse(
+ tpl_snippet_short_name))
+ TopologyTemplate(tpl, None)
+
+ tpl_snippet_qualified_name = '''
+ node_templates:
+ supported_type:
+ type: tosca:Compute
+ '''
+ tpl = (
+ toscaparser.utils.yamlparser.simple_parse(
+ tpl_snippet_qualified_name))
+ TopologyTemplate(tpl, None)
+
+ def test_requirements_as_list(self):
+ """Node template with requirements provided with or without list
+
+ Node template requirements are required to be provided as list.
+ """
+
+ expectedmessage = _('"requirements" of template "my_webserver"'
+ ' must be of type "list".')
+
+ # requirements provided as dictionary
+ tpl_snippet1 = '''
+ node_templates:
+ my_webserver:
+ type: tosca.nodes.WebServer
+ requirements:
+ host: server
+ server:
+ type: tosca.nodes.Compute
+ '''
+ err1 = self.assertRaises(
+ exception.TypeMismatchError,
+ lambda: self._single_node_template_content_test(tpl_snippet1))
+ self.assertEqual(expectedmessage, err1.__str__())
+
+ # requirements provided as string
+ tpl_snippet2 = '''
+ node_templates:
+ my_webserver:
+ type: tosca.nodes.WebServer
+ requirements: server
+ server:
+ type: tosca.nodes.Compute
+ '''
+ err2 = self.assertRaises(
+ exception.TypeMismatchError,
+ lambda: self._single_node_template_content_test(tpl_snippet2))
+ self.assertEqual(expectedmessage, err2.__str__())
+
+ # requirements provided as list
+ tpl_snippet3 = '''
+ node_templates:
+ my_webserver:
+ type: tosca.nodes.WebServer
+ requirements:
+ - host: server
+ server:
+ type: tosca.nodes.Compute
+ '''
+ self.assertIsNone(
+ self._single_node_template_content_test(tpl_snippet3))
+
+ def test_properties_override_with_flavor_and_image(self):
+ tpl_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "data/test_normative_type_properties_override.yaml")
+ self.assertIsNotNone(ToscaTemplate(tpl_path))
diff --git a/tosca2heat/tosca-parser/toscaparser/topology_template.py b/tosca2heat/tosca-parser/toscaparser/topology_template.py
index d7fd443..4571fe7 100644
--- a/tosca2heat/tosca-parser/toscaparser/topology_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/topology_template.py
@@ -118,6 +118,7 @@ class TopologyTemplate(object):
def _substitution_mappings(self):
tpl_substitution_mapping = self._tpl_substitution_mappings()
+ # if tpl_substitution_mapping and self.sub_mapped_node_template:
if tpl_substitution_mapping:
return SubstitutionMappings(tpl_substitution_mapping,
self.nodetemplates,
@@ -131,17 +132,17 @@ class TopologyTemplate(object):
for policy in self._tpl_policies():
for policy_name, policy_tpl in policy.items():
target_list = policy_tpl.get('targets')
+ target_objects = []
+ targets_type = "groups"
if target_list and len(target_list) >= 1:
- target_objects = []
- targets_type = "groups"
target_objects = self._get_policy_groups(target_list)
if not target_objects:
targets_type = "node_templates"
target_objects = self._get_group_members(target_list)
- policyObj = Policy(policy_name, policy_tpl,
- target_objects, targets_type,
- self.custom_defs)
- policies.append(policyObj)
+ policyObj = Policy(policy_name, policy_tpl,
+ target_objects, targets_type,
+ self.custom_defs)
+ policies.append(policyObj)
return policies
def _groups(self):
@@ -152,7 +153,7 @@ class TopologyTemplate(object):
if member_names is not None:
DataEntity.validate_datatype('list', member_names)
if len(member_names) < 1 or \
- len(member_names) != len(set(member_names)):
+ len(member_names) != len(set(member_names)):
exception.ExceptionCollector.appendException(
exception.InvalidGroupTargetException(
message=_('Member nodes "%s" should be >= 1 '
@@ -196,16 +197,16 @@ class TopologyTemplate(object):
# topology template can act like node template
# it is exposed by substitution_mappings.
def nodetype(self):
- return (self.substitution_mappings.node_type
- if self.substitution_mappings else None)
+ return self.substitution_mappings.node_type \
+ if self.substitution_mappings else None
def capabilities(self):
- return (self.substitution_mappings.capabilities
- if self.substitution_mappings else None)
+ return self.substitution_mappings.capabilities \
+ if self.substitution_mappings else None
def requirements(self):
- return (self.substitution_mappings.requirements
- if self.substitution_mappings else None)
+ return self.substitution_mappings.requirements \
+ if self.substitution_mappings else None
def _tpl_description(self):
description = self.tpl.get(DESCRIPTION)
@@ -258,7 +259,8 @@ class TopologyTemplate(object):
self,
node_template,
value)
- if node_template.requirements:
+ if node_template.requirements and \
+ isinstance(node_template.requirements, list):
for req in node_template.requirements:
rel = req
for req_name, req_item in req.items():
@@ -291,7 +293,7 @@ class TopologyTemplate(object):
for interface in rel_tpl.interfaces:
if interface.inputs:
for name, value in \
- interface.inputs.items():
+ interface.inputs.items():
interface.inputs[name] = \
functions.get_function(self,
rel_tpl,
diff --git a/tosca2heat/tosca-parser/toscaparser/tosca_template.py b/tosca2heat/tosca-parser/toscaparser/tosca_template.py
index 84d953c..f48078f 100644
--- a/tosca2heat/tosca-parser/toscaparser/tosca_template.py
+++ b/tosca2heat/tosca-parser/toscaparser/tosca_template.py
@@ -36,14 +36,14 @@ SECTIONS = (DEFINITION_VERSION, DEFAULT_NAMESPACE, TEMPLATE_NAME,
TOPOLOGY_TEMPLATE, TEMPLATE_AUTHOR, TEMPLATE_VERSION,
DESCRIPTION, IMPORTS, DSL_DEFINITIONS, NODE_TYPES,
RELATIONSHIP_TYPES, RELATIONSHIP_TEMPLATES,
- CAPABILITY_TYPES, ARTIFACT_TYPES, DATA_TYPES,
+ CAPABILITY_TYPES, ARTIFACT_TYPES, DATA_TYPES, INTERFACE_TYPES,
POLICY_TYPES, GROUP_TYPES, REPOSITORIES) = \
('tosca_definitions_version', 'tosca_default_namespace',
'template_name', 'topology_template', 'template_author',
'template_version', 'description', 'imports', 'dsl_definitions',
'node_types', 'relationship_types', 'relationship_templates',
'capability_types', 'artifact_types', 'data_types',
- 'policy_types', 'group_types', 'repositories')
+ 'interface_types', 'policy_types', 'group_types', 'repositories')
# Sections that are specific to individual template definitions
SPECIAL_SECTIONS = (METADATA) = ('metadata')
@@ -106,6 +106,7 @@ class ToscaTemplate(object):
self.relationship_templates = self._relationship_templates()
self.nodetemplates = self._nodetemplates()
self.outputs = self._outputs()
+ self.policies = self._policies()
self._handle_nested_tosca_templates_with_topology()
self.graph = ToscaGraph(self.nodetemplates)
@@ -162,9 +163,12 @@ class ToscaTemplate(object):
def _tpl_topology_template(self):
return self.tpl.get(TOPOLOGY_TEMPLATE)
+ def _policies(self):
+ return self.topology_template.policies
+
def _get_all_custom_defs(self, imports=None):
types = [IMPORTS, NODE_TYPES, CAPABILITY_TYPES, RELATIONSHIP_TYPES,
- DATA_TYPES, POLICY_TYPES, GROUP_TYPES]
+ DATA_TYPES, INTERFACE_TYPES, POLICY_TYPES, GROUP_TYPES]
custom_defs_final = {}
custom_defs = self._get_custom_types(types, imports)
if custom_defs:
@@ -196,9 +200,9 @@ class ToscaTemplate(object):
imports = self._tpl_imports()
if imports:
- custom_service = \
- toscaparser.imports.ImportsLoader(imports, self.path,
- type_defs, self.tpl)
+ custom_service = toscaparser.imports.\
+ ImportsLoader(imports, self.path,
+ type_defs, self.tpl)
nested_tosca_tpls = custom_service.get_nested_tosca_tpls()
self._update_nested_tosca_tpls_with_topology(nested_tosca_tpls)
diff --git a/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py b/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py
index 0d2f1d6..a0c11f0 100644
--- a/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py
+++ b/tosca2heat/tosca-parser/toscaparser/unsupportedtype.py
@@ -20,6 +20,18 @@ log = logging.getLogger('tosca')
class UnsupportedType(object):
+ """Note: TOSCA spec version related
+
+ The tosca.nodes.Storage.ObjectStorage and tosca.nodes.Storage.BlockStorage
+ used here as un_supported_types are part of the name changes in TOSCA spec
+ version 1.1. The original name as specified in version 1.0 are,
+ tosca.nodes.BlockStorage and tosca.nodes.ObjectStorage which are supported
+ by the tosca-parser. Since there are little overlapping in version support
+ currently in the tosca-parser, the names tosca.nodes.Storage.ObjectStorage
+ and tosca.nodes.Storage.BlockStorage are used here to demonstrate the usage
+ of un_supported_types. As tosca-parser move to provide support for version
+ 1.1 and higher, they will be removed.
+ """
un_supported_types = ['tosca.test.invalidtype',
'tosca.nodes.Storage.ObjectStorage',
'tosca.nodes.Storage.BlockStorage']
diff --git a/tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py b/tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py
index f5562e2..d631ac8 100644
--- a/tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py
+++ b/tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py
@@ -19,4 +19,5 @@ _t = gettext.translation('tosca-parser', localedir=_localedir,
def _(msg):
+ # type: (object) -> object
return _t.gettext(msg)
diff --git a/tosca2heat/tosca-parser/toscaparser/utils/validateutils.py b/tosca2heat/tosca-parser/toscaparser/utils/validateutils.py
index 43e14d6..b280576 100644
--- a/tosca2heat/tosca-parser/toscaparser/utils/validateutils.py
+++ b/tosca2heat/tosca-parser/toscaparser/utils/validateutils.py
@@ -198,7 +198,7 @@ class TOSCAVersionProperty(object):
"""
if self.minor_version is None and self.build_version is None and \
- value != '0':
+ value != '0':
log.warning(_('Minor version assumed "0".'))
self.version = '.'.join([value, '0'])
return value