Update tosca lib to version 0.5 09/12009/2
authorshangxdy <shang.xiaodong@zte.com.cn>
Thu, 7 Apr 2016 18:08:49 +0000 (14:08 -0400)
committershangxdy <shang.xiaodong@zte.com.cn>
Thu, 7 Apr 2016 18:59:30 +0000 (14:59 -0400)
Use tosca-parser and heat-translator to analyze to the basic
nfv-tosca type definitions, and use simple tosca new feature
such as policy, group and trigger, which are now supported by
the latest version of tosca-parser and heat-translator.

JIRA:PARSER-18

Change-Id: I797bcacbb5b32005d0aeb0f3f32851ac96e30f01
Signed--off-by: shangxdy <shang.xiaodong@zte.com.cn>
Signed-off-by: shangxdy <shang.xiaodong@zte.com.cn>
499 files changed:
tosca2heat/README.md
tosca2heat/heat-translator-0.3.0/.coveragerc [deleted file]
tosca2heat/heat-translator-0.3.0/.mailmap [deleted file]
tosca2heat/heat-translator-0.3.0/.testr.conf [deleted file]
tosca2heat/heat-translator-0.3.0/AUTHORS [deleted file]
tosca2heat/heat-translator-0.3.0/ChangeLog [deleted file]
tosca2heat/heat-translator-0.3.0/PKG-INFO [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/PKG-INFO [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/SOURCES.txt [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/dependency_links.txt [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/entry_points.txt [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/not-zip-safe [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/pbr.json [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/requires.txt [deleted file]
tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/top_level.txt [deleted file]
tosca2heat/heat-translator-0.3.0/setup.cfg [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_collectd.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_elasticsearch.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_kibana.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_logstash.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_nodejs.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_paypalpizzastore.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_rsyslog.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_wordpress.py [deleted file]
tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_single_instance_wordpress.zip [deleted file]
tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wordpress_invalid_import_path.zip [deleted file]
tosca2heat/heat-translator/CONTRIBUTING.rst [moved from tosca2heat/heat-translator-0.3.0/CONTRIBUTING.rst with 100% similarity]
tosca2heat/heat-translator/HACKING.rst [moved from tosca2heat/heat-translator-0.3.0/HACKING.rst with 100% similarity]
tosca2heat/heat-translator/LICENSE [moved from tosca2heat/heat-translator-0.3.0/LICENSE with 100% similarity]
tosca2heat/heat-translator/MANIFEST.in [moved from tosca2heat/heat-translator-0.3.0/MANIFEST.in with 100% similarity]
tosca2heat/heat-translator/README.rst [moved from tosca2heat/heat-translator-0.3.0/README.rst with 100% similarity]
tosca2heat/heat-translator/babel.cfg [moved from tosca2heat/heat-translator-0.3.0/babel.cfg with 100% similarity]
tosca2heat/heat-translator/doc/source/conf.py [moved from tosca2heat/heat-translator-0.3.0/doc/source/conf.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/doc/source/contributing.rst [moved from tosca2heat/heat-translator-0.3.0/doc/source/contributing.rst with 100% similarity]
tosca2heat/heat-translator/doc/source/index.rst [moved from tosca2heat/heat-translator-0.3.0/doc/source/index.rst with 100% similarity]
tosca2heat/heat-translator/doc/source/installation.rst [moved from tosca2heat/heat-translator-0.3.0/doc/source/installation.rst with 100% similarity]
tosca2heat/heat-translator/doc/source/usage.rst [moved from tosca2heat/heat-translator-0.3.0/doc/source/usage.rst with 66% similarity]
tosca2heat/heat-translator/heat_translator.py [moved from tosca2heat/heat-translator-0.3.0/heat_translator.py with 100% similarity]
tosca2heat/heat-translator/heat_translator_logging.conf [moved from tosca2heat/heat-translator-0.3.0/heat_translator_logging.conf with 100% similarity]
tosca2heat/heat-translator/openstack-common.conf [moved from tosca2heat/heat-translator-0.3.0/openstack-common.conf with 100% similarity]
tosca2heat/heat-translator/requirements.txt [moved from tosca2heat/tosca-parser-0.3.0/requirements.txt with 53% similarity]
tosca2heat/heat-translator/setup.cfg [new file with mode: 0644]
tosca2heat/heat-translator/setup.py [moved from tosca2heat/heat-translator-0.3.0/setup.py with 100% similarity]
tosca2heat/heat-translator/test-requirements.txt [moved from tosca2heat/heat-translator-0.3.0/test-requirements.txt with 54% similarity]
tosca2heat/heat-translator/tox.ini [moved from tosca2heat/heat-translator-0.3.0/tox.ini with 96% similarity]
tosca2heat/heat-translator/translator/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/common/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/common/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/common/exception.py [moved from tosca2heat/heat-translator-0.3.0/translator/common/exception.py with 100% similarity]
tosca2heat/heat-translator/translator/common/utils.py [moved from tosca2heat/heat-translator-0.3.0/translator/common/utils.py with 84% similarity]
tosca2heat/heat-translator/translator/conf/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/conf/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/conf/config.py [moved from tosca2heat/heat-translator-0.3.0/translator/conf/config.py with 100% similarity]
tosca2heat/heat-translator/translator/conf/translator.conf [moved from tosca2heat/heat-translator-0.3.0/translator/conf/translator.conf with 100% similarity]
tosca2heat/heat-translator/translator/custom/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/custom/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/custom/hot/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/custom/hot/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/syntax/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/syntax/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/syntax/hot_output.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_output.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/syntax/hot_parameter.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_parameter.py with 91% similarity]
tosca2heat/heat-translator/translator/hot/syntax/hot_resource.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_resource.py with 77% similarity]
tosca2heat/heat-translator/translator/hot/syntax/hot_template.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_template.py with 94% similarity]
tosca2heat/heat-translator/translator/hot/tests/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tests/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tests/test_hot_parameter.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_hot_parameter.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tests/test_translate_inputs.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_inputs.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tests/test_translate_outputs.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_outputs.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tosca/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/__init__.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tests/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_blockstorage.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_blockstorage.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_compute.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_compute.py with 85% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_objectstore.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_objectstore.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_policies.py [new file with mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage.py with 93% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tosca_block_storage_attachment.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage_attachment.py with 100% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py with 70% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_database.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_database.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_dbms.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_dbms.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_network_network.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_network.py with 95% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tosca_network_port.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_port.py with 52% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tosca_object_storage.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_object_storage.py with 95% similarity]
tosca2heat/heat-translator/translator/hot/tosca/tosca_policies.py [new file with mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_software_component.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_software_component.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_web_application.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_web_application.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca/tosca_webserver.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_webserver.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/hot/tosca_translator.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/tosca_translator.py with 85% similarity]
tosca2heat/heat-translator/translator/hot/translate_inputs.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py with 86% similarity]
tosca2heat/heat-translator/translator/hot/translate_node_templates.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/translate_node_templates.py with 80% similarity]
tosca2heat/heat-translator/translator/hot/translate_outputs.py [moved from tosca2heat/heat-translator-0.3.0/translator/hot/translate_outputs.py with 90% similarity]
tosca2heat/heat-translator/translator/osc/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/osc/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/osc/osc_plugin.py [moved from tosca2heat/heat-translator-0.3.0/translator/osc/osc_plugin.py with 100% similarity]
tosca2heat/heat-translator/translator/osc/utils.py [moved from tosca2heat/heat-translator-0.3.0/translator/osc/utils.py with 100% similarity]
tosca2heat/heat-translator/translator/osc/v1/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/osc/v1/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/osc/v1/tests/__init__.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/osc/v1/tests/fakes.py [new file with mode: 0644]
tosca2heat/heat-translator/translator/osc/v1/tests/test_translate.py [new file with mode: 0644]
tosca2heat/heat-translator/translator/osc/v1/tests/utils.py [new file with mode: 0644]
tosca2heat/heat-translator/translator/osc/v1/translate.py [moved from tosca2heat/heat-translator-0.3.0/translator/osc/v1/translate.py with 84% similarity]
tosca2heat/heat-translator/translator/shell.py [moved from tosca2heat/heat-translator-0.3.0/translator/shell.py with 58% similarity]
tosca2heat/heat-translator/translator/tests/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/common/__init__.py with 100% similarity]
tosca2heat/heat-translator/translator/tests/base.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/base.py with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/collectd/config.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/collectd/config.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/collectd/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/collectd/create.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/collectd/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/collectd/start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/elasticsearch/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/elasticsearch/create.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/elasticsearch/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/elasticsearch/start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/kibana/config.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/kibana/config.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/kibana/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/kibana/create.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/kibana/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/kibana/start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/logstash/configure_collectd.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/logstash/configure_collectd.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/logstash/configure_elasticsearch.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/logstash/configure_elasticsearch.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/logstash/configure_rsyslog.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/logstash/configure_rsyslog.py with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/logstash/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/logstash/create.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/logstash/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/logstash/start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/mongodb/config.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mongodb/config.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/mongodb/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mongodb/create.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/mongodb/create_database.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mongodb/create_database.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/mongodb/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mongodb/start.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/mysql/mysql_database_configure.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mysql/mysql_database_configure.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/mysql/mysql_dbms_configure.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mysql/mysql_dbms_configure.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/mysql/mysql_dbms_install.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mysql/mysql_dbms_install.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/mysql/mysql_dbms_start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/mysql/mysql_dbms_start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/nodejs/config.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/nodejs/config.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/nodejs/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/nodejs/create.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/nodejs/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/nodejs/start.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/rsyslog/config.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/rsyslog/config.sh with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/artifacts/rsyslog/create.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/rsyslog/create.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/rsyslog/start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/rsyslog/start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/webserver/webserver_install.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/webserver/webserver_install.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/webserver/webserver_start.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/webserver/webserver_start.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/wordpress/wordpress_configure.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/wordpress/wordpress_configure.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/artifacts/wordpress/wordpress_install.sh [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/artifacts/wordpress/wordpress_install.sh with 100% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/data/csar_elk.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_elk.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/csar_hello_world.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_hello_world.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/csar_metadata_not_yaml.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_metadata_not_yaml.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/csar_not_zip.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_not_zip.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/csar_single_instance_wordpress.zip [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/csar_wordpress_invalid_import_path.zip [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/csar_wordpress_invalid_script_url.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wordpress_invalid_script_url.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/csar_wrong_metadata_file.zip [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wrong_metadata_file.zip with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/collectd.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/collectd.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/elasticsearch.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/elasticsearch.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/kibana.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/kibana.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/logstash.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/logstash.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/rsyslog.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/rsyslog.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/custom_types/wordpress.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/custom_types/wordpress.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_artifact.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_override.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_param_override.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_elk.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_elk.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_elk_from_csar.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_elk_from_csar.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image_params.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_hello_world.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_hello_world.yaml with 89% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_hello_world_userkey.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_host_assignment.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_host_assignment.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_nfv_sample.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_nodejs_mongodb_two_instances.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_nodejs_mongodb_two_instances.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_policies.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_instance_wordpress.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_instance_wordpress.yaml with 91% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_instance_wordpress_from_csar.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_instance_wordpress_from_csar.yaml with 91% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_object_store.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_object_store.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_server.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server_with_defaults_with_input.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_server_with_defaults_with_input.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server_with_defaults_without_input.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_single_server_with_defaults_without_input.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server_without_tosca_os_version.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_software_component.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_software_component.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/hot_web_application.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/hot_web_application.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_custom_network_nodes.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_one_server_one_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/network/hot_one_server_one_network.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_one_server_three_networks.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/network/hot_one_server_three_networks.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_server_on_existing_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/network/hot_server_on_existing_network.yaml with 95% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_two_servers_one_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/network/hot_two_servers_one_network.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt1.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt1.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt2.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt2.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt1.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt1.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt2.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt2.yaml with 97% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_custom_relationship_type.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_custom_relationship_type.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_blockstorage_with_relationship_template.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_blockstorage_with_relationship_template.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt1.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt1.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt2.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt2.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_defs.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_imports.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_inline.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/network/tosca_one_server_one_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/network/tosca_one_server_one_network.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/network/tosca_one_server_three_networks.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/network/tosca_one_server_three_networks.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/network/tosca_server_on_existing_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/network/tosca_server_on_existing_network.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/network/tosca_two_servers_one_network.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/network/tosca_two_servers_one_network.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_blockstorage_with_attachment.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_blockstorage_with_attachment.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_blockstorage_with_attachment_notation1.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_blockstorage_with_attachment_notation1.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_blockstorage_with_attachment_notation2.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_blockstorage_with_attachment_notation2.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_blockstorage_with_custom_relationship_type.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_blockstorage_with_custom_relationship_type.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_blockstorage_with_relationship_template.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_blockstorage_with_relationship_template.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_multiple_blockstorage_with_attachment.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_multiple_blockstorage_with_attachment.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/storage/tosca_single_object_store.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/storage/tosca_single_object_store.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/test_host_assignment.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/test_host_assignment.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/test_single_server_without_optional_version_prop.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/test_tosca_artifact.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type_with_override.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/test_tosca_flavor_and_image.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/test_tosca_nfv_sample.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/tosca_elk.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_elk.yaml with 98% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_helloworld.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_helloworld.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_helloworld_invalid.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_helloworld_invalid.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_nodejs_mongodb_two_instances.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_nodejs_mongodb_two_instances.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_policies.yaml [new file with mode: 0644]
tosca2heat/heat-translator/translator/tests/data/tosca_single_instance_wordpress.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_single_instance_wordpress.yaml with 84% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml with 90% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml with 84% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_single_server.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml with 93% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_single_server_with_defaults.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_single_server_with_defaults.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_software_component.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_software_component.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/data/tosca_web_application.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_web_application.yaml with 100% similarity]
tosca2heat/heat-translator/translator/tests/test_conf.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/test_conf.py with 100% similarity]
tosca2heat/heat-translator/translator/tests/test_shell.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/test_shell.py with 61% similarity]
tosca2heat/heat-translator/translator/tests/test_template.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/test_template.py with 93% similarity, mode: 0644]
tosca2heat/heat-translator/translator/tests/test_tosca_hot_translation.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/test_tosca_hot_translation.py with 78% similarity]
tosca2heat/heat-translator/translator/tests/test_utils.py [moved from tosca2heat/heat-translator-0.3.0/translator/tests/test_utils.py with 96% similarity]
tosca2heat/tosca-parser-0.3.0/.coveragerc [deleted file]
tosca2heat/tosca-parser-0.3.0/.mailmap [deleted file]
tosca2heat/tosca-parser-0.3.0/.testr.conf [deleted file]
tosca2heat/tosca-parser-0.3.0/AUTHORS [deleted file]
tosca2heat/tosca-parser-0.3.0/ChangeLog [deleted file]
tosca2heat/tosca-parser-0.3.0/PKG-INFO [deleted file]
tosca2heat/tosca-parser-0.3.0/test-requirements.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/PKG-INFO [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/SOURCES.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/dependency_links.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/entry_points.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/not-zip-safe [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/pbr.json [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/requires.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/top_level.txt [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/elements/policytype.py [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/elements/property_definition.py [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/groups.py [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error1.yaml [deleted file]
tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error2.yaml [deleted file]
tosca2heat/tosca-parser/CONTRIBUTING.rst [moved from tosca2heat/tosca-parser-0.3.0/CONTRIBUTING.rst with 100% similarity]
tosca2heat/tosca-parser/HACKING.rst [moved from tosca2heat/tosca-parser-0.3.0/HACKING.rst with 100% similarity]
tosca2heat/tosca-parser/LICENSE [moved from tosca2heat/tosca-parser-0.3.0/LICENSE with 100% similarity]
tosca2heat/tosca-parser/MANIFEST.in [moved from tosca2heat/tosca-parser-0.3.0/MANIFEST.in with 100% similarity]
tosca2heat/tosca-parser/README.rst [moved from tosca2heat/tosca-parser-0.3.0/README.rst with 63% similarity]
tosca2heat/tosca-parser/babel.cfg [moved from tosca2heat/tosca-parser-0.3.0/babel.cfg with 100% similarity]
tosca2heat/tosca-parser/doc/source/conf.py [moved from tosca2heat/tosca-parser-0.3.0/doc/source/conf.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/doc/source/contributing.rst [moved from tosca2heat/tosca-parser-0.3.0/doc/source/contributing.rst with 100% similarity]
tosca2heat/tosca-parser/doc/source/index.rst [moved from tosca2heat/tosca-parser-0.3.0/doc/source/index.rst with 51% similarity]
tosca2heat/tosca-parser/doc/source/installation.rst [moved from tosca2heat/tosca-parser-0.3.0/doc/source/installation.rst with 100% similarity]
tosca2heat/tosca-parser/doc/source/usage.rst [moved from tosca2heat/tosca-parser-0.3.0/doc/source/usage.rst with 100% similarity]
tosca2heat/tosca-parser/openstack-common.conf [moved from tosca2heat/tosca-parser-0.3.0/openstack-common.conf with 100% similarity]
tosca2heat/tosca-parser/requirements.txt [moved from tosca2heat/heat-translator-0.3.0/requirements.txt with 58% similarity]
tosca2heat/tosca-parser/setup.cfg [moved from tosca2heat/tosca-parser-0.3.0/setup.cfg with 53% similarity]
tosca2heat/tosca-parser/setup.py [moved from tosca2heat/tosca-parser-0.3.0/setup.py with 96% similarity]
tosca2heat/tosca-parser/test-requirements.txt [new file with mode: 0644]
tosca2heat/tosca-parser/tosca_parser.py [moved from tosca2heat/tosca-parser-0.3.0/tosca_parser.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/__init__.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/capabilities.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/capabilities.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/common/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/__init__.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/common/exception.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/common/exception.py with 82% similarity]
tosca2heat/tosca-parser/toscaparser/dataentity.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/dataentity.py with 95% similarity]
tosca2heat/tosca-parser/toscaparser/elements/TOSCA_definition_1_0.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/TOSCA_definition_1_0.yaml with 81% similarity]
tosca2heat/tosca-parser/toscaparser/elements/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/prereq/__init__.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/artifacttype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/artifacttype.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/attribute_definition.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/attribute_definition.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/capabilitytype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/capabilitytype.py with 88% similarity]
tosca2heat/tosca-parser/toscaparser/elements/constraints.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/constraints.py with 94% similarity]
tosca2heat/tosca-parser/toscaparser/elements/datatype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/datatype.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/entity_type.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/entity_type.py with 66% similarity]
tosca2heat/tosca-parser/toscaparser/elements/grouptype.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/elements/interfaces.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/interfaces.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/nodetype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/nodetype.py with 83% similarity]
tosca2heat/tosca-parser/toscaparser/elements/policytype.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/elements/property_definition.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/elements/relationshiptype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/relationshiptype.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/scalarunit.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/scalarunit.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/elements/statefulentitytype.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/elements/statefulentitytype.py with 89% similarity]
tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/entity_template.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/entity_template.py with 80% similarity]
tosca2heat/tosca-parser/toscaparser/extensions/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/__init__.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/extensions/exttools.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/__init__.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/utils/__init__.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/__init__.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/tosca_helloworld_nfv.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_nfv_tpl.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/functions.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/functions.py with 61% similarity]
tosca2heat/tosca-parser/toscaparser/groups.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/imports.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/imports.py with 57% similarity]
tosca2heat/tosca-parser/toscaparser/nodetemplate.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/nodetemplate.py with 87% similarity]
tosca2heat/tosca-parser/toscaparser/parameters.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/parameters.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/policy.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/prereq/__init__.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/prereq/csar.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/prereq/csar.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/properties.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/properties.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/relationship_template.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/relationship_template.py with 89% similarity]
tosca2heat/tosca-parser/toscaparser/shell.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/shell.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/__init__.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/collectd/config.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/collectd/config.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/collectd/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/collectd/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/collectd/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/collectd/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/elasticsearch/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/elasticsearch/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/elasticsearch/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/elasticsearch/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/kibana/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/kibana/config.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/kibana/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/kibana/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/kibana/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/kibana/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/logstash/configure_collectd.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/logstash/configure_collectd.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/logstash/configure_elasticsearch.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/logstash/configure_elasticsearch.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/logstash/configure_rsyslog.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/logstash/configure_rsyslog.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/logstash/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/logstash/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/logstash/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/logstash/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mongodb/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mongodb/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mongodb/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mongodb/create.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mongodb/create_database.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mongodb/create_database.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mongodb/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mongodb/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mysql/mysql_database_configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mysql/mysql_database_configure.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/nodejs/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/nodejs/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/nodejs/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/nodejs/create.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/nodejs/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/nodejs/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/rsyslog/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/rsyslog/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/rsyslog/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/rsyslog/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/rsyslog/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/rsyslog/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/webserver/webserver_install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/webserver/webserver_install.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/webserver/webserver_start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/webserver/webserver_start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/wordpress/wordpress_configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/wordpress/wordpress_configure.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/artifacts/wordpress/wordpress_install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/artifacts/wordpress/wordpress_install.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/base.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/base.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.csar [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_elk.csar with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_elk.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_elk.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_hello_world.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_hello_world.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_missing_metadata.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_missing_metadata.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_no_metadata_file.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_no_metadata_file.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_not_zip.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_not_zip.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml with 97% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/README.txt [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/README.txt with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh with 100% similarity, mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/collectd.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/collectd.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_prop.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_caps_def.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/db_with_list_param.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/elasticsearch.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/elasticsearch.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/imported_sample.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/kibana.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/kibana.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/logstash.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/logstash.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/nested_rsyslog.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/nested_rsyslog.yaml with 91% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/nested_test_wordpress.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/nested_test_wordpress.yaml with 61% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/node_with_cap.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml with 97% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/rsyslog.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/rsyslog.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/wordpress.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/custom_types/wordpress.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/datatypes/custom_datatype_def.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/datatypes/custom_datatype_def.yaml with 88% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml with 89% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat_invalid.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_with_host.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_invalid_function_signature.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_invalid_function_signature.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_unknown_capability_property.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_unknown_capability_property.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_unknown_input_in_property.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/functions/test_unknown_input_in_property.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/groups/definitions.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/groups/tosca_group_template.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/policies/custom_definitions.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/policies/tosca_policy_template.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_attributes_inheritance.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_available_rel_tpls.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_caps_def.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_relationships.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_instance_nested_imports.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_instance_nested_imports.yaml with 90% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_invalid_section_names.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_invalid_section_names.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_invalid_template_version.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_invalid_template_version.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_multiple_validation_errors.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_multiple_validation_errors.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_no_inputs_in_template.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_no_inputs_in_template.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_no_outputs_in_template.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_no_outputs_in_template.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_node_filter.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_repositories_definition.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_requirements.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_requirements.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_custom_rel_with_script.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error1.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error2.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/definitions.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/topology_template/definitions.yaml with 99% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/subsystem.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/topology_template/subsystem.yaml with 97% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/topology_template/system.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/topology_template/system.yaml with 76% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_elk.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/tosca_elk.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_helloworld.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/tosca_helloworld.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_load_balancer.yaml [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/tosca_single_instance_wordpress.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml [moved from tosca2heat/heat-translator-0.3.0/translator/tests/data/tosca_single_server.yaml with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_constraints.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_constraints.py with 96% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/tests/test_datatypes.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_datatypes.py with 80% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_exception.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_exception.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_functions.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_functions.py with 61% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_prereq.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_prereq.py with 98% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_properties.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_properties.py with 67% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_scalarunit.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_scalarunit.py with 99% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_shell.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_shell.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_topology_template.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_topology_template.py with 97% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_toscadef.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_toscadef.py with 86% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_toscatpl.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_toscatpl.py with 73% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_toscatplvalidation.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_toscatplvalidation.py with 77% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_utils.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_utils.py with 78% similarity]
tosca2heat/tosca-parser/toscaparser/tests/test_validate_tosca_version.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tests/test_validate_tosca_version.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/topology_template.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/topology_template.py with 74% similarity]
tosca2heat/tosca-parser/toscaparser/tosca_template.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tosca_template.py with 72% similarity]
tosca2heat/tosca-parser/toscaparser/tpl_relationship_graph.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/tpl_relationship_graph.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/triggers.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/utils/__init__.py [new file with mode: 0644]
tosca2heat/tosca-parser/toscaparser/utils/gettextutils.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/utils/gettextutils.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/utils/urlutils.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/utils/urlutils.py with 100% similarity]
tosca2heat/tosca-parser/toscaparser/utils/validateutils.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/utils/validateutils.py with 84% similarity]
tosca2heat/tosca-parser/toscaparser/utils/yamlparser.py [moved from tosca2heat/tosca-parser-0.3.0/toscaparser/utils/yamlparser.py with 93% similarity]
tosca2heat/tosca-parser/tox.ini [moved from tosca2heat/tosca-parser-0.3.0/tox.ini with 96% similarity]

index 024f021..d2f36a7 100644 (file)
@@ -1 +1,4 @@
 ##TOSCA To HOT Translation##
+Basic version information:
+1. tosca-paser is based the version of 0.5 in openstack community
+2. heat-translator is based the version of 0.5 in openstack community
diff --git a/tosca2heat/heat-translator-0.3.0/.coveragerc b/tosca2heat/heat-translator-0.3.0/.coveragerc
deleted file mode 100644 (file)
index 6c9ae08..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[run]
-branch = True
-source = translator
-omit = translator/openstack/*
-
-[report]
-ignore_errors = True
diff --git a/tosca2heat/heat-translator-0.3.0/.mailmap b/tosca2heat/heat-translator-0.3.0/.mailmap
deleted file mode 100644 (file)
index cc92f17..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Format is:
-# <preferred e-mail> <other e-mail 1>
-# <preferred e-mail> <other e-mail 2>
\ No newline at end of file
diff --git a/tosca2heat/heat-translator-0.3.0/.testr.conf b/tosca2heat/heat-translator-0.3.0/.testr.conf
deleted file mode 100644 (file)
index fb62267..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
-             OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
-             OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
-             ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
\ No newline at end of file
diff --git a/tosca2heat/heat-translator-0.3.0/AUTHORS b/tosca2heat/heat-translator-0.3.0/AUTHORS
deleted file mode 100644 (file)
index 7a4b006..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-Andrew F. Ly <afly@us.ibm.com>
-Atsushi SAKAI <sakaia@jp.fujitsu.com>
-Ben Martin <blmartin@us.ibm.com>
-Bharath Thiruveedula <bharath_ves@hotmail.com>
-Bill Huber <wbhuber@us.ibm.com>
-Brad Topol <btopol@us.ibm.com>
-Christian Berendt <berendt@b1-systems.de>
-Dharmesh Bhakta <bhakta@us.ibm.com>
-Dimitri Mazmanov <dimitri.mazmanov@ericsson.com>
-FeihuJiang <jiangfeihu@huawei.com>
-Haiyang DING <dinghaiyang@huawei.com>
-Idan Moyal <idan@gigaspaces.com>
-Jeff Feng <jianhua@us.ibm.com>
-Jeremy Stanley <fungi@yuggoth.org>
-Julio Ruano <jeruano@us.ibm.com>
-Kanagaraj Manickam <kanagaraj.manickam@hp.com>
-Longgeek <longgeek@thstack.com>
-Madhurya <madhurya.jesu@tcs.com>
-Matt Rutkowski <mrutkows@us.ibm.com>
-Meena <meena.ventrapati@tcs.com>
-Michael Brewer <mjbrewer@us.ibm.com>
-Michael Sambol <sambol@us.ibm.com>
-Monty Taylor <mordred@inaugust.com>
-Oleksii Chuprykov <ochuprykov@mirantis.com>
-Rohan Shah <ryshah@us.ibm.com>
-Sahdev Zala <spzala@us.ibm.com>
-Serg Melikyan <smelikyan@mirantis.com>
-Sergey Lukjanov <slukjanov@mirantis.com>
-Simeon Monov <sdmonov@us.ibm.com>
-Sirushti Murugesan <sirushti.murugesan@hp.com>
-Steve Martinelli <stevemar@ca.ibm.com>
-Ton Ngo <ton@us.ibm.com>
-Vahid Hashemian <vahidhashemian@us.ibm.com>
-Victor HU <huruifeng@huawei.com>
-Yaoguo Jiang <jiangyaoguo@huawei.com>
-Zach Sais <zsais@us.ibm.com>
-Zachary Sais <zsais@us.ibm.com>
-ddaskal <ddaskal@us.ibm.com>
-huruifeng <huruifeng@huawei.com>
-jiangyaoguo <jiangyaoguo@gmail.com>
-narengan <narengan@us.ibm.com>
-spzala <spzala@us.ibm.com>
-srinivas_tadepalli <srinivas.tadepalli@tcs.com>
-tonanhngo <ton@us.ibm.com>
diff --git a/tosca2heat/heat-translator-0.3.0/ChangeLog b/tosca2heat/heat-translator-0.3.0/ChangeLog
deleted file mode 100644 (file)
index 555b752..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-CHANGES
-=======
-
-0.3.0
------
-
-* Provide an option to store translated output in a file
-* Update usage documentation
-* Add capability to only validate template in OSC plug-in
-* Provide option to only validate template
-* Add support to fetch flavor details from nova
-* Updated from global requirements
-* Create initial test coverage
-* Fix broken unittests due to tosca-parser 0.3.0 release
-* Updated from global requirements
-* Updated from global requirements
-* Correc the usage example
-* Update README
-* Added checking for invalid or malformed command line parameters
-* Refactor dynamic types mapping feature to use importlib
-
-0.2.0
------
-
-* Fix a bug in OSC related to URL handling
-* Do not use logging conf on shell
-* Update documentation to cover new features
-* Handle URLs and import parameters in OSC
-* Fix custom import issues when using shell environments
-* Create command line entry point
-* Update temporary URLs to github URLs
-* Add translation of CSAR archives
-* Handle URLs for input templates and imports
-* Update README
-* Fix translation issue with interface inputs and functions
-* Update trove classifier
-* Allow for dynamic class loading of target types
-* Change ignore-errors to ignore_errors
-* Updated from global requirements
-* Update doc references
-* Move tosca library test data under translator tests
-* Updated from global requirements
-* Enable Translator with new TOSCA library (6)
-* Supporting logging in heat-translator with config file
-* Remove CSAR files from translator
-* Enable Translator with new TOSCA library (5)
-* Enable Translator with new TOSCA library (4)
-* Enable Translator with new TOSCA library (3)
-* Enable Translator with new TOSCA library (2)
-* Enable Translator with new TOSCA library (1)
-* Add TOSCA parser as new requirement
-
-0.1.0
------
-
-* MemoryUnit Incorrectly normalizes to uppercase
-* Implement SoftwareComponent and WebApplication normative types
-* Validation of TOSCA version
-* scalar-unit data type support as template input parameters
-* Corrected checking required properties of OS capabilities in UT
-* Validation for TOSCA second to below levels in template
-* Fix two typos on heat-translator documentation
-* Modified to get closest flavor based on minimal/no inputs
-* Set property to be required by default
-* Update TOSCA artifacts type
-* Separate implementation of custom types and base types
-* supporting short versions of requirements
-* Add full support for PortDef data type
-* Update network examples to the spec (1)
-* Update TOSCA wordpress custom definition
-* Update the 4th and 5th block storage examples (1)
-* Add missing storage examples from the spec
-* Update the 6th block storage example from the spec (1)
-* Remove the circular dependency in network examples
-* Update the first block storage example to the spec (1)
-* Update object store definition and example
-* Sync single server example with latest spec
-* Sync network examples with the spec
-* Remove py26 env
-* Fix translation of block storage
-* Updated from global requirements
-* Add a unit test for nodejs-mongodb template translation
-* Update TOSCA version per spec
-* Prepare ELK TOSCA Template for Translation into HOT (6)
-* Add app in the nodejs mongodb template
-* Update TOSCA credential datatype
-* Update TOSCA relationship inheritance
-* Update TOSCA translator installation doc
-* Update TOSCA relationship valid targets
-* Document usage of translator with OSC
-* Added directory structure in README.rst
-* Add a unit test for ELK translation
-* Annotate TOSCA scripts
-* Prepare ELK TOSCA Template for Translation into HOT (5)
-* Updated from global requirements
-* Implement tosca.scalar-unit
-* Update TOSCA base type definition file with version
-* Prepare ELK TOSCA Template for Translation into HOT (4)
-* Added translation to the tosca network module
-* Added translation in dataentity module
-* Fix typos in ELK CSAR readme file
-* Updated from global requirements
-* Adding unit test coverage for the validate method
-* Implement artifact type definition
-* Add support for parameters to translate template
-* Added the missing testcases for Tosca translator
-* Add handler for ConnectsTo relationship
-* Prepare ELK TOSCA Template for Translation into HOT (3)
-* Update TOSCA ELK scripts
-* Adding an empty template test for simple_parse()
-* Add unit testcases for toscalib_elements_constraints.py
-* Fixed spelling mistake
-* Fixing an error message which was not translated
-* Add the ability to set output file
-* Create an OSC plugin for heat-translator
-* Resolve interfaces by symbolic name not by type
-* TOSCA: Database and DBMS node properties update
-* TOSCA: fix indentation in elk CSAR
-* TOSCA: create csar for monitoring use case
-* Installer scripts should not run simultaneously on the same server
-* Prepare ELK TOSCA Template for Translation into HOT (2)
-* TOSCA: Update memory size per spec changes
-* Adding test coverage for HotParameter
-* Fix host server assignment for resources with multi-node dependency
-* Heat-Translator: Update README with new IRC Channel
-* Added a unit test to cover diff_dicts in utils.py
-* Fix installation package name
-* Prepare ELK TOSCA Template for Translation into HOT
-* TOSCA: interfaces for relationship templates
-* TOSCA: fix Python34 UnicodeDecodeError
-* Pick up new plugins for ELK
-* Heat translator plugins for new TOSCA custom types
-* TOSCA: keep the license formatting consistent
-* TOSCA: Create a test CLI program
-* Fix typos in tosca_elk.yaml file
-* TOSCA: use the artifacts directory for scripts
-* TOSCA: Correct duplicate Block Storage description
-* Implement tosca.capabilities.Container
-* TOSCA: minor updates in TOSCA def file per spec
-* TOSCA: rename sample template file
-* Create a unit test for wordpress specification in TOSCA
-* Update the TOSCA monitoring use case
-* Update TOSCA requirements for template and type
-* Apply topology_template to tosca_template
-* Inital Implementation of topology template
-* Add test templates for topology template
-* Update code base to be hacking compatible
-* Update requirements and test-requirements
-* Update README.rst to point to correct urls
-* Update heat-translator's documentation theme
-* Added unit test to verify num vals in str_to_num
-* Implementation of tosca.node.ObjectStorage
-* Implementation of CompareUtils class
-* Added a unit test for convert_unit_size_to_num
-* Added unit test to cover ValueError in str_to_num
-* Update definition of tosca.nodes.WebServer
-* TOSCA: organize test templates
-* Fixes few nits in the network features code
-* Create dictionary returning methods for certain class properties
-* The output template is close to HOT template
-* Rename TOSCA AttachTo relationship
-* Fix coverage so that it works for this repo
-* TOSCA: Handle memory units
-* TOSCA: Create new utils module with memory units
-* Add TOSCA networking features
-* TOSCA: Update README source code link
-* Follow the hosting chain to find the host server
-* Add scripts for logstash, elasticsearch, kibana
-* Add scripts to set up monitoring
-* Update set of scripts for mongodb and nodejs
-* tosca data type validation for float and timestamp
-* TOSCA: Handle custom capability type definition
-* Return input default value on get_input evaluation
-* Replace ip_address attribute with public_address and private_address
-* checking input parameter not None before accessing
-* TOSCA: Add missing artifacts references
-* Change name-value pairs to name-object pairs in the dictoinary
-* validating reference properties in translate_input.py
-* Add support for properties_def as a dictionary
-* added _validate_capabilities_properties function & UT
-* Adding tosca.capabilities.Scalable in TOSCA_definitions.yaml
-* Apply TOSCA OS capability to compute node
-* TOSCA: consider nodejs as web server only
-* TOSCA: remove misleading key Entry-Definitions
-* Use TOSCA properties from capabilities definition
-* Remove Stackforge from README
-* New custom type, unit test and template for use case
-* Add TOSCA networking definiton
-* Update TOSCA interfaces naming
-* Separate TOSCA capabilities definition from assignment
-* Remove unused TOSCA type variables
-* TOSCA: Do not import individual exception classes
-* Add missing TOSCA type keywords
-* Update TOSCA compute requirement
-* Validate TOSCA template version
-* Update TOSCA version
-* Add scalar unit type
-* Handle TOSCA relationship with 'type' keyword
-* Handle custom datatypes in current template
-* Change definition for tosca.capabilities.Endpoint
-* Remove Tosca.capabilities.feature per specs changes
-* add blockstorage attachment notation
-* Remove redundant TOSCA nodejs requirement
-* Change TOSCA interfaces keyword 'input' to 'inputs'
-* Add TOSCA service template for monitoring
-* Minor tweaks
-* Main translation code to handle parameters
-* Add new support for get_attribute
-* Add support for datatypes
-* Rename TOSCA node property relationship to relationships
-* Add a debug env for tox
-* Sort TOSCA relation output for a match to expected test result
-* Create relationship between TOSCA nodes per updated specs
-* Fix .gitreview after rename/transfer
-* Fix errors in templates and base types
-* Workflow documentation is now in infra-manual
-* get_attribute HOST keyword
-* Handle get_attribute in Tosca outputs
-* Add support for list and map types
-* Check for tosca keyword in the TOSCA type
-* Create a TOSCA CSAR for Wordpress template
-* Represent memory unit in string
-* Remove extraneous vim editor configuration comments
-* Provide implementation to parse monitoring template in TOSCA library
-* Allow Tosca templates with no inputs/outputs
-* Extended intrinsic functions support
-* Remove README.md as duplicate for .rst one
-* Work toward Python 3.4 support and testing
-* Add missing TOSCA template keynames
-* Update README and other doc files
-* Clean up heat-translator documentation
-* Revert use of olsosphinx library
-* add docs job to tox.ini
-* Check tosca node requirements
-* Add Schema parent class for Property, Input, Output
-* Implement TOSCA Block Storage
-* Allow use of TOSCA types by short name in the TOSCA template
-* Add type attributes
-* Enhance the validation of tosca
-* Enhanced tosca validation
-* Added a module for intrinsic function
-* Support importing TOSCA custom node types
-* Update the Babel module version
-* TOSCA generator top level code
-* TOSCA generator translation for individual TOSCA type
-* TOSCA generator template syntax
-* Remove tosca node template inheritance from node type
-* Add missing parameter for the tosca property
-* TOSCA parser
-* TOSCA definition types for TOSCA library
-* Add .gitreview file and apply cookiecutter template
-* Delete testattrs.pyc
-* Delete test4.pyc
-* Delete test3.pyc
-* Delete test2.pyc
-* Delete squaretest.pyc
-* First code drop on data modeling
-* Initial commit
diff --git a/tosca2heat/heat-translator-0.3.0/PKG-INFO b/tosca2heat/heat-translator-0.3.0/PKG-INFO
deleted file mode 100644 (file)
index 5917638..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-Metadata-Version: 1.1
-Name: heat-translator
-Version: 0.3.0
-Summary: Tool to translate non-heat templates to Heat Orchestration Template.
-Home-page: http://www.openstack.org/
-Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
-License: UNKNOWN
-Description: ===============
-        Heat-Translator
-        ===============
-        
-        Overview
-        --------
-        
-        Heat-Translator is an Openstack project and licensed under Apache 2. It is a
-        command line tool which takes non-Heat templates as an input and produces a
-        Heat Orchestration Template (HOT) which can be deployed by Heat. Currently the
-        development and testing is done with an aim to translate OASIS Topology and
-        Orchestration Specification for Cloud Applications (TOSCA) templates to
-        HOT. However, the tool is designed to be easily extended to use with any
-        format other than TOSCA.
-        
-        Architecture
-        ------------
-        
-        Heat-Translator project takes a non-Heat template (e.g. TOSCA flat YAML
-        template or template embedded in TOSCA Cloud Service Archive (CSAR) format) as
-        an input, calls an appropriate Parser (e.g. TOSCA Parser) per the type of input
-        template to parse it and create an in-memory graph, maps it to Heat resources
-        and then produces a Heat Orchestration Template (HOT) as an output.
-        
-        How To Use
-        ----------
-        Please refer to `doc/source/usage.rst <https://github.com/openstack/heat-translator/blob/master/doc/source/usage.rst>`_
-        
-        Directory Structure
-        -------------------
-        
-        Three main directories related to the heat-translator are:
-        
-        1. hot: It is the generator, that has logic of converting TOSCA in memory graph to HOT yaml files.
-        2. common: It has all the file that can support the execution of parser and generator.
-        3. tests: It contains test programs and more importantly several templates which are used for testing.
-        
-        Project Info
-        ------------
-        
-        * License: Apache License, Version 2.0
-        * Documentation: http://docs.openstack.org/developer/heat-translator/
-        * Launchpad: https://launchpad.net/heat-translator
-        * Blueprints: https://blueprints.launchpad.net/heat-translator
-        * Bugs: https://bugs.launchpad.net/heat-translator
-        * Source: http://git.openstack.org/cgit/openstack/heat-translator/
-        * IRC Channel: #openstack-heat-translator
-        
-        
-Platform: UNKNOWN
-Classifier: Environment :: OpenStack
-Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/PKG-INFO b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/PKG-INFO
deleted file mode 100644 (file)
index 5917638..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-Metadata-Version: 1.1
-Name: heat-translator
-Version: 0.3.0
-Summary: Tool to translate non-heat templates to Heat Orchestration Template.
-Home-page: http://www.openstack.org/
-Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
-License: UNKNOWN
-Description: ===============
-        Heat-Translator
-        ===============
-        
-        Overview
-        --------
-        
-        Heat-Translator is an Openstack project and licensed under Apache 2. It is a
-        command line tool which takes non-Heat templates as an input and produces a
-        Heat Orchestration Template (HOT) which can be deployed by Heat. Currently the
-        development and testing is done with an aim to translate OASIS Topology and
-        Orchestration Specification for Cloud Applications (TOSCA) templates to
-        HOT. However, the tool is designed to be easily extended to use with any
-        format other than TOSCA.
-        
-        Architecture
-        ------------
-        
-        Heat-Translator project takes a non-Heat template (e.g. TOSCA flat YAML
-        template or template embedded in TOSCA Cloud Service Archive (CSAR) format) as
-        an input, calls an appropriate Parser (e.g. TOSCA Parser) per the type of input
-        template to parse it and create an in-memory graph, maps it to Heat resources
-        and then produces a Heat Orchestration Template (HOT) as an output.
-        
-        How To Use
-        ----------
-        Please refer to `doc/source/usage.rst <https://github.com/openstack/heat-translator/blob/master/doc/source/usage.rst>`_
-        
-        Directory Structure
-        -------------------
-        
-        Three main directories related to the heat-translator are:
-        
-        1. hot: It is the generator, that has logic of converting TOSCA in memory graph to HOT yaml files.
-        2. common: It has all the file that can support the execution of parser and generator.
-        3. tests: It contains test programs and more importantly several templates which are used for testing.
-        
-        Project Info
-        ------------
-        
-        * License: Apache License, Version 2.0
-        * Documentation: http://docs.openstack.org/developer/heat-translator/
-        * Launchpad: https://launchpad.net/heat-translator
-        * Blueprints: https://blueprints.launchpad.net/heat-translator
-        * Bugs: https://bugs.launchpad.net/heat-translator
-        * Source: http://git.openstack.org/cgit/openstack/heat-translator/
-        * IRC Channel: #openstack-heat-translator
-        
-        
-Platform: UNKNOWN
-Classifier: Environment :: OpenStack
-Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/SOURCES.txt b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/SOURCES.txt
deleted file mode 100644 (file)
index b945891..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-.coveragerc
-.mailmap
-.testr.conf
-AUTHORS
-CONTRIBUTING.rst
-ChangeLog
-HACKING.rst
-LICENSE
-MANIFEST.in
-README.rst
-babel.cfg
-heat_translator.py
-heat_translator_logging.conf
-openstack-common.conf
-requirements.txt
-setup.cfg
-setup.py
-test-requirements.txt
-tox.ini
-doc/source/conf.py
-doc/source/contributing.rst
-doc/source/index.rst
-doc/source/installation.rst
-doc/source/usage.rst
-heat_translator.egg-info/PKG-INFO
-heat_translator.egg-info/SOURCES.txt
-heat_translator.egg-info/dependency_links.txt
-heat_translator.egg-info/entry_points.txt
-heat_translator.egg-info/not-zip-safe
-heat_translator.egg-info/pbr.json
-heat_translator.egg-info/requires.txt
-heat_translator.egg-info/top_level.txt
-translator/__init__.py
-translator/shell.py
-translator/common/__init__.py
-translator/common/exception.py
-translator/common/utils.py
-translator/conf/__init__.py
-translator/conf/config.py
-translator/conf/translator.conf
-translator/custom/__init__.py
-translator/custom/hot/__init__.py
-translator/custom/hot/tosca_collectd.py
-translator/custom/hot/tosca_elasticsearch.py
-translator/custom/hot/tosca_kibana.py
-translator/custom/hot/tosca_logstash.py
-translator/custom/hot/tosca_nodejs.py
-translator/custom/hot/tosca_paypalpizzastore.py
-translator/custom/hot/tosca_rsyslog.py
-translator/custom/hot/tosca_wordpress.py
-translator/hot/__init__.py
-translator/hot/tosca_translator.py
-translator/hot/translate_inputs.py
-translator/hot/translate_node_templates.py
-translator/hot/translate_outputs.py
-translator/hot/syntax/__init__.py
-translator/hot/syntax/hot_output.py
-translator/hot/syntax/hot_parameter.py
-translator/hot/syntax/hot_resource.py
-translator/hot/syntax/hot_template.py
-translator/hot/tests/__init__.py
-translator/hot/tests/test_hot_parameter.py
-translator/hot/tests/test_translate_inputs.py
-translator/hot/tests/test_translate_outputs.py
-translator/hot/tosca/__init__.py
-translator/hot/tosca/tosca_block_storage.py
-translator/hot/tosca/tosca_block_storage_attachment.py
-translator/hot/tosca/tosca_compute.py
-translator/hot/tosca/tosca_database.py
-translator/hot/tosca/tosca_dbms.py
-translator/hot/tosca/tosca_network_network.py
-translator/hot/tosca/tosca_network_port.py
-translator/hot/tosca/tosca_object_storage.py
-translator/hot/tosca/tosca_software_component.py
-translator/hot/tosca/tosca_web_application.py
-translator/hot/tosca/tosca_webserver.py
-translator/hot/tosca/tests/__init__.py
-translator/hot/tosca/tests/test_tosca_blockstorage.py
-translator/hot/tosca/tests/test_tosca_compute.py
-translator/hot/tosca/tests/test_tosca_objectstore.py
-translator/osc/__init__.py
-translator/osc/osc_plugin.py
-translator/osc/utils.py
-translator/osc/v1/__init__.py
-translator/osc/v1/translate.py
-translator/tests/__init__.py
-translator/tests/base.py
-translator/tests/test_conf.py
-translator/tests/test_shell.py
-translator/tests/test_template.py
-translator/tests/test_tosca_hot_translation.py
-translator/tests/test_utils.py
-translator/tests/data/csar_elk.zip
-translator/tests/data/csar_hello_world.zip
-translator/tests/data/csar_metadata_not_yaml.zip
-translator/tests/data/csar_not_zip.zip
-translator/tests/data/csar_single_instance_wordpress.zip
-translator/tests/data/csar_wordpress_invalid_import_path.zip
-translator/tests/data/csar_wordpress_invalid_script_url.zip
-translator/tests/data/csar_wrong_metadata_file.zip
-translator/tests/data/test_host_assignment.yaml
-translator/tests/data/tosca_elk.yaml
-translator/tests/data/tosca_helloworld.yaml
-translator/tests/data/tosca_helloworld_invalid.yaml
-translator/tests/data/tosca_nodejs_mongodb_two_instances.yaml
-translator/tests/data/tosca_single_instance_wordpress.yaml
-translator/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml
-translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
-translator/tests/data/tosca_single_server.yaml
-translator/tests/data/tosca_single_server_with_defaults.yaml
-translator/tests/data/tosca_software_component.yaml
-translator/tests/data/tosca_web_application.yaml
-translator/tests/data/artifacts/collectd/config.py
-translator/tests/data/artifacts/collectd/create.sh
-translator/tests/data/artifacts/collectd/start.sh
-translator/tests/data/artifacts/elasticsearch/create.sh
-translator/tests/data/artifacts/elasticsearch/start.sh
-translator/tests/data/artifacts/kibana/config.sh
-translator/tests/data/artifacts/kibana/create.sh
-translator/tests/data/artifacts/kibana/start.sh
-translator/tests/data/artifacts/logstash/configure_collectd.py
-translator/tests/data/artifacts/logstash/configure_elasticsearch.py
-translator/tests/data/artifacts/logstash/configure_rsyslog.py
-translator/tests/data/artifacts/logstash/create.sh
-translator/tests/data/artifacts/logstash/start.sh
-translator/tests/data/artifacts/mongodb/config.sh
-translator/tests/data/artifacts/mongodb/create.sh
-translator/tests/data/artifacts/mongodb/create_database.sh
-translator/tests/data/artifacts/mongodb/start.sh
-translator/tests/data/artifacts/mysql/mysql_database_configure.sh
-translator/tests/data/artifacts/mysql/mysql_dbms_configure.sh
-translator/tests/data/artifacts/mysql/mysql_dbms_install.sh
-translator/tests/data/artifacts/mysql/mysql_dbms_start.sh
-translator/tests/data/artifacts/nodejs/config.sh
-translator/tests/data/artifacts/nodejs/create.sh
-translator/tests/data/artifacts/nodejs/start.sh
-translator/tests/data/artifacts/rsyslog/config.sh
-translator/tests/data/artifacts/rsyslog/create.sh
-translator/tests/data/artifacts/rsyslog/start.sh
-translator/tests/data/artifacts/webserver/webserver_install.sh
-translator/tests/data/artifacts/webserver/webserver_start.sh
-translator/tests/data/artifacts/wordpress/wordpress_configure.sh
-translator/tests/data/artifacts/wordpress/wordpress_install.sh
-translator/tests/data/custom_types/collectd.yaml
-translator/tests/data/custom_types/elasticsearch.yaml
-translator/tests/data/custom_types/kibana.yaml
-translator/tests/data/custom_types/logstash.yaml
-translator/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml
-translator/tests/data/custom_types/rsyslog.yaml
-translator/tests/data/custom_types/wordpress.yaml
-translator/tests/data/hot_output/hot_elk.yaml
-translator/tests/data/hot_output/hot_elk_from_csar.yaml
-translator/tests/data/hot_output/hot_hello_world.yaml
-translator/tests/data/hot_output/hot_host_assignment.yaml
-translator/tests/data/hot_output/hot_nodejs_mongodb_two_instances.yaml
-translator/tests/data/hot_output/hot_single_instance_wordpress.yaml
-translator/tests/data/hot_output/hot_single_instance_wordpress_from_csar.yaml
-translator/tests/data/hot_output/hot_single_object_store.yaml
-translator/tests/data/hot_output/hot_single_server.yaml
-translator/tests/data/hot_output/hot_single_server_with_defaults_with_input.yaml
-translator/tests/data/hot_output/hot_single_server_with_defaults_without_input.yaml
-translator/tests/data/hot_output/hot_software_component.yaml
-translator/tests/data/hot_output/hot_web_application.yaml
-translator/tests/data/hot_output/network/hot_one_server_one_network.yaml
-translator/tests/data/hot_output/network/hot_one_server_three_networks.yaml
-translator/tests/data/hot_output/network/hot_server_on_existing_network.yaml
-translator/tests/data/hot_output/network/hot_two_servers_one_network.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt1.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation1_alt2.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt1.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_attachment_notation2_alt2.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_custom_relationship_type.yaml
-translator/tests/data/hot_output/storage/hot_blockstorage_with_relationship_template.yaml
-translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt1.yaml
-translator/tests/data/hot_output/storage/hot_multiple_blockstorage_with_attachment_alt2.yaml
-translator/tests/data/network/tosca_one_server_one_network.yaml
-translator/tests/data/network/tosca_one_server_three_networks.yaml
-translator/tests/data/network/tosca_server_on_existing_network.yaml
-translator/tests/data/network/tosca_two_servers_one_network.yaml
-translator/tests/data/storage/tosca_blockstorage_with_attachment.yaml
-translator/tests/data/storage/tosca_blockstorage_with_attachment_notation1.yaml
-translator/tests/data/storage/tosca_blockstorage_with_attachment_notation2.yaml
-translator/tests/data/storage/tosca_blockstorage_with_custom_relationship_type.yaml
-translator/tests/data/storage/tosca_blockstorage_with_relationship_template.yaml
-translator/tests/data/storage/tosca_multiple_blockstorage_with_attachment.yaml
-translator/tests/data/storage/tosca_single_object_store.yaml
\ No newline at end of file
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/dependency_links.txt b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/dependency_links.txt
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/entry_points.txt b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/entry_points.txt
deleted file mode 100644 (file)
index b0b1081..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[console_scripts]
-heat-translator = translator.shell:main
-
-[openstack.cli.extension]
-translator = translator.osc.osc_plugin
-
-[openstack.translator.v1]
-translate_template = translator.osc.v1.translate:TranslateTemplate
-
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/not-zip-safe b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/not-zip-safe
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/pbr.json b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/pbr.json
deleted file mode 100644 (file)
index d25af9b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"git_version": "ab4979a", "is_release": true}
\ No newline at end of file
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/requires.txt b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/requires.txt
deleted file mode 100644 (file)
index 04623eb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-pbr>=1.6
-Babel>=1.3
-cliff>=1.15.0
-PyYAML>=3.1.0
-python-dateutil>=2.4.2
-six>=1.9.0
-tosca-parser>=0.3.0
diff --git a/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/top_level.txt b/tosca2heat/heat-translator-0.3.0/heat_translator.egg-info/top_level.txt
deleted file mode 100644 (file)
index 3b6719f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-translator
diff --git a/tosca2heat/heat-translator-0.3.0/setup.cfg b/tosca2heat/heat-translator-0.3.0/setup.cfg
deleted file mode 100644 (file)
index c94dcbe..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-[metadata]
-name = heat-translator
-summary = Tool to translate non-heat templates to Heat Orchestration Template.
-description-file = 
-       README.rst
-author = OpenStack
-author-email = openstack-dev@lists.openstack.org
-home-page = http://www.openstack.org/
-classifier = 
-       Environment :: OpenStack
-       Intended Audience :: Information Technology
-       Intended Audience :: System Administrators
-       License :: OSI Approved :: Apache Software License
-       Operating System :: POSIX :: Linux
-       Programming Language :: Python
-       Programming Language :: Python :: 2
-       Programming Language :: Python :: 2.7
-       Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.4
-
-[files]
-packages = 
-       translator
-
-[entry_points]
-openstack.cli.extension = 
-       translator = translator.osc.osc_plugin
-openstack.translator.v1 = 
-       translate_template = translator.osc.v1.translate:TranslateTemplate
-console_scripts = 
-       heat-translator = translator.shell:main
-
-[build_sphinx]
-source-dir = doc/source
-build-dir = doc/build
-all_files = 1
-
-[upload_sphinx]
-upload-dir = doc/build/html
-
-[compile_catalog]
-directory = translator/locale
-domain = translator
-
-[update_catalog]
-domain = translator
-output_dir = translator/locale
-input_file = translator/locale/translator.pot
-
-[extract_messages]
-keywords = _ gettext ngettext l_ lazy_gettext
-mapping_file = babel.cfg
-output_file = translator/locale/translator.pot
-
-[egg_info]
-tag_date = 0
-tag_build = 
-tag_svn_revision = 0
-
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_collectd.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_collectd.py
deleted file mode 100755 (executable)
index ec517d0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaCollectd'
-
-
-class ToscaCollectd(HotResource):
-    '''Translate TOSCA node type tosca.nodes.SoftwareComponent.Collectd.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Collectd'
-
-    def __init__(self, nodetemplate):
-        super(ToscaCollectd, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_elasticsearch.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_elasticsearch.py
deleted file mode 100755 (executable)
index 34d7670..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaElasticsearch'
-
-
-class ToscaElasticsearch(HotResource):
-    '''Translate TOSCA type tosca.nodes.SoftwareComponent.Elasticsearch.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Elasticsearch'
-
-    def __init__(self, nodetemplate):
-        super(ToscaElasticsearch, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_kibana.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_kibana.py
deleted file mode 100755 (executable)
index 71f3402..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaKibana'
-
-
-class ToscaKibana(HotResource):
-    '''Translate TOSCA node type tosca.nodes.SoftwareComponent.Kibana.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Kibana'
-
-    def __init__(self, nodetemplate):
-        super(ToscaKibana, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_logstash.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_logstash.py
deleted file mode 100755 (executable)
index 39859e0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaLogstash'
-
-
-class ToscaLogstash(HotResource):
-    '''Translate TOSCA node type tosca.nodes.SoftwareComponent.Logstash.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Logstash'
-
-    def __init__(self, nodetemplate):
-        super(ToscaLogstash, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_nodejs.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_nodejs.py
deleted file mode 100755 (executable)
index 2102af5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaNodejs'
-
-
-class ToscaNodejs(HotResource):
-    '''Translate TOSCA node type tosca.nodes.SoftwareComponent.Nodejs.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Nodejs'
-
-    def __init__(self, nodetemplate):
-        super(ToscaNodejs, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_paypalpizzastore.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_paypalpizzastore.py
deleted file mode 100755 (executable)
index ae3865b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaPaypalPizzaStore'
-
-
-class ToscaPaypalPizzaStore(HotResource):
-    '''Translate TOSCA type tosca.nodes.WebApplication.PayPalPizzaStore.'''
-
-    toscatype = 'tosca.nodes.WebApplication.PayPalPizzaStore'
-
-    def __init__(self, nodetemplate):
-        super(ToscaPaypalPizzaStore, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_rsyslog.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_rsyslog.py
deleted file mode 100755 (executable)
index 9604d3c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaRsyslog'
-
-
-class ToscaRsyslog(HotResource):
-    '''Translate TOSCA node type tosca.nodes.SoftwareComponent.Rsyslog.'''
-
-    toscatype = 'tosca.nodes.SoftwareComponent.Rsyslog'
-
-    def __init__(self, nodetemplate):
-        super(ToscaRsyslog, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_wordpress.py b/tosca2heat/heat-translator-0.3.0/translator/custom/hot/tosca_wordpress.py
deleted file mode 100755 (executable)
index c20fe6a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from translator.hot.syntax.hot_resource import HotResource
-
-# Name used to dynamically load appropriate map class.
-TARGET_CLASS_NAME = 'ToscaWordpress'
-
-
-class ToscaWordpress(HotResource):
-    '''Translate TOSCA node type tosca.nodes.WebApplication.WordPress.'''
-
-    toscatype = 'tosca.nodes.WebApplication.WordPress'
-
-    def __init__(self, nodetemplate):
-        super(ToscaWordpress, self).__init__(nodetemplate)
-        pass
-
-    def handle_properties(self):
-        pass
diff --git a/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_single_instance_wordpress.zip b/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_single_instance_wordpress.zip
deleted file mode 100644 (file)
index 5df7b48..0000000
Binary files a/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_single_instance_wordpress.zip and /dev/null differ
diff --git a/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wordpress_invalid_import_path.zip b/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wordpress_invalid_import_path.zip
deleted file mode 100644 (file)
index d644259..0000000
Binary files a/tosca2heat/heat-translator-0.3.0/translator/tests/data/csar_wordpress_invalid_import_path.zip and /dev/null differ
@@ -63,9 +63,19 @@ Alternatively, you can install a particular release of Heat-Translator as availa
 In this case, you can simply run translation via CLI entry point::
     heat-translator --template-file=translator/tests/data/tosca_helloworld.yaml --template-type=tosca
 
-When deploy the translated template with Heat, please keep in mind that you have image registered in the Glance. The Heat-Translator
-project sets flavor and image from a pre-defined set of values (as listed in /home/openstack/heat-translator/translator/hot/tosca/tosca_compute.py)
-with the best possible match to the constraints defined in the TOSCA template. If there is no possible match found, a null value is set for now.
-Per the future plan, an image and flavor will be provided from an online repository.
-
+Things To Consider
+------------------
+* When deploying the translated template with Heat, please ensure that you have image registered in the Glance. The Heat-Translator
+  project sets flavor and image from a pre-defined set of values (as listed in /home/openstack/heat-translator/translator/hot/tosca/tosca_compute.py)
+  with the best possible match to the constraints defined in the TOSCA template. If there is no possible match found, a null value is set currently.
+  Per the future plan, an image and flavor will be provided from an online repository.
+* The ``key_name`` property of Nova server is irrelevant to the TOSCA specification and can not be used in TOSCA template. In order to use it in
+  the translated templates, the user must provide it via parameters, and the heat-translator will set it to all resources of ``OS::Nova::Server`` type.
+* Since properties of TOSCA Compute OS and HOST capabilities are optional, the user should make sure that either they set these properties correctly
+  in the TOSCA template or provide them via CLI parameters in order to find best match of flavor and image.
+* The ``flavor`` and ``image`` properties of ``OS::Nova::Server`` resource is irrelevant to the TOSCA specification and can not be used in the TOSCA
+  template as such. Heat-Translator sets these properties in the translated template based on constraints defined per TOSCA Compute OS and HOST
+  capabilities. However, user may required to use these properties in template in certain circumstances, so in that case, TOSCA Compute can be extended
+  with these properties and later used in the node template. For a good example, refer to the ``translator/tests/data/test_tosca_flavor_and_image.yaml`` test
+  template.
 
similarity index 53%
rename from tosca2heat/tosca-parser-0.3.0/requirements.txt
rename to tosca2heat/heat-translator/requirements.txt
index 7dc14c3..e54d0ab 100644 (file)
@@ -1,9 +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
-Babel>=1.3
-cliff>=1.14.0 # Apache-2.0
-PyYAML>=3.1.0
-python-dateutil>=2.4.2
-six>=1.9.0
+pbr>=1.6 # Apache-2.0
+Babel>=1.3 # BSD
+cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0
+PyYAML>=3.1.0 # MIT
+python-dateutil>=2.4.2 # BSD
+six>=1.9.0 # MIT
+tosca-parser>=0.4.0 # Apache-2.0
diff --git a/tosca2heat/heat-translator/setup.cfg b/tosca2heat/heat-translator/setup.cfg
new file mode 100644 (file)
index 0000000..029eeff
--- /dev/null
@@ -0,0 +1,55 @@
+[metadata]
+name = heat-translator
+summary = Tool to translate non-heat templates to Heat Orchestration Template.
+description-file =
+    README.rst
+author = OpenStack
+author-email = openstack-dev@lists.openstack.org
+home-page = http://www.openstack.org/
+classifier =
+    Environment :: OpenStack
+    Intended Audience :: Information Technology
+    Intended Audience :: System Administrators
+    License :: OSI Approved :: Apache Software License
+    Operating System :: POSIX :: Linux
+    Programming Language :: Python
+    Programming Language :: Python :: 2
+    Programming Language :: Python :: 2.7
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.4
+
+[files]
+packages =
+    translator
+
+[entry_points]
+openstack.cli.extension =
+    translator = translator.osc.osc_plugin
+
+openstack.translator.v1 =
+    translate_template = translator.osc.v1.translate:TranslateTemplate
+
+console_scripts =
+    heat-translator = translator.shell:main
+
+[build_sphinx]
+source-dir = doc/source
+build-dir = doc/build
+all_files = 1
+
+[upload_sphinx]
+upload-dir = doc/build/html
+
+[compile_catalog]
+directory = translator/locale
+domain = translator
+
+[update_catalog]
+domain = translator
+output_dir = translator/locale
+input_file = translator/locale/translator.pot
+
+[extract_messages]
+keywords = _ gettext ngettext l_ lazy_gettext
+mapping_file = babel.cfg
+output_file = translator/locale/translator.pot
@@ -2,13 +2,13 @@
 # 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
-discover
-fixtures>=1.3.1
+coverage>=3.6 # Apache-2.0
+discover # BSD
+fixtures>=1.3.1 # Apache-2.0/BSD
 oslotest>=1.10.0 # Apache-2.0
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
-python-subunit>=0.0.18
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-testrepository>=0.0.18
-testscenarios>=0.4
-testtools>=1.4.0
+python-subunit>=0.0.18 # Apache-2.0/BSD
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+testrepository>=0.0.18 # Apache-2.0/BSD
+testscenarios>=0.4 # Apache-2.0/BSD
+testtools>=1.4.0 # MIT
similarity index 96%
rename from tosca2heat/heat-translator-0.3.0/tox.ini
rename to tosca2heat/heat-translator/tox.ini
index 3649c0a..868e95a 100644 (file)
@@ -1,6 +1,6 @@
 [tox]
 minversion = 1.6
-envlist = py27,py34,pypy,pep8
+envlist = py34,py27,pypy,pep8
 skipsdist = True
 
 [testenv]
 #    under the License.
 
 
+import json
 import logging
 import math
 import numbers
 import os
 import re
+import requests
 from six.moves.urllib.parse import urlparse
 import yaml
 
@@ -23,9 +25,11 @@ from toscaparser.utils.gettextutils import _
 import toscaparser.utils.yamlparser
 
 YAML_ORDER_PARSER = toscaparser.utils.yamlparser.simple_ordered_parse
-log = logging.getLogger('tosca')
 log = logging.getLogger('heat-translator')
 
+# Required environment variables to create openstackclient object.
+ENV_VARIABLES = ['OS_AUTH_URL', 'OS_PASSWORD', 'OS_USERNAME', 'OS_TENANT_NAME']
+
 
 class MemoryUnit(object):
 
@@ -49,7 +53,7 @@ class MemoryUnit(object):
         else:
             unit = MemoryUnit.UNIT_SIZE_DEFAULT
             log.info(_('A memory unit is not provided for size; using the '
-                       'default unit %(default)s') % {'default': 'B'})
+                       'default unit %(default)s.') % {'default': 'B'})
         regex = re.compile('(\d*)\s*(\w*)')
         result = regex.match(str(size)).groups()
         if result[1]:
@@ -59,7 +63,7 @@ class MemoryUnit(object):
                             * math.pow(MemoryUnit.UNIT_SIZE_DICT
                                        [unit], -1))
             log.info(_('Given size %(size)s is converted to %(num)s '
-                       '%(unit)s') % {'size': size,
+                       '%(unit)s.') % {'size': size,
                      'num': converted, 'unit': unit})
         else:
             converted = (str_to_num(result[0]))
@@ -76,7 +80,7 @@ class MemoryUnit(object):
 
             msg = _('Provided unit "{0}" is not valid. The valid units are'
                     ' {1}').format(unit, MemoryUnit.UNIT_SIZE_DICT.keys())
-            log.warning(msg)
+            log.error(msg)
             raise ValueError(msg)
 
 
@@ -264,3 +268,52 @@ def str_to_num(value):
         return int(value)
     except ValueError:
         return float(value)
+
+
+def check_for_env_variables():
+    return set(ENV_VARIABLES) < set(os.environ.keys())
+
+
+def get_ks_access_dict():
+    tenant_name = os.getenv('OS_TENANT_NAME')
+    username = os.getenv('OS_USERNAME')
+    password = os.getenv('OS_PASSWORD')
+    auth_url = os.getenv('OS_AUTH_URL')
+
+    auth_dict = {
+        "auth": {
+            "tenantName": tenant_name,
+            "passwordCredentials": {
+                "username": username,
+                "password": password
+            }
+        }
+    }
+    headers = {'Content-Type': 'application/json'}
+    try:
+        keystone_response = requests.post(auth_url + '/tokens',
+                                          data=json.dumps(auth_dict),
+                                          headers=headers)
+        if keystone_response.status_code != 200:
+            return None
+        return json.loads(keystone_response.content)
+    except Exception:
+        return None
+
+
+def get_url_for(access_dict, service_type):
+    if access_dict is None:
+        return None
+    service_catalog = access_dict['access']['serviceCatalog']
+    service_url = ''
+    for service in service_catalog:
+        if service['type'] == service_type:
+            service_url = service['endpoints'][0]['publicURL']
+            break
+    return service_url
+
+
+def get_token_id(access_dict):
+    if access_dict is None:
+        return None
+    return access_dict['access']['token']['id']
 # under the License.
 
 from collections import OrderedDict
+import logging
+from toscaparser.utils.gettextutils import _
 
 KEYS = (TYPE, DESCRIPTION, DEFAULT, CONSTRAINTS, HIDDEN, LABEL) = \
        ('type', 'description', 'default', 'constraints', 'hidden', 'label')
 
+log = logging.getLogger('heat-translator')
+
 
 class HotParameter(object):
     '''Attributes for HOT parameter section.'''
@@ -29,6 +33,7 @@ class HotParameter(object):
         self.default = default
         self.hidden = hidden
         self.constraints = constraints
+        log.info(_('Initialized the input parameters.'))
 
     def get_dict_output(self):
         param_sections = OrderedDict()
 # under the License.
 
 from collections import OrderedDict
+import logging
 import six
 
+from toscaparser.elements.interfaces import InterfacesDef
 from toscaparser.functions import GetInput
 from toscaparser.nodetemplate import NodeTemplate
 from toscaparser.utils.gettextutils import _
@@ -23,6 +25,7 @@ SECTIONS = (TYPE, PROPERTIES, MEDADATA, DEPENDS_ON, UPDATE_POLICY,
             DELETION_POLICY) = \
            ('type', 'properties', 'metadata',
             'depends_on', 'update_policy', 'deletion_policy')
+log = logging.getLogger('heat-translator')
 
 
 class HotResource(object):
@@ -31,6 +34,7 @@ class HotResource(object):
     def __init__(self, nodetemplate, name=None, type=None, properties=None,
                  metadata=None, depends_on=None,
                  update_policy=None, deletion_policy=None):
+        log.debug(_('Translating TOSCA node type to HOT resource type.'))
         self.nodetemplate = nodetemplate
         if name:
             self.name = name
@@ -78,23 +82,23 @@ class HotResource(object):
         deploy_lookup = {}
         # TODO(anyone):  sequence for life cycle needs to cover different
         # scenarios and cannot be fixed or hard coded here
-        interfaces_deploy_sequence = ['create', 'configure', 'start']
+        operations_deploy_sequence = ['create', 'configure', 'start']
 
-        # create HotResource for each interface used for deployment:
+        operations = HotResource._get_all_operations(self.nodetemplate)
+
+        # create HotResource for each operation used for deployment:
         # create, start, configure
-        # ignore the other interfaces
+        # ignore the other operations
         # observe the order:  create, start, configure
-        # use the current HotResource for the first interface in this order
+        # use the current HotResource for the first operation in this order
 
         # hold the original name since it will be changed during
         # the transformation
         node_name = self.name
         reserve_current = 'NONE'
-        interfaces_actual = []
-        for interface in self.nodetemplate.interfaces:
-            interfaces_actual.append(interface.name)
-        for operation in interfaces_deploy_sequence:
-            if operation in interfaces_actual:
+
+        for operation in operations_deploy_sequence:
+            if operation in operations.keys():
                 reserve_current = operation
                 break
 
@@ -103,28 +107,28 @@ class HotResource(object):
         hosting_server = None
         if self.nodetemplate.requirements is not None:
             hosting_server = self._get_hosting_server()
-        for interface in self.nodetemplate.interfaces:
-            if interface.name in interfaces_deploy_sequence:
-                config_name = node_name + '_' + interface.name + '_config'
-                deploy_name = node_name + '_' + interface.name + '_deploy'
+        for operation in operations.values():
+            if operation.name in operations_deploy_sequence:
+                config_name = node_name + '_' + operation.name + '_config'
+                deploy_name = node_name + '_' + operation.name + '_deploy'
                 hot_resources.append(
                     HotResource(self.nodetemplate,
                                 config_name,
                                 'OS::Heat::SoftwareConfig',
                                 {'config':
-                                    {'get_file': interface.implementation}}))
+                                    {'get_file': operation.implementation}}))
 
                 # hosting_server is None if requirements is None
                 hosting_on_server = (hosting_server.name if
                                      hosting_server else None)
-                if interface.name == reserve_current:
+                if operation.name == reserve_current:
                     deploy_resource = self
                     self.name = deploy_name
                     self.type = 'OS::Heat::SoftwareDeployment'
                     self.properties = {'config': {'get_resource': config_name},
                                        'server': {'get_resource':
                                                   hosting_on_server}}
-                    deploy_lookup[interface.name] = self
+                    deploy_lookup[operation.name] = self
                 else:
                     sd_config = {'config': {'get_resource': config_name},
                                  'server': {'get_resource':
@@ -135,21 +139,21 @@ class HotResource(object):
                                     'OS::Heat::SoftwareDeployment',
                                     sd_config)
                     hot_resources.append(deploy_resource)
-                    deploy_lookup[interface.name] = deploy_resource
-                lifecycle_inputs = self._get_lifecycle_inputs(interface)
+                    deploy_lookup[operation.name] = deploy_resource
+                lifecycle_inputs = self._get_lifecycle_inputs(operation)
                 if lifecycle_inputs:
                     deploy_resource.properties['input_values'] = \
                         lifecycle_inputs
 
         # Add dependencies for the set of HOT resources in the sequence defined
-        # in interfaces_deploy_sequence
+        # in operations_deploy_sequence
         # TODO(anyone): find some better way to encode this implicit sequence
         group = {}
         for op, hot in deploy_lookup.items():
             # position to determine potential preceding nodes
-            op_index = interfaces_deploy_sequence.index(op)
+            op_index = operations_deploy_sequence.index(op)
             for preceding_op in \
-                    reversed(interfaces_deploy_sequence[:op_index]):
+                    reversed(operations_deploy_sequence[:op_index]):
                 preceding_hot = deploy_lookup.get(preceding_op)
                 if preceding_hot:
                     hot.depends_on.append(preceding_hot)
@@ -236,15 +240,15 @@ class HotResource(object):
 
         return {self.name: resource_sections}
 
-    def _get_lifecycle_inputs(self, interface):
+    def _get_lifecycle_inputs(self, operation):
         # check if this lifecycle operation has input values specified
         # extract and convert to HOT format
-        if isinstance(interface.value, six.string_types):
-            # the interface has a static string
+        if isinstance(operation.value, six.string_types):
+            # the operation has a static string
             return {}
         else:
-            # the interface is a dict {'implemenation': xxx, 'input': yyy}
-            inputs = interface.value.get('inputs')
+            # the operation is a dict {'implemenation': xxx, 'input': yyy}
+            inputs = operation.value.get('inputs')
             deploy_inputs = {}
             if inputs:
                 for name, value in six.iteritems(inputs):
@@ -287,7 +291,8 @@ class HotResource(object):
         # capability is a list of dict
         # For now just check if it's type tosca.nodes.Compute
         # TODO(anyone): match up requirement and capability
-        if node.type == 'tosca.nodes.Compute':
+        base_type = HotResource.get_base_type(node.type_definition)
+        if base_type.type == 'tosca.nodes.Compute':
             return True
         else:
             return False
@@ -298,7 +303,7 @@ class HotResource(object):
         raise Exception(_("No translation in TOSCA type {0} for attribute "
                           "{1}").format(self.nodetemplate.type, attribute))
 
-    def _get_tosca_props(self, properties):
+    def get_tosca_props(self):
         tosca_props = {}
         for prop in self.nodetemplate.get_properties_objects():
             if isinstance(prop.value, GetInput):
@@ -306,3 +311,52 @@ class HotResource(object):
             else:
                 tosca_props[prop.name] = prop.value
         return tosca_props
+
+    @staticmethod
+    def _get_all_operations(node):
+        operations = {}
+        for operation in node.interfaces:
+            operations[operation.name] = operation
+
+        node_type = node.type_definition
+        if isinstance(node_type, str) or \
+            node_type.type == "tosca.policies.Placement":
+                return operations
+
+        while True:
+            type_operations = HotResource._get_interface_operations_from_type(
+                node_type, node, 'Standard')
+            type_operations.update(operations)
+            operations = type_operations
+
+            if node_type.parent_type is not None:
+                node_type = node_type.parent_type
+            else:
+                return operations
+
+    @staticmethod
+    def _get_interface_operations_from_type(node_type, node, lifecycle_name):
+        operations = {}
+        if isinstance(node_type, str) or \
+            node_type.type == "tosca.policies.Placement":
+                return operations
+        if node_type.interfaces and lifecycle_name in node_type.interfaces:
+            for name, elems in node_type.interfaces[lifecycle_name].items():
+                # ignore empty operations (only type)
+                # ignore global interface inputs,
+                # concrete inputs are on the operations themselves
+                if name != 'type' and name != 'inputs':
+                    operations[name] = InterfacesDef(node_type,
+                                                     lifecycle_name,
+                                                     node, name, elems)
+        return operations
+
+    @staticmethod
+    def get_base_type(node_type):
+        if node_type.parent_type is not None:
+            if node_type.parent_type.type.endswith('.Root'):
+                return node_type
+            else:
+                return HotResource.get_base_type(node_type.parent_type)
+        else:
+            return node_type
 # under the License.
 
 from collections import OrderedDict
+import logging
 import textwrap
+from toscaparser.utils.gettextutils import _
 import yaml
 
+log = logging.getLogger('heat-translator')
+
 
 class HotTemplate(object):
     '''Container for full Heat Orchestration template.'''
@@ -41,6 +45,7 @@ class HotTemplate(object):
         return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', nodes)
 
     def output_to_yaml(self):
+        log.debug(_('Converting translated output to yaml format.'))
         dict_output = OrderedDict()
         # Version
         version_string = self.VERSION + ": " + self.LATEST + "\n\n"
@@ -212,10 +212,12 @@ class ToscaComputeTest(TestCase):
                   disk_size: 1 GB
                   mem_size: 1 GB
         '''
-        with patch('translator.hot.tosca.tosca_compute.ToscaCompute.'
-                   '_check_for_env_variables') as mock_check_env:
+        with patch('translator.common.utils.'
+                   'check_for_env_variables') as mock_check_env:
             mock_check_env.return_value = True
             mock_os_getenv.side_effect = ['demo', 'demo',
+                                          'demo', 'http://abc.com/5000/',
+                                          'demo', 'demo',
                                           'demo', 'http://abc.com/5000/']
             mock_ks_response = mock.MagicMock()
             mock_ks_response.status_code = 200
@@ -251,3 +253,34 @@ class ToscaComputeTest(TestCase):
             self._tosca_compute_test(
                 tpl_snippet,
                 expectedprops)
+
+    @patch('requests.post')
+    @patch('requests.get')
+    @patch('os.getenv')
+    def test_node_compute_without_nova_flavor(self, mock_os_getenv,
+                                              mock_get, mock_post):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            capabilities:
+              host:
+                properties:
+                  num_cpus: 1
+                  disk_size: 1 GB
+                  mem_size: 1 GB
+        '''
+        with patch('translator.common.utils.'
+                   'check_for_env_variables') as mock_check_env:
+            mock_check_env.return_value = True
+            mock_os_getenv.side_effect = ['demo', 'demo',
+                                          'demo', 'http://abc.com/5000/']
+            mock_ks_response = mock.MagicMock()
+            mock_ks_content = {}
+            mock_ks_response.content = json.dumps(mock_ks_content)
+            expectedprops = {'flavor': 'm1.small',
+                             'user_data_format': 'SOFTWARE_CONFIG',
+                             'image': None}
+            self._tosca_compute_test(
+                tpl_snippet,
+                expectedprops)
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_policies.py b/tosca2heat/heat-translator/translator/hot/tosca/tests/test_tosca_policies.py
new file mode 100644 (file)
index 0000000..24368ab
--- /dev/null
@@ -0,0 +1,80 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from toscaparser.nodetemplate import NodeTemplate
+from toscaparser.policy import Policy
+from toscaparser.tests.base import TestCase
+import toscaparser.utils.yamlparser
+from translator.hot.tosca.tosca_compute import ToscaCompute
+from translator.hot.tosca.tosca_policies import ToscaPolicies
+
+
+class ToscaPoicyTest(TestCase):
+
+    def _tosca_policy_test(self, tpl_snippet, expectedprops):
+        nodetemplates = (toscaparser.utils.yamlparser.
+                         simple_parse(tpl_snippet)['node_templates'])
+        policies = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet)['policies'])
+        name = list(nodetemplates.keys())[0]
+        policy_name = list(policies[0].keys())[0]
+        for policy in policies:
+            tpl = policy[policy_name]
+            targets = tpl["targets"]
+        try:
+            nodetemplate = NodeTemplate(name, nodetemplates)
+            toscacompute = ToscaCompute(nodetemplate)
+            toscacompute.handle_properties()
+
+            policy = Policy(policy_name, tpl, targets,
+                            "node_templates")
+            toscapolicy = ToscaPolicies(policy)
+            nodetemplate = [toscacompute]
+            toscapolicy.handle_properties(nodetemplate)
+
+            self.assertEqual(toscacompute.properties, expectedprops)
+        except Exception:
+            raise
+
+    def test_compute_with_policies(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            capabilities:
+              host:
+                properties:
+                  disk_size: 10 GB
+                  num_cpus: 4
+                  mem_size: 4 GB
+              os:
+                properties:
+                  architecture: x86_64
+                  type: Linux
+                  distribution: Fedora
+                  version: 18.0
+        policies:
+          - my_compute_placement_policy:
+              type: tosca.policies.Placement
+              description: Apply my placement policy to my application servers
+              targets: [ server ]
+        '''
+        expectedprops = {'flavor': 'm1.large',
+                         'image': 'fedora-amd64-heat-config',
+                         'scheduler_hints': {
+                             'group': {
+                                 'get_resource':
+                                 'my_compute_placement_policy'}},
+                         'user_data_format': 'SOFTWARE_CONFIG'}
+        self._tosca_policy_test(
+            tpl_snippet,
+            expectedprops)
@@ -18,7 +18,7 @@ from toscaparser.functions import GetInput
 from toscaparser.utils.gettextutils import _
 from translator.hot.syntax.hot_resource import HotResource
 
-log = logging.getLogger("tosca")
+log = logging.getLogger('heat-translator')
 
 # Name used to dynamically load appropriate map class.
 TARGET_CLASS_NAME = 'ToscaBlockStorage'
@@ -45,8 +45,10 @@ class ToscaBlockStorage(HotResource):
                                   get_num_from_scalar_unit('GiB'))
                     if size_value == 0:
                         # OpenStack Heat expects size in GB
+                        msg = _('Cinder Volume Size unit should be in GB.')
+                        log.error(msg)
                         raise InvalidPropertyValueError(
-                            what=_('Cinder Volume Size unit should be in GBs'))
+                            what=msg)
                     elif int(size_value) < size_value:
                         size_value = int(size_value) + 1
                         log.warning(_("Cinder unit value should be in "
old mode 100755 (executable)
new mode 100644 (file)
similarity index 70%
rename from tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py
rename to tosca2heat/heat-translator/translator/hot/tosca/tosca_compute.py
index 137418d..e2ac130
 
 import json
 import logging
-import os
 import requests
 
-from toscaparser.utils.validateutils import TOSCAVersionProperty
+from toscaparser.utils.gettextutils import _
 import translator.common.utils
 from translator.hot.syntax.hot_resource import HotResource
-log = logging.getLogger('tosca')
+
+log = logging.getLogger('heat-translator')
+
 
 # Name used to dynamically load appropriate map class.
 TARGET_CLASS_NAME = 'ToscaCompute'
 
-# Required environment variables to create novaclient object.
-ENV_VARIABLES = ['OS_AUTH_URL', 'OS_PASSWORD', 'OS_USERNAME', 'OS_TENANT_NAME']
-
 # A design issue to be resolved is how to translate the generic TOSCA server
 # properties to OpenStack flavors and images.  At the Atlanta design summit,
 # there was discussion on using Glance to store metadata and Graffiti to
@@ -79,6 +77,11 @@ IMAGES = {'ubuntu-software-config-os-init': {'architecture': 'x86_64',
 class ToscaCompute(HotResource):
     '''Translate TOSCA node type tosca.nodes.Compute.'''
 
+    COMPUTE_HOST_PROP = (DISK_SIZE, MEM_SIZE, NUM_CPUS) = \
+                        ('disk_size', 'mem_size', 'num_cpus')
+
+    COMPUTE_OS_PROP = (ARCHITECTURE, DISTRIBUTION, TYPE, VERSION) = \
+                      ('architecture', 'distribution', 'type', 'version')
     toscatype = 'tosca.nodes.Compute'
 
     def __init__(self, nodetemplate):
@@ -93,9 +96,9 @@ class ToscaCompute(HotResource):
             self.nodetemplate.get_capability('host'),
             self.nodetemplate.get_capability('os'))
         self.properties['user_data_format'] = 'SOFTWARE_CONFIG'
-        # TODO(anyone): handle user key
-        # hardcoded here for testing
-        self.properties['key_name'] = 'userkey'
+        tosca_props = self.get_tosca_props()
+        for key, value in tosca_props.items():
+            self.properties[key] = value
 
     # To be reorganized later based on new development in Glance and Graffiti
     def translate_compute_flavor_and_image(self,
@@ -116,64 +119,45 @@ class ToscaCompute(HotResource):
             image = self._best_image(os_cap_props)
         hot_properties['flavor'] = flavor
         hot_properties['image'] = image
-        # TODO(anyone): consider adding the flavor or image as a template
-        # parameter if no match is found.
         return hot_properties
 
-    def _check_for_env_variables(self):
-        return set(ENV_VARIABLES) < set(os.environ.keys())
-
     def _create_nova_flavor_dict(self):
         '''Populates and returns the flavors dict using Nova ReST API'''
-
-        tenant_name = os.getenv('OS_TENANT_NAME')
-        username = os.getenv('OS_USERNAME')
-        password = os.getenv('OS_PASSWORD')
-        auth_url = os.getenv('OS_AUTH_URL')
-
-        auth_dict = {
-            "auth": {
-                "tenantName": tenant_name,
-                "passwordCredentials": {
-                    "username": username,
-                    "password": password
+        try:
+            access_dict = translator.common.utils.get_ks_access_dict()
+            access_token = translator.common.utils.get_token_id(access_dict)
+            if access_token is None:
+                return None
+            nova_url = translator.common.utils.get_url_for(access_dict,
+                                                           'compute')
+            if not nova_url:
+                return None
+            nova_response = requests.get(nova_url + '/flavors/detail',
+                                         headers={'X-Auth-Token':
+                                                  access_token})
+            if nova_response.status_code != 200:
+                return None
+            flavors = json.loads(nova_response.content)['flavors']
+            flavor_dict = dict()
+            for flavor in flavors:
+                flavor_name = str(flavor['name'])
+                flavor_dict[flavor_name] = {
+                    'mem_size': flavor['ram'],
+                    'disk_size': flavor['disk'],
+                    'num_cpus': flavor['vcpus'],
                 }
-            }
-        }
-        headers = {'Content-Type': 'application/json'}
-        keystone_response = requests.post(auth_url + '/tokens',
-                                          data=json.dumps(auth_dict),
-                                          headers=headers)
-        if keystone_response.status_code != 200:
-            return None
-        access_dict = json.loads(keystone_response.content)
-        access_token = access_dict['access']['token']['id']
-        service_catalog = access_dict['access']['serviceCatalog']
-        nova_url = ''
-        for service in service_catalog:
-            if service['type'] == 'compute':
-                nova_url = service['endpoints'][0]['publicURL']
-        if not nova_url:
-            return None
-        nova_response = requests.get(nova_url + '/flavors/detail',
-                                     headers={'X-Auth-Token': access_token})
-        if nova_response.status_code != 200:
+        except Exception as e:
+            # Handles any exception coming from openstack
+            log.warn(_('Choosing predefined flavors since received '
+                       'Openstack Exception: %s') % str(e))
             return None
-        flavors = json.loads(nova_response.content)['flavors']
-        flavor_dict = dict()
-        for flavor in flavors:
-            flavor_name = str(flavor['name'])
-            flavor_dict[flavor_name] = {
-                'mem_size': flavor['ram'],
-                'disk_size': flavor['disk'],
-                'num_cpus': flavor['vcpus'],
-            }
         return flavor_dict
 
     def _best_flavor(self, properties):
+        log.info(_('Choosing the best flavor for given attributes.'))
         # Check whether user exported all required environment variables.
         flavors = FLAVORS
-        if self._check_for_env_variables():
+        if translator.common.utils.check_for_env_variables():
             resp = self._create_nova_flavor_dict()
             if resp:
                 flavors = resp
@@ -184,23 +168,29 @@ class ToscaCompute(HotResource):
         # TODO(anyone): Handle the case where the value contains something like
         # get_input instead of a value.
         # flavors that fit the CPU count
-        cpu = properties.get('num_cpus')
-        match_cpu = self._match_flavors(match_all, flavors, 'num_cpus', cpu)
+        cpu = properties.get(self.NUM_CPUS)
+        if cpu is None:
+            self._log_compute_msg(self.NUM_CPUS, 'flavor')
+        match_cpu = self._match_flavors(match_all, flavors, self.NUM_CPUS, cpu)
 
         # flavors that fit the mem size
-        mem = properties.get('mem_size')
+        mem = properties.get(self.MEM_SIZE)
         if mem:
             mem = translator.common.utils.MemoryUnit.convert_unit_size_to_num(
                 mem, 'MB')
+        else:
+            self._log_compute_msg(self.MEM_SIZE, 'flavor')
         match_cpu_mem = self._match_flavors(match_cpu, flavors,
-                                            'mem_size', mem)
+                                            self.MEM_SIZE, mem)
         # flavors that fit the disk size
-        disk = properties.get('disk_size')
+        disk = properties.get(self.DISK_SIZE)
         if disk:
             disk = translator.common.utils.MemoryUnit.\
                 convert_unit_size_to_num(disk, 'GB')
+        else:
+            self._log_compute_msg(self.DISK_SIZE, 'flavor')
         match_cpu_mem_disk = self._match_flavors(match_cpu_mem, flavors,
-                                                 'disk_size', disk)
+                                                 self.DISK_SIZE, disk)
         # if multiple match, pick the flavor with the least memory
         # the selection can be based on other heuristic, e.g. pick one with the
         # least total resource
@@ -213,19 +203,26 @@ class ToscaCompute(HotResource):
 
     def _best_image(self, properties):
         match_all = IMAGES.keys()
-        architecture = properties.get('architecture')
+        architecture = properties.get(self.ARCHITECTURE)
+        if architecture is None:
+            self._log_compute_msg(self.ARCHITECTURE, 'image')
         match_arch = self._match_images(match_all, IMAGES,
-                                        'architecture', architecture)
-        type = properties.get('type')
-        match_type = self._match_images(match_arch, IMAGES, 'type', type)
-        distribution = properties.get('distribution')
+                                        self.ARCHITECTURE, architecture)
+        type = properties.get(self.TYPE)
+        if type is None:
+            self._log_compute_msg(self.TYPE, 'image')
+        match_type = self._match_images(match_arch, IMAGES, self.TYPE, type)
+        distribution = properties.get(self.DISTRIBUTION)
+        if distribution is None:
+            self._log_compute_msg(self.DISTRIBUTION, 'image')
         match_distribution = self._match_images(match_type, IMAGES,
-                                                'distribution',
+                                                self.DISTRIBUTION,
                                                 distribution)
-        version = properties.get('version')
-        version = TOSCAVersionProperty(version).get_version()
+        version = properties.get(self.VERSION)
+        if version is None:
+            self._log_compute_msg(self.VERSION, 'image')
         match_version = self._match_images(match_distribution, IMAGES,
-                                           'version', version)
+                                           self.VERSION, version)
 
         if len(match_version):
             return list(match_version)[0]
@@ -239,6 +236,7 @@ class ToscaCompute(HotResource):
             if isinstance(size, int):
                 if this_dict[flavor][attr] >= size:
                     matching_flavors.append(flavor)
+        log.debug(_('Returning list of flavors matching the attribute size.'))
         return matching_flavors
 
     def _least_flavor(self, this_list, this_dict, attr):
@@ -267,8 +265,16 @@ class ToscaCompute(HotResource):
         # Note: We treat private and public IP  addresses equally, but
         # this will change in the future when TOSCA starts to support
         # multiple private/public IP addresses.
+        log.debug(_('Converting TOSCA attribute for a nodetemplate to a HOT \
+                  attriute.'))
         if attribute == 'private_address' or \
            attribute == 'public_address':
                 attr['get_attr'] = [self.name, 'networks', 'private', 0]
 
         return attr
+
+    def _log_compute_msg(self, prop, what):
+        msg = _('No value is provided for Compute capability '
+                'property "%(prop)s". This may set an undesired "%(what)s" '
+                'in the template.') % {'prop': prop, 'what': what}
+        log.warn(msg)
@@ -34,8 +34,7 @@ class ToscaNetwork(HotResource):
         pass
 
     def handle_properties(self):
-        tosca_props = self._get_tosca_props(
-            self.nodetemplate.get_properties_objects())
+        tosca_props = self.get_tosca_props()
 
         net_props = {}
         for key, value in tosca_props.items():
@@ -73,8 +72,7 @@ class ToscaNetwork(HotResource):
         if self.hide_resource:
             return
 
-        tosca_props = self._get_tosca_props(
-            self.nodetemplate.get_properties_objects())
+        tosca_props = self.get_tosca_props()
 
         subnet_props = {}
 
@@ -15,6 +15,8 @@ from translator.hot.syntax.hot_resource import HotResource
 
 # Name used to dynamically load appropriate map class.
 TARGET_CLASS_NAME = 'ToscaNetworkPort'
+TOSCA_LINKS_TO = 'tosca.relationships.network.LinksTo'
+TOSCA_BINDS_TO = 'tosca.relationships.network.BindsTo'
 
 
 class ToscaNetworkPort(HotResource):
@@ -49,14 +51,12 @@ class ToscaNetworkPort(HotResource):
         resources.insert(lo, resource)
 
     def handle_properties(self):
-        tosca_props = self._get_tosca_props(
-            self.nodetemplate.get_properties_objects())
+        tosca_props = self.get_tosca_props()
         port_props = {}
         for key, value in tosca_props.items():
             if key == 'ip_address':
-                fixed_ip = []
+                fixed_ip = {}
                 fixed_ip['ip_address'] = value
-                fixed_ip['subnet'] = ''
                 port_props['fixed_ips'] = [fixed_ip]
             elif key == 'order':
                 self.order = value
@@ -70,48 +70,45 @@ class ToscaNetworkPort(HotResource):
             else:
                 port_props[key] = value
 
-        # Get the nodetype relationships
-        relationships = {relation.type: node for relation, node in
-                         self.nodetemplate.relationships.items()}
-
-        # Check for LinksTo relations. If found add a network property with
-        # the network name into the port
         links_to = None
-        if 'tosca.relationships.network.LinksTo' in relationships:
-            links_to = relationships['tosca.relationships.network.LinksTo']
+        binds_to = None
+        for rel, node in self.nodetemplate.relationships.items():
+            # Check for LinksTo relations. If found add a network property with
+            # the network name into the port
+            if not links_to and rel.is_derived_from(TOSCA_LINKS_TO):
+                links_to = node
 
-            network_resource = None
-            for hot_resource in self.depends_on_nodes:
-                if links_to.name == hot_resource.name:
-                    network_resource = hot_resource
-                    self.depends_on.remove(hot_resource)
-                    break
+                network_resource = None
+                for hot_resource in self.depends_on_nodes:
+                    if links_to.name == hot_resource.name:
+                        network_resource = hot_resource
+                        self.depends_on.remove(hot_resource)
+                        break
 
-            if network_resource.existing_resource_id:
-                port_props['network'] =\
-                    str(network_resource.existing_resource_id)
-            else:
-                port_props['network'] = '{ get_resource: %s }'\
-                    % (links_to.name)
+                if network_resource.existing_resource_id:
+                    port_props['network'] =\
+                        str(network_resource.existing_resource_id)
+                else:
+                    port_props['network'] = '{ get_resource: %s }'\
+                        % (links_to.name)
 
-        # Check for BindsTo relationship. If found add network to the networks
-        # property of the corresponding compute resource
-        binds_to = None
-        if 'tosca.relationships.network.BindsTo' in relationships:
-            binds_to = relationships['tosca.relationships.network.BindsTo']
-            compute_resource = None
-            for hot_resource in self.depends_on_nodes:
-                if binds_to.name == hot_resource.name:
-                    compute_resource = hot_resource
-                    self.depends_on.remove(hot_resource)
-                    break
-            if compute_resource:
-                port_resources = compute_resource.assoc_port_resources
-                self._insert_sorted_resource(port_resources, self)
-                # TODO(sdmonov): Using generate networks every time we add a
-                # network is not the fastest way to do the things. We should
-                # do this only once at the end.
-                networks = self._generate_networks_for_compute(port_resources)
-                compute_resource.properties['networks'] = networks
+            # Check for BindsTo relationship. If found add network to the
+            # network property of the corresponding compute resource
+            elif not binds_to and rel.is_derived_from(TOSCA_BINDS_TO):
+                binds_to = node
+                compute_resource = None
+                for hot_resource in self.depends_on_nodes:
+                    if binds_to.name == hot_resource.name:
+                        compute_resource = hot_resource
+                        self.depends_on.remove(hot_resource)
+                        break
+                if compute_resource:
+                    port_rsrcs = compute_resource.assoc_port_resources
+                    self._insert_sorted_resource(port_rsrcs, self)
+                    # TODO(sdmonov): Using generate networks every time we add
+                    # a network is not the fastest way to do the things. We
+                    # should do this only once at the end.
+                    networks = self._generate_networks_for_compute(port_rsrcs)
+                    compute_resource.properties['networks'] = networks
 
         self.properties = port_props
@@ -29,8 +29,7 @@ class ToscaObjectStorage(HotResource):
         pass
 
     def handle_properties(self):
-        tosca_props = self._get_tosca_props(
-            self.nodetemplate.get_properties_objects())
+        tosca_props = self.get_tosca_props()
         objectstore_props = {}
         container_quota = {}
         skip_check = False
diff --git a/tosca2heat/heat-translator/translator/hot/tosca/tosca_policies.py b/tosca2heat/heat-translator/translator/hot/tosca/tosca_policies.py
new file mode 100644 (file)
index 0000000..b32fc1d
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from translator.hot.syntax.hot_resource import HotResource
+
+# Name used to dynamically load appropriate map class.
+TARGET_CLASS_NAME = 'ToscaPolicies'
+
+
+class ToscaPolicies(HotResource):
+    '''Translate TOSCA policy type tosca.poicies.Placement.'''
+
+    toscatype = 'tosca.policies.Placement'
+
+    def __init__(self, policy):
+        super(ToscaPolicies, self).__init__(policy,
+                                            type='OS::Nova::ServerGroup')
+        self.policy = policy
+
+    def handle_properties(self, resources):
+        self.properties["name"] = self.name
+        self.properties["policies"] = ["affinity"]
+        for resource in resources:
+            if resource.name in self.policy.targets:
+                resource.properties["scheduler_hints"] = {
+                    "group": {"get_resource": self.name}}
 # under the License.
 
 import logging
+from toscaparser.utils.gettextutils import _
 from translator.hot.syntax.hot_template import HotTemplate
 from translator.hot.translate_inputs import TranslateInputs
 from translator.hot.translate_node_templates import TranslateNodeTemplates
 from translator.hot.translate_outputs import TranslateOutputs
 
+log = logging.getLogger('heat-translator')
+
 
 class TOSCATranslator(object):
     '''Invokes translation methods.'''
 
-    log = logging.getLogger('heat-translator')
-
-    def __init__(self, tosca, parsed_params):
+    def __init__(self, tosca, parsed_params, deploy=None):
         super(TOSCATranslator, self).__init__()
         self.tosca = tosca
         self.hot_template = HotTemplate()
         self.parsed_params = parsed_params
+        self.deploy = deploy
         self.node_translator = None
+        log.info(_('Initialized parmaters for translation.'))
 
     def translate(self):
         self._resolve_input()
@@ -41,7 +44,8 @@ class TOSCATranslator(object):
         return self.hot_template.output_to_yaml()
 
     def _translate_inputs(self):
-        translator = TranslateInputs(self.tosca.inputs, self.parsed_params)
+        translator = TranslateInputs(self.tosca.inputs, self.parsed_params,
+                                     self.deploy)
         return translator.translate()
 
     def _translate_outputs(self):
@@ -58,7 +62,7 @@ class TOSCATranslator(object):
                         self.parsed_params[node_prop.value['get_input']]
                     except Exception:
                         msg = (_('Must specify all input values in \
-                                TOSCA template, missing %s') %
+                                TOSCA template, missing %s.') %
                                node_prop.value['get_input'])
-                        self.log.warning(msg)
+                        log.error(msg)
                         raise ValueError(msg)
@@ -14,6 +14,7 @@
 import logging
 from toscaparser.dataentity import DataEntity
 from toscaparser.elements.scalarunit import ScalarUnit_Size
+from toscaparser.parameters import Input
 from toscaparser.utils.gettextutils import _
 from toscaparser.utils.validateutils import TOSCAVersionProperty
 from translator.hot.syntax.hot_parameter import HotParameter
@@ -58,19 +59,30 @@ log = logging.getLogger('heat-translator')
 
 
 class TranslateInputs(object):
+
     '''Translate TOSCA Inputs to Heat Parameters.'''
 
-    def __init__(self, inputs, parsed_params):
+    def __init__(self, inputs, parsed_params, deploy=None):
         self.inputs = inputs
         self.parsed_params = parsed_params
+        self.deploy = deploy
 
     def translate(self):
         return self._translate_inputs()
 
     def _translate_inputs(self):
         hot_inputs = []
-        hot_default = None
+        if 'key_name' in self.parsed_params and 'key_name' not in self.inputs:
+            name = 'key_name'
+            type = 'string'
+            default = self.parsed_params[name]
+            schema_dict = {'type': type, 'default': default}
+            input = Input(name, schema_dict)
+            self.inputs.append(input)
+
+        log.info(_('Translating TOSCA input type to HOT input type.'))
         for input in self.inputs:
+            hot_default = None
             hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type]
 
             if input.name in self.parsed_params:
@@ -80,10 +92,11 @@ class TranslateInputs(object):
                 hot_default = DataEntity.validate_datatype(input.type,
                                                            input.default)
             else:
-                log.warning(_("Need to specify a value "
-                              "for input {0}").format(input.name))
-                raise Exception(_("Need to specify a value "
-                                  "for input {0}").format(input.name))
+                if self.deploy:
+                    msg = _("Need to specify a value "
+                            "for input {0}.").format(input.name)
+                    log.error(msg)
+                    raise Exception(msg)
             if input.type == "scalar-unit.size":
                 # Assumption here is to use this scalar-unit.size for size of
                 # cinder volume in heat templates and will be in GB.
@@ -92,9 +105,9 @@ class TranslateInputs(object):
                 hot_default = (ScalarUnit_Size(hot_default).
                                get_num_from_scalar_unit('GiB'))
                 if hot_default == 0:
-                    log.warning(_('Unit value should be > 0.'))
-                    raise Exception(_(
-                        'Unit value should be > 0.'))
+                    msg = _('Unit value should be > 0.')
+                    log.error(msg)
+                    raise Exception(msg)
                 elif int(hot_default) < hot_default:
                     hot_default = int(hot_default) + 1
                     log.warning(_("Cinder unit value should be in multiples"
@@ -108,7 +121,8 @@ class TranslateInputs(object):
             hot_constraints = []
             if input.constraints:
                 for constraint in input.constraints:
-                    constraint.validate(hot_default)
+                    if hot_default:
+                        constraint.validate(hot_default)
                     hc, hvalue = self._translate_constraints(
                         constraint.constraint_key, constraint.constraint_value)
                     hot_constraints.append({hc: hvalue})
@@ -19,7 +19,9 @@ import six
 from toscaparser.functions import GetAttribute
 from toscaparser.functions import GetInput
 from toscaparser.functions import GetProperty
+from toscaparser.properties import Property
 from toscaparser.relationship_template import RelationshipTemplate
+from toscaparser.utils.gettextutils import _
 from translator.common.exception import ToscaClassAttributeError
 from translator.common.exception import ToscaClassImportError
 from translator.common.exception import ToscaModImportError
@@ -141,7 +143,9 @@ class TranslateNodeTemplates(object):
         # list of all HOT resources generated
         self.hot_resources = []
         # mapping between TOSCA nodetemplate and HOT resource
+        log.debug(_('Mapping between TOSCA nodetemplate and HOT resource.'))
         self.hot_lookup = {}
+        self.policies = self.tosca.topology_template.policies
 
     def translate(self):
         return self._translate_nodetemplates()
@@ -155,20 +159,25 @@ class TranslateNodeTemplates(object):
         for depend_on in resource.depends_on_nodes:
             self._recursive_handle_properties(depend_on)
 
-        resource.handle_properties()
+        if resource.type == "OS::Nova::ServerGroup":
+            resource.handle_properties(self.hot_resources)
+        else:
+            resource.handle_properties()
 
     def _translate_nodetemplates(self):
 
+        log.debug(_('Translating the node templates.'))
         suffix = 0
         # Copy the TOSCA graph: nodetemplate
         for node in self.nodetemplates:
-            hot_node = TOSCA_TO_HOT_TYPE[node.type](node)
+            base_type = HotResource.get_base_type(node.type_definition)
+            hot_node = TOSCA_TO_HOT_TYPE[base_type.type](node)
             self.hot_resources.append(hot_node)
             self.hot_lookup[node] = hot_node
 
             # BlockStorage Attachment is a special case,
             # which doesn't match to Heat Resources 1 to 1.
-            if node.type == "tosca.nodes.Compute":
+            if base_type.type == "tosca.nodes.Compute":
                 volume_name = None
                 requirements = node.requirements
                 if requirements:
@@ -193,6 +202,18 @@ class TranslateNodeTemplates(object):
                                                                 volume_name)
                     if attachment_node:
                         self.hot_resources.append(attachment_node)
+                for i in self.tosca.inputs:
+                    if (i.name == 'key_name' and
+                            node.get_property_value('key_name') is None):
+                        schema = {'type': i.type, 'default': i.default}
+                        value = {"get_param": "key_name"}
+                        prop = Property(i.name, value, schema)
+                        node._properties.append(prop)
+
+        for policy in self.policies:
+            policy_type = policy.type_definition
+            policy_node = TOSCA_TO_HOT_TYPE[policy_type.type](policy)
+            self.hot_resources.append(policy_node)
 
         # Handle life cycle operations: this may expand each node
         # into multiple HOT resources and may change their name
@@ -274,22 +295,66 @@ class TranslateNodeTemplates(object):
             inputs = resource.properties.get('input_values')
             if inputs:
                 for name, value in six.iteritems(inputs):
-                    if isinstance(value, GetAttribute):
-                        # for the attribute
-                        # get the proper target type to perform the translation
-                        args = value.result()
-                        target = args[0]
-                        hot_target = self.find_hot_resource(target)
-
-                        inputs[name] = hot_target.get_hot_attribute(args[1],
-                                                                    args)
-                    else:
-                        if isinstance(value, GetProperty) or \
-                                isinstance(value, GetInput):
-                            inputs[name] = value.result()
+                    inputs[name] = self._translate_input(value, resource)
 
         return self.hot_resources
 
+    def _translate_input(self, input_value, resource):
+        get_property_args = None
+        if isinstance(input_value, GetProperty):
+            get_property_args = input_value.args
+        # to remove when the parser is fixed to return GetProperty
+        if isinstance(input_value, dict) and 'get_property' in input_value:
+            get_property_args = input_value['get_property']
+        if get_property_args is not None:
+            hot_target = self._find_hot_resource_for_tosca(
+                get_property_args[0], resource)
+            if hot_target:
+                props = hot_target.get_tosca_props()
+                prop_name = get_property_args[1]
+                if prop_name in props:
+                    return props[prop_name]
+        elif isinstance(input_value, GetAttribute):
+            # for the attribute
+            # get the proper target type to perform the translation
+            args = input_value.result()
+            hot_target = self._find_hot_resource_for_tosca(args[0], resource)
+
+            return hot_target.get_hot_attribute(args[1], args)
+        # most of artifacts logic should move to the parser
+        elif isinstance(input_value, dict) and 'get_artifact' in input_value:
+            get_artifact_args = input_value['get_artifact']
+
+            hot_target = self._find_hot_resource_for_tosca(
+                get_artifact_args[0], resource)
+            artifacts = TranslateNodeTemplates.get_all_artifacts(
+                hot_target.nodetemplate)
+
+            if get_artifact_args[1] in artifacts:
+                artifact = artifacts[get_artifact_args[1]]
+                if artifact.get('type', None) == 'tosca.artifacts.File':
+                    return {'get_file': artifact.get('file')}
+        elif isinstance(input_value, GetInput):
+            if isinstance(input_value.args, list) \
+                    and len(input_value.args) == 1:
+                return {'get_param': input_value.args[0]}
+            else:
+                return {'get_param': input_value.args}
+
+        return input_value
+
+    @staticmethod
+    def get_all_artifacts(nodetemplate):
+        artifacts = nodetemplate.type_definition.get_value('artifacts',
+                                                           parent=True)
+        if not artifacts:
+            artifacts = {}
+        tpl_artifacts = nodetemplate.entity_tpl.get('artifacts')
+        if tpl_artifacts:
+            artifacts.update(tpl_artifacts)
+
+        return artifacts
+
     def _get_attachment_node(self, node, suffix, volume_name):
         attach = False
         ntpl = self.nodetemplates
@@ -350,11 +415,21 @@ class TranslateNodeTemplates(object):
             if node.name == tosca_name:
                 return node
 
-    def _find_hot_resource_for_tosca(self, tosca_name):
+    def _find_hot_resource_for_tosca(self, tosca_name,
+                                     current_hot_resource=None):
+        if tosca_name == 'SELF':
+            return current_hot_resource
+        if tosca_name == 'HOST' and current_hot_resource is not None:
+            for req in current_hot_resource.nodetemplate.requirements:
+                if 'host' in req:
+                    return self._find_hot_resource_for_tosca(req['host'])
+
         for node in self.nodetemplates:
             if node.name == tosca_name:
                 return self.hot_lookup[node]
 
+        return None
+
     def _create_connect_configs(self, source_node, target_name,
                                 connect_interfaces):
         connectsto_resources = []
@@ -381,7 +456,7 @@ class TranslateNodeTemplates(object):
                 msg = _("Template error:  "
                         "no configuration found for ConnectsTo "
                         "in {1}").format(self.nodetemplate.name)
-                log.warning(msg)
+                log.error(msg)
                 raise Exception(msg)
         config_name = source_node.name + '_' + target_name + '_connect_config'
         implement = connect_config.get('implementation')
 # License for the specific language governing permissions and limitations
 # under the License.
 
+import logging
+
+from toscaparser.utils.gettextutils import _
 from translator.hot.syntax.hot_output import HotOutput
 
+log = logging.getLogger('heat-translator')
+
 
 class TranslateOutputs(object):
     '''Translate TOSCA Outputs to Heat Outputs.'''
 
     def __init__(self, outputs, node_translator):
+        log.debug(_('Translating TOSCA outputs to HOT outputs.'))
         self.outputs = outputs
         self.nodes = node_translator
 
diff --git a/tosca2heat/heat-translator/translator/osc/v1/tests/fakes.py b/tosca2heat/heat-translator/translator/osc/v1/tests/fakes.py
new file mode 100644 (file)
index 0000000..a08c3ac
--- /dev/null
@@ -0,0 +1,32 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+
+import sys
+
+
+class FakeApp(object):
+    def __init__(self):
+        self.client_manager = None
+        self.stdin = sys.stdin
+        self.stdout = sys.stdout
+        self.stderr = sys.stderr
+
+
+class FakeClientManager(object):
+    def __init__(self):
+        self.compute = None
+        self.identity = None
+        self.image = None
+        self.object_store = None
+        self.volume = None
+        self.network = None
+        self.session = None
diff --git a/tosca2heat/heat-translator/translator/osc/v1/tests/test_translate.py b/tosca2heat/heat-translator/translator/osc/v1/tests/test_translate.py
new file mode 100644 (file)
index 0000000..6a5f115
--- /dev/null
@@ -0,0 +1,448 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+
+import mock
+import testtools
+
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+import toscaparser.utils.yamlparser
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import URLException
+from toscaparser.common.exception import ValidationError
+from toscaparser.utils.gettextutils import _
+from translator.common.utils import CompareUtils
+from translator.common.utils import YamlUtils
+from translator.osc.v1.tests import fakes
+from translator.osc.v1.tests import utils
+from translator.osc.v1 import translate
+
+
+class TestTranslateTemplate(testtools.TestCase):
+
+    def setUp(self):
+        super(TestTranslateTemplate, self).setUp()
+        self.app = fakes.FakeApp()
+        self.app.client_manager = fakes.FakeClientManager()
+        self.app.client_manager.translator = None
+        self.cmd = translate.TranslateTemplate(self.app, None)
+
+    def check_parser(self, cmd, args, verify_args):
+        cmd_parser = cmd.get_parser('check_parser')
+        try:
+            parsed_args = cmd_parser.parse_args(args)
+        except SystemExit:
+            raise Exception("Argument parse failed")
+        for av in verify_args:
+            attr, value = av
+            if attr:
+                self.assertIn(attr, parsed_args)
+                self.assertEqual(getattr(parsed_args, attr), value)
+        return parsed_args
+
+    def _check_error(self, tosca_file, hot_file, params, assert_error,
+                     expected_msg, c_error):
+        arglist = ["--template-file", tosca_file,
+                   "--template-type", "tosca"]
+        parsed_args = self.check_parser(self.cmd, arglist, [])
+        parsed_args.parameter = params
+        self.assertRaises(assert_error, self.cmd.take_action,
+                          parsed_args)
+        ExceptionCollector.assertExceptionMessage(c_error, expected_msg)
+
+    @mock.patch('sys.stdout', new_callable=StringIO)
+    def _check_success(self, tosca_file, hot_file, params, mock_stdout):
+        arglist = ["--template-file", tosca_file,
+                   "--template-type", "tosca"]
+        parsed_args = self.check_parser(self.cmd, arglist, [])
+        parsed_args.parameter = params
+        self.cmd.take_action(parsed_args)
+        expected_output = YamlUtils.get_dict(hot_file)
+        mock_stdout_yaml = "\n".join(mock_stdout.getvalue().split("\n"))
+        actual_output = toscaparser.utils.yamlparser.simple_parse(
+            mock_stdout_yaml)
+        self.assertEqual({}, CompareUtils.diff_dicts(
+            actual_output, expected_output))
+
+    def test_osc_translate_single_server(self):
+        tosca_file = utils.get_template_path("tosca_single_server.yaml")
+
+        hot_file = utils.get_template_path("hot_output/hot_single_server.yaml")
+
+        params = {'cpus': 1}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_single_server_defaults_with_input(self):
+        tosca_file = utils.get_template_path(
+            "tosca_single_server_with_defaults.yaml")
+
+        hot_file = utils.get_template_path(
+            "hot_output/hot_single_server_with_defaults_with_input.yaml")
+
+        params = {'cpus': '1'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_single_server_defaults_without_input(self):
+        tosca_file = utils.get_template_path(
+            "tosca_single_server_with_defaults.yaml")
+
+        hot_file = utils.get_template_path(
+            "hot_output/hot_single_server_with_defaults_without_input.yaml")
+
+        self._check_success(tosca_file, hot_file, {})
+
+    def test_osc_translate_wordpress_single_instance(self):
+        tosca_file = utils.get_template_path(
+            "tosca_single_instance_wordpress.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_single_instance_wordpress.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_helloworld(self):
+        tosca_file = utils.get_template_path(
+            "tosca_helloworld.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_hello_world.yaml")
+        self._check_success(tosca_file, hot_file, {})
+
+    def test_osc_translate_host_assignment(self):
+        tosca_file = utils.get_template_path(
+            "test_host_assignment.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_host_assignment.yaml")
+        self._check_success(tosca_file, hot_file, {})
+
+    def test_osc_translate_elk(self):
+        tosca_file = utils.get_template_path(
+            "tosca_elk.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_elk.yaml")
+        params = {'github_url':
+                  'http://github.com/paypal/rest-api-sample-app-nodejs.git',
+                  'my_cpus': 4}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_nodejs_mongodb_two_instances(self):
+        tosca_file = utils.get_template_path(
+            "tosca_nodejs_mongodb_two_instances.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_nodejs_mongodb_two_instances.yaml")
+        params = {'github_url':
+                  'http://github.com/paypal/rest-api-sample-app-nodejs.git',
+                  'my_cpus': 4}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_blockstorage_with_attachment(self):
+        tosca_file = utils.get_template_path(
+            "storage/tosca_blockstorage_with_attachment.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/storage/hot_blockstorage_with_attachment.yaml")
+        params = {'cpus': 1,
+                  'storage_location': '/dev/vdc',
+                  'storage_size': '2000 MB',
+                  'storage_snapshot_id': 'ssid'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_blockstorage_with_custom_relationship_type(self):
+        tosca_file = utils.get_template_path(
+            "storage/tosca_blockstorage_with_custom_relationship_type.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/storage/"
+            "hot_blockstorage_with_custom_relationship_type.yaml")
+        params = {'cpus': 1,
+                  'storage_location': '/dev/vdc',
+                  'storage_size': '1 GB',
+                  'storage_snapshot_id': 'ssid'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_blockstorage_with_relationship_template(self):
+        tosca_file = utils.get_template_path(
+            "storage/" +
+            "tosca_blockstorage_with_relationship_template.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_blockstorage_with_relationship_template.yaml")
+        params = {'cpus': 1,
+                  'storage_location': '/dev/vdc',
+                  'storage_size': '1 GB'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_blockstorage_with_attachment_notation1(self):
+        tosca_file = utils.get_template_path(
+            "storage/" +
+            "tosca_blockstorage_with_attachment_notation1.yaml")
+        hot_file1 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_blockstorage_with_attachment_notation1_alt1.yaml")
+        hot_file2 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_blockstorage_with_attachment_notation1_alt2.yaml")
+        params = {'cpus': 1,
+                  'storage_location': 'some_folder',
+                  'storage_size': '1 GB',
+                  'storage_snapshot_id': 'ssid'}
+        try:
+            self._check_success(tosca_file, hot_file1, params)
+        except Exception:
+            self._check_success(tosca_file, hot_file2, params)
+
+    def test_osc_translate_blockstorage_with_attachment_notation2(self):
+        tosca_file = utils.get_template_path(
+            "storage/" +
+            "tosca_blockstorage_with_attachment_notation2.yaml")
+        hot_file1 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_blockstorage_with_attachment_notation2_alt1.yaml")
+        hot_file2 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_blockstorage_with_attachment_notation2_alt2.yaml")
+        params = {'cpus': 1,
+                  'storage_location': '/dev/vdc',
+                  'storage_size': '1 GB',
+                  'storage_snapshot_id': 'ssid'}
+        try:
+            self._check_success(tosca_file, hot_file1, params)
+        except Exception:
+            self._check_success(tosca_file, hot_file2, params)
+
+    def test_osc_translate_multiple_blockstorage_with_attachment(self):
+        tosca_file = utils.get_template_path(
+            "storage/" +
+            "tosca_multiple_blockstorage_with_attachment.yaml")
+        hot_file1 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_multiple_blockstorage_with_attachment_alt1.yaml")
+        hot_file2 = utils.get_template_path(
+            "hot_output/storage/" +
+            "hot_multiple_blockstorage_with_attachment_alt2.yaml")
+        params = {'cpus': 1,
+                  'storage_location': '/dev/vdc',
+                  'storage_size': '1 GB',
+                  'storage_snapshot_id': 'ssid'}
+        try:
+            self._check_success(tosca_file, hot_file1, params)
+        except Exception:
+            self._check_success(tosca_file, hot_file2, params)
+
+    def test_osc_translate_single_object_store(self):
+        tosca_file = utils.get_template_path(
+            "storage/tosca_single_object_store.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_single_object_store.yaml")
+        params = {'objectstore_name': 'myobjstore'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_one_server_one_network(self):
+        tosca_file = utils.get_template_path(
+            "network/tosca_one_server_one_network.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/network/" +
+            "hot_one_server_one_network.yaml")
+        params = {'network_name': 'private_net'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_server_on_existing_network(self):
+        tosca_file = utils.get_template_path(
+            "network/" +
+            "tosca_server_on_existing_network.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/network/" +
+            "hot_server_on_existing_network.yaml")
+        params = {'network_name': 'private_net'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_two_servers_one_network(self):
+        tosca_file = utils.get_template_path(
+            "network/tosca_two_servers_one_network.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/network/" +
+            "hot_two_servers_one_network.yaml")
+        params = {'network_name': 'my_private_net',
+                  'network_cidr': '10.0.0.0/24',
+                  'network_start_ip': '10.0.0.100',
+                  'network_end_ip': '10.0.0.150'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_one_server_three_networks(self):
+        tosca_file = utils.get_template_path(
+            "network/" +
+            "tosca_one_server_three_networks.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/network/" +
+            "hot_one_server_three_networks.yaml")
+        self._check_success(tosca_file, hot_file, {})
+
+    def test_osc_translate_software_component(self):
+        tosca_file = utils.get_template_path("tosca_software_component.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_software_component.yaml")
+        params = {'cpus': '1',
+                  'download_url': 'http://www.software.com/download'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_web_application(self):
+        tosca_file = utils.get_template_path("tosca_web_application.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_web_application.yaml")
+        params = {'cpus': '2', 'context_root': 'my_web_app'}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_template_with_url_import(self):
+        tosca_file = utils.get_template_path(
+            "tosca_single_instance_wordpress_with_url_import.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_single_instance_wordpress.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_template_by_url_with_local_import(self):
+        tosca_file = ("https://raw.githubusercontent.com/openstack/" +
+                      "heat-translator/master/translator/tests/data/" +
+                      "tosca_single_instance_wordpress.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/" +
+            "hot_single_instance_wordpress.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_template_by_url_with_local_abspath_import(self):
+        tosca_file = ("https://raw.githubusercontent.com/openstack/" +
+                      "heat-translator/master/translator/tests/data/" +
+                      "tosca_single_instance_wordpress_with_local_abspath" +
+                      "_import.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/" +
+            "hot_single_instance_wordpress.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+
+        expected_msg = _('Absolute file name "/tmp/wordpress.yaml" cannot be '
+                         'used in a URL-based input template "https://raw.'
+                         'githubusercontent.com/openstack/heat-translator/'
+                         'master/translator/tests/data/tosca_single_instance_'
+                         'wordpress_with_local_abspath_import.yaml".')
+        self._check_error(tosca_file, hot_file, params, ValidationError,
+                          expected_msg, ImportError)
+
+    def test_osc_translate_template_by_url_with_url_import(self):
+        tosca_url = ("https://raw.githubusercontent.com/openstack/" +
+                     "heat-translator/master/translator/tests/data/" +
+                     "tosca_single_instance_wordpress_with_url_import.yaml")
+        hot_file = utils.get_template_path(
+            "hot_output/" +
+            "hot_single_instance_wordpress.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+        self._check_success(tosca_url, hot_file, params)
+
+    def test_osc_translate_hello_world_csar(self):
+        tosca_file = utils.get_template_path("csar_hello_world.zip")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_hello_world.yaml")
+        self._check_success(tosca_file, hot_file, {})
+
+    def test_osc_single_instance_wordpress_csar(self):
+        tosca_file = utils.get_template_path(
+            "csar_single_instance_wordpress.zip")
+        hot_file = utils.get_template_path(
+            "hot_output/" +
+            "hot_single_instance_wordpress_from_csar.yaml")
+        params = {'db_name': 'wordpress',
+                  'db_user': 'wp_user',
+                  'db_pwd': 'wp_pass',
+                  'db_root_pwd': 'passw0rd',
+                  'db_port': 3366,
+                  'cpus': 8}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_elk_csar_from_url(self):
+        tosca_file = ("https://github.com/openstack/heat-translator/raw/" +
+                      "master/translator/tests/data/csar_elk.zip")
+        hot_file = utils.get_template_path(
+            "hot_output/hot_elk_from_csar.yaml")
+        params = {'github_url':
+                  'http://github.com/paypal/rest-api-sample-app-nodejs.git',
+                  'my_cpus': 4}
+        self._check_success(tosca_file, hot_file, params)
+
+    def test_osc_translate_csar_not_zip(self):
+        tosca_file = utils.get_template_path("csar_not_zip.zip")
+        hot_file = ''
+        expected_msg = _('"%s" is not a valid zip file.') % tosca_file
+        self._check_error(tosca_file, hot_file, {}, ValidationError,
+                          expected_msg, ValidationError)
+
+    def test_osc_translate_csar_metadata_not_yaml(self):
+        tosca_file = utils.get_template_path("csar_metadata_not_yaml.zip")
+        hot_file = ''
+        expected_msg = _('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR '
+                         '"%s" does not contain valid YAML'
+                         ' content.') % tosca_file
+        self._check_error(tosca_file, hot_file, {}, ValidationError,
+                          expected_msg, ValidationError)
+
+    def test_osc_translate_csar_wrong_metadata_file(self):
+        tosca_file = utils.get_template_path("csar_wrong_metadata_file.zip")
+        hot_file = ''
+
+        expected_msg = _('"%s" is not a valid CSAR as it does not contain the '
+                         'required file "TOSCA.meta" in the folder '
+                         '"TOSCA-Metadata".') % tosca_file
+        self._check_error(tosca_file, hot_file, {}, ValidationError,
+                          expected_msg, ValidationError)
+
+    def test_osc_translate_csar_wordpress_invalid_import_path(self):
+        tosca_file = utils.get_template_path(
+            "csar_wordpress_invalid_import_path.zip")
+        hot_file = ''
+        expected_msg = _('Import '
+                         '"Invalid_import_path/wordpress.yaml" is not valid.')
+        self._check_error(tosca_file, hot_file, {}, ValidationError,
+                          expected_msg, ImportError)
+
+    def test_osc_translate_csar_wordpress_invalid_script_url(self):
+        tosca_file = utils.get_template_path(
+            "csar_wordpress_invalid_script_url.zip")
+        hot_file = ''
+        expected_msg = _('The resource at '
+                         '"https://raw.githubusercontent.com/openstack/'
+                         'heat-translator/master/translator/tests/data/'
+                         'custom_types/wordpress1.yaml" cannot be accessed.')
+        self._check_error(tosca_file, hot_file, {}, ValidationError,
+                          expected_msg, URLException)
diff --git a/tosca2heat/heat-translator/translator/osc/v1/tests/utils.py b/tosca2heat/heat-translator/translator/osc/v1/tests/utils.py
new file mode 100644 (file)
index 0000000..edd45a7
--- /dev/null
@@ -0,0 +1,19 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+
+import os
+
+
+def get_template_path(path):
+    data_folder = "../../../tests/data/"
+    return os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                        data_folder + path)
@@ -12,6 +12,7 @@
 
 """Translate action implementations"""
 
+import logging
 import logging.config
 import os
 import sys
@@ -19,15 +20,20 @@ import sys
 from cliff import command
 
 from toscaparser.tosca_template import ToscaTemplate
+from toscaparser.utils.gettextutils import _
 from translator.common.utils import UrlUtils
 from translator.hot.tosca_translator import TOSCATranslator
 from translator.osc import utils
 
 
+logging.config.fileConfig('heat_translator_logging.conf')
+log = logging.getLogger('heat-translator')
+
+
 class TranslateTemplate(command.Command):
+
     """Translate a template"""
 
-    log = logging.getLogger('heat-translator' + '.TranslateTemplate')
     auth_required = False
 
     def get_parser(self, prog_name):
@@ -62,7 +68,8 @@ class TranslateTemplate(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        self.log.debug('take_action(%s)', parsed_args)
+        log.debug(_('Translating the template with input parameters'
+                    '(%s).'), parsed_args)
         output = None
 
         if parsed_args.parameter:
@@ -78,12 +85,17 @@ class TranslateTemplate(command.Command):
                 validate = parsed_args.validate_only
                 if validate and validate.lower() == "true":
                     ToscaTemplate(path, parsed_params, a_file)
+                    msg = (_('The input "%(path)s" successfully passed '
+                             'validation.') % {'path': path})
+                    print(msg)
                 else:
                     tosca = ToscaTemplate(path, parsed_params, a_file)
                     translator = TOSCATranslator(tosca, parsed_params)
                     output = translator.translate()
             else:
-                sys.stdout.write('Could not find template file.')
+                msg = _('Could not find template file.')
+                log.error(msg)
+                sys.stdout.write(msg)
                 raise SystemExit
 
         if output:
 #    under the License.
 
 
+import ast
+import json
+import logging
 import logging.config
 import os
+import prettytable
+import requests
 import sys
+import uuid
+import yaml
 
 from toscaparser.tosca_template import ToscaTemplate
 from toscaparser.utils.gettextutils import _
 from toscaparser.utils.urlutils import UrlUtils
+from translator.common import utils
 from translator.hot.tosca_translator import TOSCATranslator
 
 """
@@ -37,6 +45,7 @@ other required arguments.
 
 """
 
+logging.config.fileConfig('heat_translator_logging.conf')
 log = logging.getLogger("heat-translator")
 
 
@@ -48,28 +57,37 @@ class TranslatorShell(object):
         if len(args) < 2:
             msg = _("The program requires minimum two arguments. "
                     "Please refer to the usage documentation.")
+            log.error(msg)
             raise ValueError(msg)
         if "--template-file=" not in args[0]:
             msg = _("The program expects --template-file as first argument. "
                     "Please refer to the usage documentation.")
+            log.error(msg)
             raise ValueError(msg)
         if "--template-type=" not in args[1]:
             msg = _("The program expects --template-type as second argument. "
                     "Please refer to the usage documentation.")
+            log.error(msg)
             raise ValueError(msg)
 
     def main(self, args):
+        # TODO(spzala): set self.deploy based on passed args once support for
+        # --deploy argument is enabled.
+        self.deploy = False
         self._validate(args)
         path = args[0].split('--template-file=')[1]
         # e.g. --template_file=translator/tests/data/tosca_helloworld.yaml
         template_type = args[1].split('--template-type=')[1]
         # e.g. --template_type=tosca
         if not template_type:
-            raise ValueError(_("Template type is needed. "
-                               "For example, 'tosca'"))
+            msg = _("Template type is needed. For example, 'tosca'")
+            log.error(msg)
+            raise ValueError(msg)
         elif template_type not in self.SUPPORTED_TYPES:
-            raise ValueError(_("%(value)s is not a valid template type.")
-                             % {'value': template_type})
+            msg = _("%(value)s is not a valid template type.") % {
+                'value': template_type}
+            log.error(msg)
+            raise ValueError(msg)
         parsed_params = {}
         validate_only = None
         output_file = None
@@ -83,6 +101,8 @@ class TranslatorShell(object):
                 if "--output-file=" in arg:
                     output = arg
                     output_file = output.split('--output-file=')[1]
+                if "--deploy" in arg:
+                    self.deploy = True
             if parameters:
                 parsed_params = self._parse_parameters(parameters)
         a_file = os.path.isfile(path)
@@ -95,14 +115,27 @@ class TranslatorShell(object):
                     run_only_validation = True
             if run_only_validation:
                 ToscaTemplate(path, parsed_params, a_file)
+                msg = (_('The input "%(path)s" successfully passed '
+                         'validation.') % {'path': path})
+                print(msg)
             else:
+                log.info(
+                    _('Checked whether template path is a file or url path.'))
                 heat_tpl = self._translate(template_type, path, parsed_params,
                                            a_file)
                 if heat_tpl:
+                    if utils.check_for_env_variables() and self.deploy:
+                        try:
+                            heatclient(heat_tpl, parsed_params)
+                        except Exception:
+                            log.error(_("Unable to launch the heat stack"))
+
                     self._write_output(heat_tpl, output_file)
         else:
-            raise ValueError(_("The path %(path)s is not a valid file"
-                               " or URL.") % {'path': path})
+            msg = _("The path %(path)s is not a valid file or URL.") % {
+                'path': path}
+            log.error(msg)
+            raise ValueError(msg)
 
     def _parse_parameters(self, parameter_list):
         parsed_inputs = {}
@@ -114,27 +147,33 @@ class TranslatorShell(object):
             for param in inputs:
                 keyvalue = param.split('=')
                 # Validate the parameter has both a name and value
+                msg = _("'%(param)s' is not a well-formed parameter.") % {
+                    'param': param}
                 if keyvalue.__len__() is 2:
                     # Assure parameter name is not zero-length or whitespace
                     stripped_name = keyvalue[0].strip()
                     if not stripped_name:
-                        raise ValueError(_("'%(param)s' is not a well-formed "
-                                         "parameter.") % {'param': param})
+                        log.error(msg)
+                        raise ValueError(msg)
                     # Add the valid parameter to the dictionary
                     parsed_inputs[keyvalue[0]] = keyvalue[1]
                 else:
-                    raise ValueError(_("'%(param)s' is not a well-formed "
-                                     "parameter.") % {'param': param})
+                    log.error(msg)
+                    raise ValueError(msg)
         else:
-            raise ValueError(_("'%(list)s' is not a valid parameter list.")
-                             % {'list': parameter_list})
+            msg = _("'%(list)s' is not a valid parameter list.") % {
+                'list': parameter_list}
+            log.error(msg)
+            raise ValueError(msg)
         return parsed_inputs
 
     def _translate(self, sourcetype, path, parsed_params, a_file):
         output = None
         if sourcetype == "tosca":
+            log.debug(_('Loading the tosca template.'))
             tosca = ToscaTemplate(path, parsed_params, a_file)
-            translator = TOSCATranslator(tosca, parsed_params)
+            translator = TOSCATranslator(tosca, parsed_params, self.deploy)
+            log.debug(_('Translating the tosca template.'))
             output = translator.translate()
         return output
 
@@ -147,6 +186,48 @@ class TranslatorShell(object):
                 print(output)
 
 
+def heatclient(output, params):
+    try:
+        access_dict = utils.get_ks_access_dict()
+        endpoint = utils.get_url_for(access_dict, 'orchestration')
+        token = utils.get_token_id(access_dict)
+    except Exception as e:
+        log.error(e)
+    headers = {
+        'Content-Type': 'application/json',
+        'X-Auth-Token': token
+    }
+    heat_stack_name = "heat_" + str(uuid.uuid4()).split("-")[0]
+    output = yaml.load(output)
+    output['heat_template_version'] = str(output['heat_template_version'])
+    data = {
+        'stack_name': heat_stack_name,
+        'template': output,
+        'parameters': params
+    }
+    response = requests.post(endpoint + '/stacks',
+                             data=json.dumps(data),
+                             headers=headers)
+    content = ast.literal_eval(response._content)
+    if response.status_code == 201:
+        stack_id = content["stack"]["id"]
+        get_url = endpoint + '/stacks/' + heat_stack_name + '/' + stack_id
+        get_stack_response = requests.get(get_url,
+                                          headers=headers)
+        stack_details = json.loads(get_stack_response.content)["stack"]
+        col_names = ["id", "stack_name", "stack_status", "creation_time",
+                     "updated_time"]
+        pt = prettytable.PrettyTable(col_names)
+        stack_list = []
+        for col in col_names:
+            stack_list.append(stack_details[col])
+        pt.add_row(stack_list)
+        print(pt)
+    else:
+        err_msg = content["error"]["message"]
+        log(_("Unable to deploy to Heat\n%s\n") % err_msg)
+
+
 def main(args=None):
     if args is None:
         args = sys.argv[1:]
diff --git a/tosca2heat/heat-translator/translator/tests/data/csar_single_instance_wordpress.zip b/tosca2heat/heat-translator/translator/tests/data/csar_single_instance_wordpress.zip
new file mode 100644 (file)
index 0000000..17e655e
Binary files /dev/null and b/tosca2heat/heat-translator/translator/tests/data/csar_single_instance_wordpress.zip differ
diff --git a/tosca2heat/heat-translator/translator/tests/data/csar_wordpress_invalid_import_path.zip b/tosca2heat/heat-translator/translator/tests/data/csar_wordpress_invalid_import_path.zip
new file mode 100644 (file)
index 0000000..9dc6c9a
Binary files /dev/null and b/tosca2heat/heat-translator/translator/tests/data/csar_wordpress_invalid_import_path.zip differ
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_artifact.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_artifact.yaml
new file mode 100644 (file)
index 0000000..7284116
--- /dev/null
@@ -0,0 +1,30 @@
+heat_template_version: 2013-05-23
+
+description: >
+  TOSCA template to test artifact usage
+
+parameters: {}
+resources:
+  customwebserver_create_deploy:
+    type: OS::Heat::SoftwareDeployment
+    properties:
+      config:
+        get_resource: customwebserver_create_config
+      input_values:
+        content:
+          get_file: http://www.mycompany.org/content.tgz
+      server:
+        get_resource: server
+  server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.small
+      image: ubuntu-12.04-software-config-os-init
+      user_data_format: SOFTWARE_CONFIG
+  customwebserver_create_config:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      config:
+        get_file: install.sh
+      group: script
+outputs: {}
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type.yaml
new file mode 100644 (file)
index 0000000..9f722cc
--- /dev/null
@@ -0,0 +1,34 @@
+
+heat_template_version: 2013-05-23
+
+description: >
+  TOSCA template to test custom type with an interface defined on it
+
+parameters:
+  install_path:
+    type: string
+    default: /home/custom/other
+resources:
+  customwebserver_create_deploy:
+    type: OS::Heat::SoftwareDeployment
+    properties:
+      config:
+        get_resource: customwebserver_create_config
+      input_values:
+        path:
+          get_param: install_path
+      server:
+        get_resource: server
+  server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.small
+      image: ubuntu-12.04-software-config-os-init
+      user_data_format: SOFTWARE_CONFIG
+  customwebserver_create_config:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      config:
+        get_file: install.sh
+      group: script
+outputs: {}
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_override.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_override.yaml
new file mode 100644 (file)
index 0000000..24a2893
--- /dev/null
@@ -0,0 +1,34 @@
+heat_template_version: 2013-05-23
+
+description: >
+  TOSCA template to test custom type with an interface defined on it,
+  and an interface overriding the type's one on the template itself
+
+parameters:
+  install_path:
+    type: string
+    default: /home/custom/other
+resources:
+  customwebserver_create_deploy:
+    type: OS::Heat::SoftwareDeployment
+    properties:
+      config:
+        get_resource: customwebserver_create_config
+      input_values:
+        path:
+          get_param: install_path
+      server:
+        get_resource: server
+  server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.small
+      image: ubuntu-12.04-software-config-os-init
+      user_data_format: SOFTWARE_CONFIG
+  customwebserver_create_config:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      config:
+        get_file: install_override.sh
+      group: script
+outputs: {}
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_param_override.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_custom_type_with_param_override.yaml
new file mode 100644 (file)
index 0000000..b166d7c
--- /dev/null
@@ -0,0 +1,34 @@
+heat_template_version: 2013-05-23
+
+description: >
+  TOSCA template to test custom type with an interface defined on it,
+  and an interface overriding the type's one on the template itself
+
+parameters:
+  install_path:
+    type: string
+    default: /home/custom/from/cli
+resources:
+  customwebserver_create_deploy:
+    type: OS::Heat::SoftwareDeployment
+    properties:
+      config:
+        get_resource: customwebserver_create_config
+      input_values:
+        path:
+          get_param: install_path
+      server:
+        get_resource: server
+  server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.small
+      image: ubuntu-12.04-software-config-os-init
+      user_data_format: SOFTWARE_CONFIG
+  customwebserver_create_config:
+    type: OS::Heat::SoftwareConfig
+    properties:
+      config:
+        get_file: install_override.sh
+      group: script
+outputs: {}
\ No newline at end of file
@@ -46,7 +46,8 @@ resources:
       config:
         get_resource: paypal_pizzastore_configure_config
       input_values:
-        github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git
+        github_url:
+          get_param: github_url
         mongodb_ip:
           get_attr:
           - mongo_server
@@ -472,7 +473,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   mongo_server:
@@ -480,7 +480,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   logstash_server:
@@ -488,7 +487,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   elasticsearch_server:
@@ -496,7 +494,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   kibana_server:
@@ -504,7 +501,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
 outputs:
@@ -46,7 +46,8 @@ resources:
       config:
         get_resource: paypal_pizzastore_configure_config
       input_values:
-        github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git
+        github_url:
+          get_param: github_url
         mongodb_ip:
           get_attr:
           - mongo_server
@@ -472,7 +473,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   mongo_server:
@@ -480,7 +480,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   logstash_server:
@@ -488,7 +487,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   elasticsearch_server:
@@ -496,7 +494,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   kibana_server:
@@ -504,7 +501,6 @@ resources:
     properties:
       flavor: m1.large
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
 outputs:
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image.yaml
new file mode 100644 (file)
index 0000000..da8285e
--- /dev/null
@@ -0,0 +1,18 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying a server with custom properties for image, flavor and key_name.
+
+parameters:
+  key_name:
+    type: string
+    default: inputkey
+resources:
+  my_server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      key_name: {get_param: key_name}
+      user_data_format: SOFTWARE_CONFIG
+outputs: {}
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image_params.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_flavor_and_image_params.yaml
new file mode 100644 (file)
index 0000000..679461c
--- /dev/null
@@ -0,0 +1,18 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying a server with custom properties for image, flavor and key_name.
+
+parameters:
+  key_name:
+    type: string
+    default: paramkey
+resources:
+  my_server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      key_name: {get_param: key_name}
+      user_data_format: SOFTWARE_CONFIG
+outputs: {}
@@ -10,6 +10,5 @@ resources:
     properties:
       flavor: m1.medium
       image: rhel-6.5-test-image
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
-outputs: {}
\ No newline at end of file
+outputs: {}
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_hello_world_userkey.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_hello_world_userkey.yaml
new file mode 100644 (file)
index 0000000..e5fadb0
--- /dev/null
@@ -0,0 +1,19 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying a single server with predefined properties.
+
+parameters:
+  key_name:
+    type: string
+    default: userkey
+
+resources:
+  my_server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      key_name: { get_param: key_name }
+      user_data_format: SOFTWARE_CONFIG
+outputs: {}
@@ -16,7 +16,6 @@ resources:
     properties:
       flavor: m1.medium
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   logstash_server:
@@ -24,7 +23,6 @@ resources:
     properties:
       flavor: m1.medium
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   app_collectd_create_config:
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_nfv_sample.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_nfv_sample.yaml
new file mode 100644 (file)
index 0000000..2103d43
--- /dev/null
@@ -0,0 +1,35 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying a single server with predefined properties.
+
+parameters: {}
+resources:
+  VDU1:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      networks:
+      - port: { get_resource: CP1 }
+      user_data_format: SOFTWARE_CONFIG
+  CP1:
+    type: OS::Neutron::Port
+    properties:
+      fixed_ips:
+        - ip_address: '192.168.0.55'
+      network: { get_resource: VL1 }
+  VL1:
+    type: OS::Neutron::Net
+  VL1_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      ip_version: 4
+      allocation_pools:
+      - end: 192.168.0.200
+        start: 192.168.0.50
+      gateway_ip: 192.168.0.1
+      cidr: 192.168.0.0/24
+      network: { get_resource: VL1 }
+outputs: {}
+
@@ -157,7 +157,6 @@ resources:
     properties:
       flavor: m1.medium
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   app_server:
@@ -165,7 +164,6 @@ resources:
     properties:
       flavor: m1.medium
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
 outputs:
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_policies.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_policies.yaml
new file mode 100644 (file)
index 0000000..c7cfa44
--- /dev/null
@@ -0,0 +1,25 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying the nodes based on given policies.
+
+parameters: {}
+
+resources:
+  my_server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      scheduler_hints:
+        group:
+          get_resource: my_compute_placement_policy
+      user_data_format: SOFTWARE_CONFIG
+  my_compute_placement_policy:
+    type: OS::Nova::ServerGroup
+    properties:
+      name: my_compute_placement_policy
+      policies:
+      - affinity
+
+outputs: {}
\ No newline at end of file
@@ -50,7 +50,8 @@ resources:
       config:
         get_resource: mysql_dbms_create_config
       input_values:
-        db_root_password: passw0rd
+        db_root_password:
+          get_param: db_root_pwd
       server:
         get_resource: server
 
@@ -103,10 +104,14 @@ resources:
       config:
         get_resource: mysql_database_configure_config
       input_values:
-        db_name: wordpress
-        db_password: wp_pass
-        db_root_password: passw0rd
-        db_user: wp_user
+        db_name:
+          get_param: db_name
+        db_password:
+          get_param: db_pwd
+        db_root_password:
+          get_param: db_root_pwd
+        db_user:
+          get_param: db_user
       server:
         get_resource: server
     depends_on:
@@ -175,9 +180,12 @@ resources:
       config:
         get_resource: wordpress_configure_config
       input_values:
-        wp_db_name: wordpress
-        wp_db_password: wp_pass
-        wp_db_user: wp_user
+        wp_db_name:
+          get_param: db_name
+        wp_db_password:
+          get_param: db_pwd
+        wp_db_user:
+          get_param: db_user
       server:
         get_resource: server
     depends_on:
@@ -188,7 +196,6 @@ resources:
     properties:
       flavor: m1.xlarge
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
 outputs:
@@ -82,7 +82,8 @@ resources:
       config:
         get_resource: mysql_dbms_configure_config
       input_values:
-        root_password: passw0rd
+        db_root_password:
+          get_param: db_root_pwd
       server:
         get_resource: server
     depends_on:
@@ -101,10 +102,14 @@ resources:
       config:
         get_resource: mysql_database_configure_config
       input_values:
-        db_name: wordpress
-        db_password: wp_pass
-        db_root_password: passw0rd
-        db_user: wp_user
+        db_name:
+          get_param: db_name
+        db_password:
+          get_param: db_pwd
+        db_root_password:
+          get_param: db_root_pwd
+        db_user:
+          get_param: db_user
       server:
         get_resource: server
     depends_on:
@@ -173,9 +178,12 @@ resources:
       config:
         get_resource: wordpress_configure_config
       input_values:
-        wp_db_name: wordpress
-        wp_db_password: wp_pass
-        wp_db_user: wp_user
+        wp_db_name:
+          get_param: db_name
+        wp_db_password:
+          get_param: db_pwd
+        wp_db_user:
+          get_param: db_user
       server:
         get_resource: server
     depends_on:
@@ -186,7 +194,6 @@ resources:
     properties:
       flavor: m1.xlarge
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
 outputs:
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server_without_tosca_os_version.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/hot_single_server_without_tosca_os_version.yaml
new file mode 100644 (file)
index 0000000..d2828cf
--- /dev/null
@@ -0,0 +1,17 @@
+heat_template_version: 2013-05-23
+
+description: >
+  TOSCA simple profile that just defines a single compute instance and selects a
+  flavor and host Operating System for the Compute node. Note, this is just a test
+  template showing Compute without optional 'version' property of OS capability.
+  In general, you should have version to narrow down your image selection.
+
+parameters: {}
+resources:
+  my_server:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      user_data_format: SOFTWARE_CONFIG
+outputs: {}
@@ -26,7 +26,6 @@ resources:
     properties:
       flavor: m1.medium
       image: ubuntu-software-config-os-init
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
 
   web_server_create_deploy:
@@ -67,7 +66,8 @@ resources:
       config:
         get_resource: web_app_create_config
       input_values:
-        context_root: my_web_app
+        context_root:
+          get_param: context_root
       server:
         get_resource: server
     depends_on:
diff --git a/tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_custom_network_nodes.yaml b/tosca2heat/heat-translator/translator/tests/data/hot_output/network/hot_custom_network_nodes.yaml
new file mode 100644 (file)
index 0000000..556dcf4
--- /dev/null
@@ -0,0 +1,33 @@
+heat_template_version: 2013-05-23
+
+description: >
+  Template for deploying a single server with predefined properties.
+
+parameters: {}
+resources:
+  VDU1:
+    type: OS::Nova::Server
+    properties:
+      flavor: m1.medium
+      image: rhel-6.5-test-image
+      networks:
+      - port: { get_resource: CP1 }
+      user_data_format: SOFTWARE_CONFIG
+  CP1:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_resource: VL1 }
+  VL1:
+    type: OS::Neutron::Net
+  VL1_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      ip_version: 4
+      allocation_pools:
+      - end: 192.168.0.200
+        start: 192.168.0.50
+      gateway_ip: 192.168.0.1
+      cidr: 192.168.0.0/24
+      network: { get_resource: VL1 }
+outputs: {}
+
@@ -27,7 +27,6 @@ resources:
     properties:
       flavor: m1.small
       image: cirros-0.3.2-x86_64-uec
-      key_name: userkey
       networks:
       - port: { get_resource: my_port }
       user_data_format: SOFTWARE_CONFIG
@@ -37,7 +36,6 @@ resources:
     properties:
       flavor: m1.small
       image: cirros-0.3.2-x86_64-uec
-      key_name: userkey
       networks:
       - port: { get_resource: my_port2 }
       user_data_format: SOFTWARE_CONFIG
@@ -38,7 +38,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -57,7 +56,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -38,7 +38,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -57,7 +56,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -42,7 +42,6 @@ resources:
     properties:
       flavor: m1.small
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -61,7 +60,6 @@ resources:
     properties:
       flavor: m1.small
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -42,7 +42,6 @@ resources:
     properties:
       flavor: m1.small
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -61,7 +60,6 @@ resources:
     properties:
       flavor: m1.small
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -33,7 +33,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -61,7 +60,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage2
@@ -33,7 +33,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage
@@ -61,7 +60,6 @@ resources:
     properties:
       flavor: m1.medium
       image: fedora-amd64-heat-config
-      key_name: userkey
       user_data_format: SOFTWARE_CONFIG
     depends_on:
     - my_storage2
diff --git a/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_defs.yaml b/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_defs.yaml
new file mode 100644 (file)
index 0000000..552ae07
--- /dev/null
@@ -0,0 +1,41 @@
+node_types:
+  tosca.nodes.vendor.VDU:
+    derived_from: tosca.nodes.Compute
+    capabilities:
+      virtualbinding:
+        type: tosca.capabilities.vendor.VendorBindable
+
+  tosca.nodes.vendor.CP:
+    derived_from: tosca.nodes.network.Port
+    requirements:
+      - virtualLink:
+          capability: tosca.capabilities.VendorLinkable
+          relationship: tosca.relationships.vendor.VendorLinksTo
+          node: tosca.nodes.vendor.VL
+      - virtualBinding:
+          capability: tosca.capabilities.vendor.VendorBindable
+          node: tosca.nodes.vendor.VDU
+          relationship: tosca.relationships.vendor.VendorBindsTo
+
+  tosca.nodes.vendor.VL:
+    derived_from: tosca.nodes.network.Network
+    capabilities:
+      virtual_linkable:
+        type: tosca.capabilities.vendor.VendorLinkable
+
+relationship_types:
+  tosca.relationships.vendor.VendorLinksTo:
+    derived_from: tosca.relationships.network.LinksTo
+    valid_target_types: [ tosca.capabilities.vendor.VendorLinkable ]
+
+  tosca.relationships.vendor.VendorBindsTo:
+    derived_from: tosca.relationships.network.BindsTo
+    valid_target_types: [ tosca.capabilities.vendor.VendorBindable ]
+
+capability_types:
+  tosca.capabilities.vendor.VendorLinkable:
+    derived_from: tosca.capabilities.network.Linkable
+
+  tosca.capabilities.vendor.VendorBindable:
+    derived_from: tosca.capabilities.network.Bindable
+
diff --git a/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_imports.yaml b/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_imports.yaml
new file mode 100644 (file)
index 0000000..ea473b1
--- /dev/null
@@ -0,0 +1,41 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with predefined properties.
+
+imports:
+  - test_tosca_custom_network_nodes_defs.yaml
+
+topology_template:
+  node_templates:
+
+    VDU1:
+      type: tosca.nodes.vendor.VDU
+      capabilities:
+        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
+    CP1:
+      type: tosca.nodes.vendor.CP
+      requirements:
+        - virtualLink:
+            node: VL1
+        - virtualBinding:
+            node: VDU1
+
+    VL1:
+      type: tosca.nodes.vendor.VL
+      properties:
+        cidr: '192.168.0.0/24'
+        start_ip: '192.168.0.50'
+        end_ip: '192.168.0.200'
+        gateway_ip: '192.168.0.1'
diff --git a/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_inline.yaml b/tosca2heat/heat-translator/translator/tests/data/network/test_tosca_custom_network_nodes_inline.yaml
new file mode 100644 (file)
index 0000000..509aab4
--- /dev/null
@@ -0,0 +1,82 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with predefined properties.
+
+
+node_types:
+  tosca.nodes.vendor.VDU:
+    derived_from: tosca.nodes.Compute
+    capabilities:
+      virtualbinding:
+        type: tosca.capabilities.vendor.VendorBindable
+
+  tosca.nodes.vendor.CP:
+    derived_from: tosca.nodes.network.Port
+    requirements:
+      - virtualLink:
+          capability: tosca.capabilities.VendorLinkable
+          relationship: tosca.relationships.vendor.VendorLinksTo
+          node: tosca.nodes.vendor.VL
+      - virtualBinding:
+          capability: tosca.capabilities.vendor.VendorBindable
+          node: tosca.nodes.vendor.VDU
+          relationship: tosca.relationships.vendor.VendorBindsTo
+
+  tosca.nodes.vendor.VL:
+    derived_from: tosca.nodes.network.Network
+    capabilities:
+      virtual_linkable:
+        type: tosca.capabilities.vendor.VendorLinkable
+
+relationship_types:
+  tosca.relationships.vendor.VendorLinksTo:
+    derived_from: tosca.relationships.network.LinksTo
+    valid_target_types: [ tosca.capabilities.vendor.VendorLinkable ]
+
+  tosca.relationships.vendor.VendorBindsTo:
+    derived_from: tosca.relationships.network.BindsTo
+    valid_target_types: [ tosca.capabilities.vendor.VendorBindable ]
+
+capability_types:
+  tosca.capabilities.vendor.VendorLinkable:
+    derived_from: tosca.capabilities.network.Linkable
+
+  tosca.capabilities.vendor.VendorBindable:
+    derived_from: tosca.capabilities.network.Bindable
+
+topology_template:
+  node_templates:
+
+    VDU1:
+      type: tosca.nodes.vendor.VDU
+      capabilities:
+        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
+    CP1:
+      type: tosca.nodes.vendor.CP
+      requirements:
+        - virtualLink:
+            node: VL1
+            relationship: tosca.relationships.vendor.VendorLinksTo
+        - virtualBinding:
+            node: VDU1
+            relationship: tosca.relationships.vendor.VendorBindsTo
+
+    VL1:
+      type: tosca.nodes.vendor.VL
+      properties:
+        cidr: '192.168.0.0/24'
+        start_ip: '192.168.0.50'
+        end_ip: '192.168.0.200'
+        gateway_ip: '192.168.0.1'
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_single_server_without_optional_version_prop.yaml b/tosca2heat/heat-translator/translator/tests/data/test_single_server_without_optional_version_prop.yaml
new file mode 100644 (file)
index 0000000..8cf5255
--- /dev/null
@@ -0,0 +1,24 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA simple profile that just defines a single compute instance and selects a
+  flavor and host Operating System for the Compute node. Note, this is just a test
+  template showing Compute without optional 'version' property of OS capability. In
+  general, you should have version to narrow down your image selection.
+
+topology_template:
+
+  node_templates:
+    my_server:
+      type: Compute
+      capabilities:
+        host:
+          properties:
+            disk_size: 40 GB
+            num_cpus: 2
+            mem_size: 4 MB
+        os:
+          properties:
+            architecture: x86_64
+            type: Linux
+            distribution: RHEL
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_tosca_artifact.yaml b/tosca2heat/heat-translator/translator/tests/data/test_tosca_artifact.yaml
new file mode 100644 (file)
index 0000000..be2caca
--- /dev/null
@@ -0,0 +1,40 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA template to test artifact usage
+
+node_types:
+  tosca.nodes.CustomWebServer:
+    derived_from: tosca.nodes.WebServer
+    artifacts:
+      web_content:
+        file: http://www.mycompany.org/content.tgz
+        type: tosca.artifacts.File
+    interfaces:
+      Standard:
+        create:
+          inputs:
+            content: { get_artifact: [ SELF, web_content ] }
+          implementation: install.sh
+
+topology_template:
+  node_templates:
+
+    customwebserver:
+      type: tosca.nodes.CustomWebServer
+      requirements:
+        - host: server
+
+    server:
+      type: tosca.nodes.Compute
+      capabilities:
+        host:
+         properties:
+           num_cpus: 1
+           mem_size: 1 GB
+        os:
+          properties:
+            type: Linux
+            distribution: Ubuntu
+            version: 12.04
+            architecture: x86_64
+
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type.yaml b/tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type.yaml
new file mode 100644 (file)
index 0000000..c427ef0
--- /dev/null
@@ -0,0 +1,47 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA template to test custom type with an interface defined on it
+
+node_types:
+  tosca.nodes.CustomWebServer:
+    derived_from: tosca.nodes.WebServer
+    properties:
+      custom_install_path:
+        type: string
+        default: /home/custom/custom
+    interfaces:
+      Standard:
+        create:
+          implementation: install.sh
+          inputs:
+            path: { get_property: [ SELF, custom_install_path ] }
+
+topology_template:
+  inputs:
+    install_path:
+      type: string
+      default: /home/custom/other
+
+  node_templates:
+
+    customwebserver:
+      type: tosca.nodes.CustomWebServer
+      requirements:
+        - host: server
+      properties:
+        custom_install_path : { get_input: install_path }
+
+    server:
+      type: tosca.nodes.Compute
+      capabilities:
+        host:
+         properties:
+           num_cpus: 1
+           mem_size: 1 GB
+        os:
+          properties:
+            type: Linux
+            distribution: Ubuntu
+            version: 12.04
+            architecture: x86_64
+
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type_with_override.yaml b/tosca2heat/heat-translator/translator/tests/data/test_tosca_custom_type_with_override.yaml
new file mode 100644 (file)
index 0000000..d398c63
--- /dev/null
@@ -0,0 +1,45 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA template to test custom type with an interface defined on it,
+  and an interface overriding the type's one on the template itself
+
+node_types:
+  tosca.nodes.CustomWebServer:
+    derived_from: tosca.nodes.WebServer
+    interfaces:
+      Standard:
+        create:
+          implementation: install.sh
+
+topology_template:
+  inputs:
+    install_path:
+      type: string
+      default: /home/custom/other
+
+  node_templates:
+    customwebserver:
+      type: tosca.nodes.CustomWebServer
+      requirements:
+        - host: server
+      interfaces:
+        Standard:
+          create:
+            implementation: install_override.sh
+            inputs:
+              path: { get_input: install_path }
+
+    server:
+      type: tosca.nodes.Compute
+      capabilities:
+        host:
+         properties:
+           num_cpus: 1
+           mem_size: 1 GB
+        os:
+          properties:
+            type: Linux
+            distribution: Ubuntu
+            version: 12.04
+            architecture: x86_64
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_tosca_flavor_and_image.yaml b/tosca2heat/heat-translator/translator/tests/data/test_tosca_flavor_and_image.yaml
new file mode 100644 (file)
index 0000000..3247589
--- /dev/null
@@ -0,0 +1,29 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a server with custom properties for image, flavor and key_name.
+
+node_types:
+  tosca.nodes.nfv.VDU:
+    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.nfv.VDU
+      properties:
+        flavor: m1.medium
+        image: rhel-6.5-test-image
+        key_name:
+          get_input: key_name
diff --git a/tosca2heat/heat-translator/translator/tests/data/test_tosca_nfv_sample.yaml b/tosca2heat/heat-translator/translator/tests/data/test_tosca_nfv_sample.yaml
new file mode 100644 (file)
index 0000000..1112234
--- /dev/null
@@ -0,0 +1,43 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+description: Template for deploying a single server with predefined properties.
+
+topology_template:
+  node_templates:
+
+    VDU1:
+      type: tosca.nodes.nfv.VDU
+      capabilities:
+        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
+    CP1:
+      type: tosca.nodes.nfv.CP
+      properties:
+        ip_address: 192.168.0.55
+      requirements:
+        - virtualLink:
+            node: VL1
+#           relationship: tosca.relationships.nfv.VirtualLinksTo
+        - virtualBinding:
+            node: VDU1
+            relationship: tosca.relationships.nfv.VirtualBindsTo
+
+    VL1:
+      type: tosca.nodes.nfv.VL
+      properties:
+        vendor: ACME
+        cidr: '192.168.0.0/24'
+        start_ip: '192.168.0.50'
+        end_ip: '192.168.0.200'
+        gateway_ip: '192.168.0.1'
@@ -51,7 +51,7 @@ topology_template:
            configure:
              implementation: nodejs/config.sh
              inputs:
-               github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git
+               github_url:  { get_property: [ SELF, github_url ] }
                mongodb_ip: { get_attribute: [mongo_server, private_address] }
            start: nodejs/start.sh
     nodejs:
diff --git a/tosca2heat/heat-translator/translator/tests/data/tosca_policies.yaml b/tosca2heat/heat-translator/translator/tests/data/tosca_policies.yaml
new file mode 100644 (file)
index 0000000..26417d3
--- /dev/null
@@ -0,0 +1,28 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying the nodes based on given policies.
+
+topology_template:
+  node_templates:
+    my_server:
+      type: tosca.nodes.Compute
+      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
+  policies:
+     - my_compute_placement_policy:
+         type: tosca.policies.Placement
+         description: Apply my placement policy to my application’s servers
+         targets: [ my_server ]
@@ -46,9 +46,9 @@ topology_template:
           configure:
             implementation: wordpress/wordpress_configure.sh
             inputs:
-              wp_db_name: wordpress
-              wp_db_user: wp_user
-              wp_db_password: wp_pass
+               wp_db_name: { get_property: [ mysql_database, name ] }
+               wp_db_user: { get_property: [ mysql_database, user ] }
+               wp_db_password: { get_property: [ mysql_database, password ] }
 
     mysql_database:
       type: tosca.nodes.Database
@@ -68,10 +68,10 @@ topology_template:
           configure:
             implementation: mysql/mysql_database_configure.sh
             inputs:
-              db_name: wordpress
-              db_user: wp_user
-              db_password: wp_pass
-              db_root_password: passw0rd
+                db_name: { get_property: [ SELF, name ] }
+                db_user: { get_property: [ SELF, user ] }
+                db_password: { get_property: [ SELF, password ] }
+                db_root_password: { get_property: [ mysql_dbms, root_password ] }
     mysql_dbms:
       type: tosca.nodes.DBMS
       properties:
@@ -84,7 +84,7 @@ topology_template:
           create:
             implementation: mysql/mysql_dbms_install.sh
             inputs:
-              db_root_password: passw0rd
+              db_root_password: { get_property: [ SELF, root_password ] }
           start: mysql/mysql_dbms_start.sh
           configure:
             implementation: mysql/mysql_dbms_configure.sh
@@ -51,9 +51,9 @@ topology_template:
           configure:
             implementation: wordpress/wordpress_configure.sh
             inputs:
-              wp_db_name: wordpress
-              wp_db_user: wp_user
-              wp_db_password: wp_pass
+              wp_db_name: { get_input: db_name }
+              wp_db_user: { get_input: db_user }
+              wp_db_password: { get_input: db_pwd }
 
     mysql_database:
       type: tosca.nodes.Database
@@ -73,10 +73,10 @@ topology_template:
           configure:
             implementation: mysql/mysql_database_configure.sh
             inputs:
-              db_name: wordpress
-              db_user: wp_user
-              db_password: wp_pass
-              db_root_password: passw0rd
+              db_name: { get_input: db_name }
+              db_user: { get_input: db_user }
+              db_password: { get_input: db_pwd }
+              db_root_password: { get_input: db_root_pwd }
     mysql_dbms:
       type: tosca.nodes.DBMS
       properties:
@@ -46,9 +46,9 @@ topology_template:
           configure:
             implementation: wordpress/wordpress_configure.sh
             inputs:
-              wp_db_name: wordpress
-              wp_db_user: wp_user
-              wp_db_password: wp_pass
+               wp_db_name: { get_property: [ mysql_database, name ] }
+               wp_db_user: { get_property: [ mysql_database, user ] }
+               wp_db_password: { get_property: [ mysql_database, password ] }
 
     mysql_database:
       type: tosca.nodes.Database
@@ -68,10 +68,10 @@ topology_template:
           configure:
             implementation: mysql/mysql_database_configure.sh
             inputs:
-              db_name: wordpress
-              db_user: wp_user
-              db_password: wp_pass
-              db_root_password: passw0rd
+                db_name: { get_property: [ SELF, name ] }
+                db_user: { get_property: [ SELF, user ] }
+                db_password: { get_property: [ SELF, password ] }
+                db_root_password: { get_property: [ mysql_dbms, root_password ] }
     mysql_dbms:
       type: tosca.nodes.DBMS
       properties:
@@ -84,7 +84,7 @@ topology_template:
           create:
             implementation: mysql/mysql_dbms_install.sh
             inputs:
-              db_root_password: passw0rd
+              db_root_password: { get_property: [ SELF, root_password ] }
           start: mysql/mysql_dbms_start.sh
           configure:
             implementation: mysql/mysql_dbms_configure.sh
@@ -29,4 +29,4 @@ topology_template:
   outputs:
     private_ip:
       description: The private IP address of the deployed server instance.
-      value: { get_attribute: [my_server, private_address] }
\ No newline at end of file
+      value: { get_attribute: [my_server, private_address] }
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import ast
+import json
 import os
 import shutil
 import tempfile
 
+from mock import patch
 from toscaparser.common import exception
 from toscaparser.utils.gettextutils import _
 import translator.shell as shell
@@ -114,3 +117,75 @@ class ShellTest(TestCase):
                 shutil.rmtree(temp_dir)
                 self.assertTrue(temp_dir is None or
                                 not os.path.exists(temp_dir))
+
+    @patch('uuid.uuid4')
+    @patch('translator.common.utils.check_for_env_variables')
+    @patch('requests.post')
+    @patch('translator.common.utils.get_url_for')
+    @patch('translator.common.utils.get_token_id')
+    @patch('os.getenv')
+    @patch('translator.hot.tosca.tosca_compute.'
+           'ToscaCompute._create_nova_flavor_dict')
+    def test_template_deploy_with_credentials(self, mock_flavor_dict,
+                                              mock_os_getenv,
+                                              mock_token,
+                                              mock_url, mock_post,
+                                              mock_env,
+                                              mock_uuid):
+        mock_uuid.return_value = 'abcXXX-abcXXX'
+        mock_env.return_value = True
+        mock_flavor_dict.return_value = {
+            'm1.medium': {'mem_size': 4096, 'disk_size': 40, 'num_cpus': 2}
+        }
+        mock_url.return_value = 'http://abc.com'
+        mock_token.return_value = 'mock_token'
+        mock_os_getenv.side_effect = ['demo', 'demo',
+                                      'demo', 'http://www.abc.com']
+        try:
+            data = {
+                'stack_name': 'heat_abcXXX',
+                'parameters': {},
+                'template': {
+                    'outputs': {},
+                    'heat_template_version': '2013-05-23',
+                    'description': 'Template for deploying a single server '
+                                   'with predefined properties.\n',
+                    'parameters': {},
+                    'resources': {
+                        'my_server': {
+                            'type': 'OS::Nova::Server',
+                            'properties': {
+                                'flavor': 'm1.medium',
+                                'user_data_format': 'SOFTWARE_CONFIG',
+                                'image': 'rhel-6.5-test-image'
+                            }
+                        }
+                    }
+                }
+            }
+
+            mock_heat_res = {
+                "stack": {
+                    "id": 1234
+                }
+            }
+            headers = {
+                'Content-Type': 'application/json',
+                'X-Auth-Token': 'mock_token'
+            }
+
+            class mock_response(object):
+                def __init__(self, status_code, _content):
+                    self.status_code = status_code
+                    self._content = _content
+
+            mock_response_obj = mock_response(201, json.dumps(mock_heat_res))
+            mock_post.return_value = mock_response_obj
+            shell.main([self.template_file, self.template_type,
+                        "--deploy"])
+            args, kwargs = mock_post.call_args
+            self.assertEqual(args[0], 'http://abc.com/stacks')
+            self.assertEqual(ast.literal_eval(kwargs['data']), data)
+            self.assertEqual(kwargs['headers'], headers)
+        except Exception:
+            self.fail(self.failure_msg)
old mode 100755 (executable)
new mode 100644 (file)
similarity index 93%
rename from tosca2heat/heat-translator-0.3.0/translator/tests/test_template.py
rename to tosca2heat/heat-translator/translator/tests/test_template.py
index 7d4f441..7cced36
@@ -27,15 +27,15 @@ class ToscaMongoNodejsTest(TestCase):
     tosca = ToscaTemplate(tosca_tpl, parsed_params)
 
     def test_relationship_def(self):
-        expected_relationship = ['tosca.relationships.HostedOn']
-        expected_capabilities_names = ['node']
+        expected_relationship = 'tosca.relationships.HostedOn'
+        expected_capabilities_names = 'node'
         for tpl in self.tosca.nodetemplates:
             if tpl.name == 'nodejs':
                 def_keys = tpl.type_definition.relationship.keys()
-                self.assertEqual(
+                self.assertIn(
                     expected_relationship,
                     sorted([x.type for x in def_keys]))
-                self.assertEqual(
+                self.assertIn(
                     expected_capabilities_names,
                     sorted([x.capability_name for x in def_keys]))
 
@@ -484,7 +484,8 @@ class ToscaHotTranslationTest(TestCase):
             ValidationError,
             TranslationUtils.compare_tosca_translation_with_hot,
             tosca_file, hot_file, params)
-        expected_msg = _('Import "Definitions/wordpress.yaml" is not valid.')
+        expected_msg = _('Import '
+                         '"Invalid_import_path/wordpress.yaml" is not valid.')
         ExceptionCollector.assertExceptionMessage(ImportError, expected_msg)
 
     def test_translate_csar_wordpress_invalid_script_url(self):
@@ -501,3 +502,132 @@ class ToscaHotTranslationTest(TestCase):
                          'heat-translator/master/translator/tests/data/'
                          'custom_types/wordpress1.yaml" cannot be accessed.')
         ExceptionCollector.assertExceptionMessage(URLException, expected_msg)
+
+    def test_hot_translate_flavor_image(self):
+        tosca_file = '../tests/data/test_tosca_flavor_and_image.yaml'
+        hot_file = '../tests/data/hot_output/hot_flavor_and_image.yaml'
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   {})
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_flavor_image_params(self):
+        tosca_file = '../tests/data/test_tosca_flavor_and_image.yaml'
+        hot_file = '../tests/data/hot_output/hot_flavor_and_image_params.yaml'
+        params = {'key_name': 'paramkey'}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_custom_type(self):
+        tosca_file = '../tests/data/test_tosca_custom_type.yaml'
+        hot_file = '../tests/data/hot_output/' \
+            'hot_custom_type.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_custom_type_with_override(self):
+        tosca_file = '../tests/data/test_tosca_custom_type_with_override.yaml'
+        hot_file = '../tests/data/hot_output/' \
+            'hot_custom_type_with_override.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_custom_type_with_param_override(self):
+        tosca_file = '../tests/data/test_tosca_custom_type_with_override.yaml'
+        hot_file = '../tests/data/hot_output/' \
+            'hot_custom_type_with_param_override.yaml'
+        params = {'install_path': '/home/custom/from/cli'}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_artifact(self):
+        tosca_file = '../tests/data/test_tosca_artifact.yaml'
+        hot_file = '../tests/data/hot_output/' \
+            'hot_artifact.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_without_tosca_os_version(self):
+        tosca_file = '../tests/data/' \
+            'test_single_server_without_optional_version_prop.yaml'
+        hot_file = '../tests/data/hot_output/' \
+            'hot_single_server_without_tosca_os_version.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_helloworld_with_userkey(self):
+        tosca_file = '../tests/data/tosca_helloworld.yaml'
+        hot_file = '../tests/data/hot_output/hot_hello_world_userkey.yaml'
+        params = {'key_name': 'userkey'}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_custom_networks_nodes_inline(self):
+        tosca_file = '../tests/data/network/' \
+                     'test_tosca_custom_network_nodes_inline.yaml'
+        hot_file = '../tests/data/hot_output/network/' \
+                   'hot_custom_network_nodes.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_custom_networks_nodes_imports(self):
+        tosca_file = '../tests/data/network/' \
+                     'test_tosca_custom_network_nodes_imports.yaml'
+        hot_file = '../tests/data/hot_output/network/' \
+                   'hot_custom_network_nodes.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_nfv_sample(self):
+        tosca_file = '../tests/data/test_tosca_nfv_sample.yaml'
+        hot_file = '../tests/data/hot_output/hot_nfv_sample.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
+
+    def test_hot_translate_policy(self):
+        tosca_file = '../tests/data/tosca_policies.yaml'
+        hot_file = '../tests/data/hot_output/hot_policies.yaml'
+        params = {}
+        diff = TranslationUtils.compare_tosca_translation_with_hot(tosca_file,
+                                                                   hot_file,
+                                                                   params)
+        self.assertEqual({}, diff, '<difference> : ' +
+                         json.dumps(diff, indent=4, separators=(', ', ': ')))
@@ -168,7 +168,7 @@ class CommonUtilsTest(TestCase):
             self.cmpUtils.diff_dicts(expected, provided))
 
     def test_yamlutils_get_dict_missing_file(self):
-        self.assertEqual(None, self.yamlUtils.get_dict('./no_file.yaml'))
+        self.assertIsNone(self.yamlUtils.get_dict('./no_file.yaml'))
 
     def test_yamlutils_get_dict(self):
         yaml_file = os.path.join(
@@ -195,10 +195,8 @@ class CommonUtilsTest(TestCase):
         yaml_file2 = os.path.join(
             os.path.dirname(os.path.abspath(__file__)),
             '../tests/data/custom_types/collectd.yaml')
-        self.assertEqual(True,
-                         self.yamlUtils.compare_yamls(yaml_file1, yaml_file1))
-        self.assertEqual(False,
-                         self.yamlUtils.compare_yamls(yaml_file1, yaml_file2))
+        self.assertTrue(self.yamlUtils.compare_yamls(yaml_file1, yaml_file1))
+        self.assertFalse(self.yamlUtils.compare_yamls(yaml_file1, yaml_file2))
 
     def test_yamlutils_compare_yaml_dict(self):
         yaml_file1 = os.path.join(
@@ -221,8 +219,7 @@ class CommonUtilsTest(TestCase):
                   'relationship': 'tosca.relationships.ConnectsTo'}}]}}}
         self.assertEqual({}, self.cmpUtils.diff_dicts(
             self.yamlUtils.get_dict(yaml_file1), dict))
-        self.assertEqual(False,
-                         self.yamlUtils.compare_yaml_dict(yaml_file2, dict))
+        self.assertFalse(self.yamlUtils.compare_yaml_dict(yaml_file2, dict))
 
     def test_assert_value_is_num(self):
         value = 1
diff --git a/tosca2heat/tosca-parser-0.3.0/.coveragerc b/tosca2heat/tosca-parser-0.3.0/.coveragerc
deleted file mode 100644 (file)
index 3309d46..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[run]
-branch = True
-source = toscaparser
-omit = toscaparser/openstack/*
-
-[report]
-ignore_errors = True
diff --git a/tosca2heat/tosca-parser-0.3.0/.mailmap b/tosca2heat/tosca-parser-0.3.0/.mailmap
deleted file mode 100644 (file)
index cc92f17..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Format is:
-# <preferred e-mail> <other e-mail 1>
-# <preferred e-mail> <other e-mail 2>
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser-0.3.0/.testr.conf b/tosca2heat/tosca-parser-0.3.0/.testr.conf
deleted file mode 100644 (file)
index fb62267..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
-             OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
-             OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
-             ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser-0.3.0/AUTHORS b/tosca2heat/tosca-parser-0.3.0/AUTHORS
deleted file mode 100644 (file)
index 1f9b09b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-Andrew F. Ly <afly@us.ibm.com>
-Anjali <a.naladala1@tcs.com>
-Atsushi SAKAI <sakaia@jp.fujitsu.com>
-Ben Martin <blmartin@us.ibm.com>
-Bill Huber <wbhuber@us.ibm.com>
-Brad Topol <btopol@us.ibm.com>
-Christian Berendt <berendt@b1-systems.de>
-Dharmesh Bhakta <bhakta@us.ibm.com>
-Dimitri Mazmanov <dimitri.mazmanov@ericsson.com>
-FeihuJiang <jiangfeihu@huawei.com>
-Haiyang DING <dinghaiyang@huawei.com>
-Idan Moyal <idan@gigaspaces.com>
-Jeff Feng <jianhua@us.ibm.com>
-Jeremy Stanley <fungi@yuggoth.org>
-Kanagaraj Manickam <kanagaraj.manickam@hp.com>
-Longgeek <longgeek@thstack.com>
-Madhurya <madhurya.jesu@tcs.com>
-Meena <meena.ventrapati@tcs.com>
-Michael Brewer <mjbrewer@us.ibm.com>
-Michael Sambol <sambol@us.ibm.com>
-Monty Taylor <mordred@inaugust.com>
-Oleksii Chuprykov <ochuprykov@mirantis.com>
-Rohan Shah <ryshah@us.ibm.com>
-Sahdev Zala <spzala@us.ibm.com>
-Serg Melikyan <smelikyan@mirantis.com>
-Sergey Lukjanov <slukjanov@mirantis.com>
-Simeon Monov <sdmonov@us.ibm.com>
-Steve Martinelli <stevemar@ca.ibm.com>
-Ton Ngo <ton@us.ibm.com>
-Vahid Hashemian <vahidhashemian@us.ibm.com>
-Victor HU <huruifeng@huawei.com>
-Yaoguo Jiang <jiangyaoguo@huawei.com>
-Zach Sais <zsais@us.ibm.com>
-Zachary Sais <zsais@us.ibm.com>
-ddaskal <ddaskal@us.ibm.com>
-huruifeng <huruifeng@huawei.com>
-jiangyaoguo <jiangyaoguo@gmail.com>
-narengan <narengan@us.ibm.com>
-spzala <spzala@us.ibm.com>
-srinivas_tadepalli <srinivas.tadepalli@tcs.com>
-tonanhngo <ton@us.ibm.com>
diff --git a/tosca2heat/tosca-parser-0.3.0/ChangeLog b/tosca2heat/tosca-parser-0.3.0/ChangeLog
deleted file mode 100644 (file)
index 67c4ba6..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-CHANGES
-=======
-
-0.3.0
------
-
-* Add checks in shell for optional keynames in the template
-* Add full stack trace for parser errors
-* Update documentation
-* Fix issues with CSAR error handling
-* Fix an incorrect template
-* Fix a broken test
-* Add expected path for built in template
-* Update definition for public endpoint
-* Update PortSpec definition per latest spec
-* Fix more unhandled errors for full validation
-* Update requirements
-* Fix missing import with new test
-* Fix an error message format
-* Update error message to a uniform format
-* Fix an issue with handling invalid section names
-* Create an initial test coverage for shell entry point
-* Modify test case for broader coverage
-* Full validation of TOSCA templates
-* Create shell entry point
-* Update trove classifier
-* Support .zip and .csar extension for CSAR files
-* Update the endpoint admin capability definition
-* Fix and test the validation of template file
-* Fix a bug where the temp folder is not always removed
-* Fix error message for invalid CSAR URLs
-* Remove one line subject at top of file since its not necessary and update formatting for consistency
-* Support nested type definitions using imports
-
-0.2.0
------
-
-* Fix backward compatibility issue
-* Add validation of external resources for CSAR archives
-* Update CSAR url to its github url
-* Create CLI test utility
-* Add CSAR processing support
-* Allow special keywords in TOSCA template
-* Add documentation for parser architecture
-* Add CSAR decompression support
-* Fix translation issue with interface inputs and functions
-* TOSCA imports implementation single-line and multi-line grammar
-* Support extracting the main template from a CSAR archive
-* Restructured node template testcases in file test_toscatplvalidation.py
-* Change ignore-errors to ignore_errors
-* Update links for URL referenced templates
-* Added PolicyType definitions for TOSCA
-* Remove unused yaml files
-* Change the entity type module name for consistency
-* Extract CSAR description metadata from the main template
-* Handle URLs for input templates and imports
-* Add CSAR validation and metadata extraction
-* Added occurrences of requirements validation
-* Fix property inheritance for node templates
-
-0.1.0
------
-
-* Change i18n references
-* Update TOX
-* Update setup config file
-* Fix coverage file with new repo
-* Create README
-* Add init file for toscaparser
-* Update documentation
-* Redefine respository structure
-* Remove translator specific code
-* Update gitreview file
-* MemoryUnit Incorrectly normalizes to uppercase
-* Implement SoftwareComponent and WebApplication normative types
-* Validation of TOSCA version
-* scalar-unit data type support as template input parameters
-* Corrected checking required properties of OS capabilities in UT
-* Validation for TOSCA second to below levels in template
-* Fix two typos on heat-translator documentation
-* Modified to get closest flavor based on minimal/no inputs
-* Set property to be required by default
-* Update TOSCA artifacts type
-* Separate implementation of custom types and base types
-* supporting short versions of requirements
-* Add full support for PortDef data type
-* Update network examples to the spec (1)
-* Update TOSCA wordpress custom definition
-* Update the 4th and 5th block storage examples (1)
-* Add missing storage examples from the spec
-* Update the 6th block storage example from the spec (1)
-* Remove the circular dependency in network examples
-* Update the first block storage example to the spec (1)
-* Update object store definition and example
-* Sync single server example with latest spec
-* Sync network examples with the spec
-* Remove py26 env
-* Fix translation of block storage
-* Updated from global requirements
-* Add a unit test for nodejs-mongodb template translation
-* Update TOSCA version per spec
-* Prepare ELK TOSCA Template for Translation into HOT (6)
-* Add app in the nodejs mongodb template
-* Update TOSCA credential datatype
-* Update TOSCA relationship inheritance
-* Update TOSCA translator installation doc
-* Update TOSCA relationship valid targets
-* Document usage of translator with OSC
-* Added directory structure in README.rst
-* Add a unit test for ELK translation
-* Annotate TOSCA scripts
-* Prepare ELK TOSCA Template for Translation into HOT (5)
-* Updated from global requirements
-* Implement tosca.scalar-unit
-* Update TOSCA base type definition file with version
-* Prepare ELK TOSCA Template for Translation into HOT (4)
-* Added translation to the tosca network module
-* Added translation in dataentity module
-* Fix typos in ELK CSAR readme file
-* Updated from global requirements
-* Adding unit test coverage for the validate method
-* Implement artifact type definition
-* Add support for parameters to translate template
-* Added the missing testcases for Tosca translator
-* Add handler for ConnectsTo relationship
-* Prepare ELK TOSCA Template for Translation into HOT (3)
-* Update TOSCA ELK scripts
-* Adding an empty template test for simple_parse()
-* Add unit testcases for toscalib_elements_constraints.py
-* Fixed spelling mistake
-* Fixing an error message which was not translated
-* Add the ability to set output file
-* Create an OSC plugin for heat-translator
-* Resolve interfaces by symbolic name not by type
-* TOSCA: Database and DBMS node properties update
-* TOSCA: fix indentation in elk CSAR
-* TOSCA: create csar for monitoring use case
-* Installer scripts should not run simultaneously on the same server
-* Prepare ELK TOSCA Template for Translation into HOT (2)
-* TOSCA: Update memory size per spec changes
-* Adding test coverage for HotParameter
-* Fix host server assignment for resources with multi-node dependency
-* Heat-Translator: Update README with new IRC Channel
-* Added a unit test to cover diff_dicts in utils.py
-* Fix installation package name
-* Prepare ELK TOSCA Template for Translation into HOT
-* TOSCA: interfaces for relationship templates
-* TOSCA: fix Python34 UnicodeDecodeError
-* Pick up new plugins for ELK
-* Heat translator plugins for new TOSCA custom types
-* TOSCA: keep the license formatting consistent
-* TOSCA: Create a test CLI program
-* Fix typos in tosca_elk.yaml file
-* TOSCA: use the artifacts directory for scripts
-* TOSCA: Correct duplicate Block Storage description
-* Implement tosca.capabilities.Container
-* TOSCA: minor updates in TOSCA def file per spec
-* TOSCA: rename sample template file
-* Create a unit test for wordpress specification in TOSCA
-* Update the TOSCA monitoring use case
-* Update TOSCA requirements for template and type
-* Apply topology_template to tosca_template
-* Inital Implementation of topology template
-* Add test templates for topology template
-* Update code base to be hacking compatible
-* Update requirements and test-requirements
-* Update README.rst to point to correct urls
-* Update heat-translator's documentation theme
-* Added unit test to verify num vals in str_to_num
-* Implementation of tosca.node.ObjectStorage
-* Implementation of CompareUtils class
-* Added a unit test for convert_unit_size_to_num
-* Added unit test to cover ValueError in str_to_num
-* Update definition of tosca.nodes.WebServer
-* TOSCA: organize test templates
-* Fixes few nits in the network features code
-* Create dictionary returning methods for certain class properties
-* The output template is close to HOT template
-* Rename TOSCA AttachTo relationship
-* Fix coverage so that it works for this repo
-* TOSCA: Handle memory units
-* TOSCA: Create new utils module with memory units
-* Add TOSCA networking features
-* TOSCA: Update README source code link
-* Follow the hosting chain to find the host server
-* Add scripts for logstash, elasticsearch, kibana
-* Add scripts to set up monitoring
-* Update set of scripts for mongodb and nodejs
-* tosca data type validation for float and timestamp
-* TOSCA: Handle custom capability type definition
-* Return input default value on get_input evaluation
-* Replace ip_address attribute with public_address and private_address
-* checking input parameter not None before accessing
-* TOSCA: Add missing artifacts references
-* Change name-value pairs to name-object pairs in the dictoinary
-* validating reference properties in translate_input.py
-* Add support for properties_def as a dictionary
-* added _validate_capabilities_properties function & UT
-* Adding tosca.capabilities.Scalable in TOSCA_definitions.yaml
-* Apply TOSCA OS capability to compute node
-* TOSCA: consider nodejs as web server only
-* TOSCA: remove misleading key Entry-Definitions
-* Use TOSCA properties from capabilities definition
-* Remove Stackforge from README
-* New custom type, unit test and template for use case
-* Add TOSCA networking definiton
-* Update TOSCA interfaces naming
-* Separate TOSCA capabilities definition from assignment
-* Remove unused TOSCA type variables
-* TOSCA: Do not import individual exception classes
-* Add missing TOSCA type keywords
-* Update TOSCA compute requirement
-* Validate TOSCA template version
-* Update TOSCA version
-* Add scalar unit type
-* Handle TOSCA relationship with 'type' keyword
-* Handle custom datatypes in current template
-* Change definition for tosca.capabilities.Endpoint
-* Remove Tosca.capabilities.feature per specs changes
-* add blockstorage attachment notation
-* Remove redundant TOSCA nodejs requirement
-* Change TOSCA interfaces keyword 'input' to 'inputs'
-* Add TOSCA service template for monitoring
-* Minor tweaks
-* Main translation code to handle parameters
-* Add new support for get_attribute
-* Add support for datatypes
-* Rename TOSCA node property relationship to relationships
-* Add a debug env for tox
-* Sort TOSCA relation output for a match to expected test result
-* Create relationship between TOSCA nodes per updated specs
-* Fix .gitreview after rename/transfer
-* Fix errors in templates and base types
-* Workflow documentation is now in infra-manual
-* get_attribute HOST keyword
-* Handle get_attribute in Tosca outputs
-* Add support for list and map types
-* Check for tosca keyword in the TOSCA type
-* Create a TOSCA CSAR for Wordpress template
-* Represent memory unit in string
-* Remove extraneous vim editor configuration comments
-* Provide implementation to parse monitoring template in TOSCA library
-* Allow Tosca templates with no inputs/outputs
-* Extended intrinsic functions support
-* Remove README.md as duplicate for .rst one
-* Work toward Python 3.4 support and testing
-* Add missing TOSCA template keynames
-* Update README and other doc files
-* Clean up heat-translator documentation
-* Revert use of olsosphinx library
-* add docs job to tox.ini
-* Check tosca node requirements
-* Add Schema parent class for Property, Input, Output
-* Implement TOSCA Block Storage
-* Allow use of TOSCA types by short name in the TOSCA template
-* Add type attributes
-* Enhance the validation of tosca
-* Enhanced tosca validation
-* Added a module for intrinsic function
-* Support importing TOSCA custom node types
-* Update the Babel module version
-* TOSCA generator top level code
-* TOSCA generator translation for individual TOSCA type
-* TOSCA generator template syntax
-* Remove tosca node template inheritance from node type
-* Add missing parameter for the tosca property
-* TOSCA parser
-* TOSCA definition types for TOSCA library
-* Add .gitreview file and apply cookiecutter template
-* Delete testattrs.pyc
-* Delete test4.pyc
-* Delete test3.pyc
-* Delete test2.pyc
-* Delete squaretest.pyc
-* First code drop on data modeling
-* Initial commit
diff --git a/tosca2heat/tosca-parser-0.3.0/PKG-INFO b/tosca2heat/tosca-parser-0.3.0/PKG-INFO
deleted file mode 100644 (file)
index fdb8a18..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-Metadata-Version: 1.1
-Name: tosca-parser
-Version: 0.3.0
-Summary: Parser for TOSCA Simple Profile in YAML.
-Home-page: http://www.openstack.org/
-Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
-License: UNKNOWN
-Description: ===============
-        TOSCA Parser
-        ===============
-        
-        Overview
-        --------
-        
-        The TOSCA Parser is an OpenStack project and licensed under Apache 2. It is
-        developed to parse TOSCA Simple Profile in YAML. It reads the TOSCA templates
-        and creates an in-memory graph of TOSCA nodes and their relationship.
-        
-        Architecture
-        ------------
-        
-        The TOSCA Parser takes TOSCA YAML template as an input, with optional input of
-        dictionary of needed parameters with their values, and produces in-memory
-        objects of different TOSCA elements with their relationship to each other. It
-        also creates a graph of TOSCA node templates and their relationship. The support
-        for parsing template within TOSCA CSAR is under development.
-        
-        The ToscaTemplate class located in the toscaparser/tosca_template.py is an entry
-        class of the parser and various functionality of parser can be used by initiating
-        this class. In order to see an example usage, refer to the heat-translator
-        class TranslateTemplate located in the translator/osc/v1/translate.py module.
-        
-        The toscaparser/elements sub-directory contains various modules to handle
-        various TOSCA type elements like node type, relationship type etc. The
-        entity_type.py module is a parent of all type elements. The toscaparser
-        directory contains various python module to handle service template including
-        topology template, node templates, relationship templates etc. The
-        entity_template.py is a parent of all template elements.
-        
-        
-        How To Use
-        ----------
-        Please refer to `doc/source/usage.rst <https://github.com/openstack/tosca-parser/blob/master/doc/source/usage.rst>`_
-        
-        Project Info
-        ------------
-        
-        * License: Apache License, Version 2.0
-        * Source: http://git.openstack.org/cgit/openstack/tosca-parser/
-        
-        
-Platform: UNKNOWN
-Classifier: Environment :: OpenStack
-Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
diff --git a/tosca2heat/tosca-parser-0.3.0/test-requirements.txt b/tosca2heat/tosca-parser-0.3.0/test-requirements.txt
deleted file mode 100644 (file)
index 08dc3e7..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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.
-hacking<0.11,>=0.10.0
-coverage>=3.6
-discover
-fixtures>=1.3.1
-oslotest>=1.7.0 # Apache-2.0
-oslosphinx>=2.5.0 # Apache-2.0
-python-subunit>=0.0.18
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-testrepository>=0.0.18
-testscenarios>=0.4
-testtools>=1.4.0
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/PKG-INFO b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/PKG-INFO
deleted file mode 100644 (file)
index fdb8a18..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-Metadata-Version: 1.1
-Name: tosca-parser
-Version: 0.3.0
-Summary: Parser for TOSCA Simple Profile in YAML.
-Home-page: http://www.openstack.org/
-Author: OpenStack
-Author-email: openstack-dev@lists.openstack.org
-License: UNKNOWN
-Description: ===============
-        TOSCA Parser
-        ===============
-        
-        Overview
-        --------
-        
-        The TOSCA Parser is an OpenStack project and licensed under Apache 2. It is
-        developed to parse TOSCA Simple Profile in YAML. It reads the TOSCA templates
-        and creates an in-memory graph of TOSCA nodes and their relationship.
-        
-        Architecture
-        ------------
-        
-        The TOSCA Parser takes TOSCA YAML template as an input, with optional input of
-        dictionary of needed parameters with their values, and produces in-memory
-        objects of different TOSCA elements with their relationship to each other. It
-        also creates a graph of TOSCA node templates and their relationship. The support
-        for parsing template within TOSCA CSAR is under development.
-        
-        The ToscaTemplate class located in the toscaparser/tosca_template.py is an entry
-        class of the parser and various functionality of parser can be used by initiating
-        this class. In order to see an example usage, refer to the heat-translator
-        class TranslateTemplate located in the translator/osc/v1/translate.py module.
-        
-        The toscaparser/elements sub-directory contains various modules to handle
-        various TOSCA type elements like node type, relationship type etc. The
-        entity_type.py module is a parent of all type elements. The toscaparser
-        directory contains various python module to handle service template including
-        topology template, node templates, relationship templates etc. The
-        entity_template.py is a parent of all template elements.
-        
-        
-        How To Use
-        ----------
-        Please refer to `doc/source/usage.rst <https://github.com/openstack/tosca-parser/blob/master/doc/source/usage.rst>`_
-        
-        Project Info
-        ------------
-        
-        * License: Apache License, Version 2.0
-        * Source: http://git.openstack.org/cgit/openstack/tosca-parser/
-        
-        
-Platform: UNKNOWN
-Classifier: Environment :: OpenStack
-Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/SOURCES.txt b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/SOURCES.txt
deleted file mode 100644 (file)
index 785f1f9..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-.coveragerc
-.mailmap
-.testr.conf
-AUTHORS
-CONTRIBUTING.rst
-ChangeLog
-HACKING.rst
-LICENSE
-MANIFEST.in
-README.rst
-babel.cfg
-openstack-common.conf
-requirements.txt
-setup.cfg
-setup.py
-test-requirements.txt
-tosca_parser.py
-tox.ini
-doc/source/conf.py
-doc/source/contributing.rst
-doc/source/index.rst
-doc/source/installation.rst
-doc/source/usage.rst
-tosca_parser.egg-info/PKG-INFO
-tosca_parser.egg-info/SOURCES.txt
-tosca_parser.egg-info/dependency_links.txt
-tosca_parser.egg-info/entry_points.txt
-tosca_parser.egg-info/not-zip-safe
-tosca_parser.egg-info/pbr.json
-tosca_parser.egg-info/requires.txt
-tosca_parser.egg-info/top_level.txt
-toscaparser/__init__.py
-toscaparser/capabilities.py
-toscaparser/dataentity.py
-toscaparser/entity_template.py
-toscaparser/functions.py
-toscaparser/groups.py
-toscaparser/imports.py
-toscaparser/nodetemplate.py
-toscaparser/parameters.py
-toscaparser/properties.py
-toscaparser/relationship_template.py
-toscaparser/shell.py
-toscaparser/topology_template.py
-toscaparser/tosca_template.py
-toscaparser/tpl_relationship_graph.py
-toscaparser/common/__init__.py
-toscaparser/common/exception.py
-toscaparser/elements/TOSCA_definition_1_0.yaml
-toscaparser/elements/__init__.py
-toscaparser/elements/artifacttype.py
-toscaparser/elements/attribute_definition.py
-toscaparser/elements/capabilitytype.py
-toscaparser/elements/constraints.py
-toscaparser/elements/datatype.py
-toscaparser/elements/entity_type.py
-toscaparser/elements/interfaces.py
-toscaparser/elements/nodetype.py
-toscaparser/elements/policytype.py
-toscaparser/elements/property_definition.py
-toscaparser/elements/relationshiptype.py
-toscaparser/elements/scalarunit.py
-toscaparser/elements/statefulentitytype.py
-toscaparser/prereq/__init__.py
-toscaparser/prereq/csar.py
-toscaparser/tests/__init__.py
-toscaparser/tests/base.py
-toscaparser/tests/test_constraints.py
-toscaparser/tests/test_datatypes.py
-toscaparser/tests/test_exception.py
-toscaparser/tests/test_functions.py
-toscaparser/tests/test_prereq.py
-toscaparser/tests/test_properties.py
-toscaparser/tests/test_scalarunit.py
-toscaparser/tests/test_shell.py
-toscaparser/tests/test_topology_template.py
-toscaparser/tests/test_toscadef.py
-toscaparser/tests/test_toscatpl.py
-toscaparser/tests/test_toscatplvalidation.py
-toscaparser/tests/test_utils.py
-toscaparser/tests/test_validate_tosca_version.py
-toscaparser/tests/artifacts/collectd/config.py
-toscaparser/tests/artifacts/collectd/create.sh
-toscaparser/tests/artifacts/collectd/start.sh
-toscaparser/tests/artifacts/elasticsearch/create.sh
-toscaparser/tests/artifacts/elasticsearch/start.sh
-toscaparser/tests/artifacts/kibana/config.sh
-toscaparser/tests/artifacts/kibana/create.sh
-toscaparser/tests/artifacts/kibana/start.sh
-toscaparser/tests/artifacts/logstash/configure_collectd.py
-toscaparser/tests/artifacts/logstash/configure_elasticsearch.py
-toscaparser/tests/artifacts/logstash/configure_rsyslog.py
-toscaparser/tests/artifacts/logstash/create.sh
-toscaparser/tests/artifacts/logstash/start.sh
-toscaparser/tests/artifacts/mongodb/config.sh
-toscaparser/tests/artifacts/mongodb/create.sh
-toscaparser/tests/artifacts/mongodb/create_database.sh
-toscaparser/tests/artifacts/mongodb/start.sh
-toscaparser/tests/artifacts/mysql/mysql_database_configure.sh
-toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh
-toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh
-toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh
-toscaparser/tests/artifacts/nodejs/config.sh
-toscaparser/tests/artifacts/nodejs/create.sh
-toscaparser/tests/artifacts/nodejs/start.sh
-toscaparser/tests/artifacts/rsyslog/config.sh
-toscaparser/tests/artifacts/rsyslog/create.sh
-toscaparser/tests/artifacts/rsyslog/start.sh
-toscaparser/tests/artifacts/webserver/webserver_install.sh
-toscaparser/tests/artifacts/webserver/webserver_start.sh
-toscaparser/tests/artifacts/wordpress/wordpress_configure.sh
-toscaparser/tests/artifacts/wordpress/wordpress_install.sh
-toscaparser/tests/data/test_instance_nested_imports.yaml
-toscaparser/tests/data/test_invalid_section_names.yaml
-toscaparser/tests/data/test_invalid_template_version.yaml
-toscaparser/tests/data/test_multiple_validation_errors.yaml
-toscaparser/tests/data/test_no_inputs_in_template.yaml
-toscaparser/tests/data/test_no_outputs_in_template.yaml
-toscaparser/tests/data/test_requirements.yaml
-toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml
-toscaparser/tests/data/test_tosca_top_level_error1.yaml
-toscaparser/tests/data/test_tosca_top_level_error2.yaml
-toscaparser/tests/data/tosca_elk.yaml
-toscaparser/tests/data/tosca_helloworld.yaml
-toscaparser/tests/data/tosca_single_instance_wordpress.yaml
-toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml
-toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
-toscaparser/tests/data/CSAR/csar_elk.csar
-toscaparser/tests/data/CSAR/csar_elk.zip
-toscaparser/tests/data/CSAR/csar_hello_world.zip
-toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip
-toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip
-toscaparser/tests/data/CSAR/csar_missing_metadata.zip
-toscaparser/tests/data/CSAR/csar_no_metadata_file.zip
-toscaparser/tests/data/CSAR/csar_not_zip.zip
-toscaparser/tests/data/CSAR/csar_wordpress.zip
-toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip
-toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip
-toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip
-toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip
-toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip
-toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip
-toscaparser/tests/data/CSAR/tosca_elk/README.txt
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml
-toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py
-toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py
-toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py
-toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh
-toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh
-toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh
-toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta
-toscaparser/tests/data/custom_types/collectd.yaml
-toscaparser/tests/data/custom_types/elasticsearch.yaml
-toscaparser/tests/data/custom_types/kibana.yaml
-toscaparser/tests/data/custom_types/logstash.yaml
-toscaparser/tests/data/custom_types/nested_rsyslog.yaml
-toscaparser/tests/data/custom_types/nested_test_wordpress.yaml
-toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml
-toscaparser/tests/data/custom_types/rsyslog.yaml
-toscaparser/tests/data/custom_types/wordpress.yaml
-toscaparser/tests/data/datatypes/custom_datatype_def.yaml
-toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml
-toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml
-toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml
-toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml
-toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml
-toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml
-toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml
-toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml
-toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml
-toscaparser/tests/data/functions/test_invalid_function_signature.yaml
-toscaparser/tests/data/functions/test_unknown_capability_property.yaml
-toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml
-toscaparser/tests/data/functions/test_unknown_input_in_property.yaml
-toscaparser/tests/data/topology_template/definitions.yaml
-toscaparser/tests/data/topology_template/subsystem.yaml
-toscaparser/tests/data/topology_template/system.yaml
-toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml
-toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml
-toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml
-toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml
-toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml
-toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml
-toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml
-toscaparser/utils/__init__.py
-toscaparser/utils/gettextutils.py
-toscaparser/utils/urlutils.py
-toscaparser/utils/validateutils.py
-toscaparser/utils/yamlparser.py
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/dependency_links.txt b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/dependency_links.txt
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/entry_points.txt b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/entry_points.txt
deleted file mode 100644 (file)
index 3738471..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[console_scripts]
-tosca-parser = toscaparser.shell:main
-
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/not-zip-safe b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/not-zip-safe
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/pbr.json b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/pbr.json
deleted file mode 100644 (file)
index f630d90..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"is_release": true, "git_version": "4fbd9cd"}
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/requires.txt b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/requires.txt
deleted file mode 100644 (file)
index 0752db5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-pbr>=1.6
-Babel>=1.3
-cliff>=1.14.0
-PyYAML>=3.1.0
-python-dateutil>=2.4.2
-six>=1.9.0
diff --git a/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/top_level.txt b/tosca2heat/tosca-parser-0.3.0/tosca_parser.egg-info/top_level.txt
deleted file mode 100644 (file)
index 12d8e9b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-toscaparser
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/elements/policytype.py b/tosca2heat/tosca-parser-0.3.0/toscaparser/elements/policytype.py
deleted file mode 100644 (file)
index aa53c2d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from toscaparser.elements.statefulentitytype import StatefulEntityType
-
-
-class PolicyType(StatefulEntityType):
-    '''TOSCA built-in policies type.'''
-
-    def __init__(self, ptype, custom_def=None):
-        super(PolicyType, self).__init__(ptype, self.POLICY_PREFIX,
-                                         custom_def)
-        self.type = ptype
-        self.properties = None
-        if self.PROPERTIES in self.defs:
-            self.properties = self.defs[self.PROPERTIES]
-        self.parent_policies = self._get_parent_policies()
-
-    def _get_parent_policies(self):
-        policies = {}
-        parent_policy = self.parent_type
-        if parent_policy:
-            while parent_policy != 'tosca.policies.Root':
-                policies[parent_policy] = self.TOSCA_DEF[parent_policy]
-                parent_policy = policies[parent_policy]['derived_from']
-        return policies
-
-    @property
-    def parent_type(self):
-        '''Return a policy this policy is derived from.'''
-        return self.derived_from(self.defs)
-
-    def get_policy(self, name):
-        '''Return the definition of a policy field by name.'''
-        if name in self.defs:
-            return self.defs[name]
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/elements/property_definition.py b/tosca2heat/tosca-parser-0.3.0/toscaparser/elements/property_definition.py
deleted file mode 100644 (file)
index 4ffcade..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from toscaparser.common.exception import ExceptionCollector
-from toscaparser.common.exception import InvalidSchemaError
-from toscaparser.utils.gettextutils import _
-
-
-class PropertyDef(object):
-    '''TOSCA built-in Property type.'''
-
-    def __init__(self, name, value=None, schema=None):
-        self.name = name
-        self.value = value
-        self.schema = schema
-
-        try:
-            self.schema['type']
-        except KeyError:
-            msg = (_('Schema definition of "%(pname)s" must have a "type" '
-                     'attribute.') % dict(pname=self.name))
-            ExceptionCollector.appendException(
-                InvalidSchemaError(message=msg))
-
-    @property
-    def required(self):
-        if self.schema:
-            for prop_key, prop_value in self.schema.items():
-                if prop_key == 'required' and prop_value:
-                    return True
-        return False
-
-    @property
-    def default(self):
-        if self.schema:
-            for prop_key, prop_value in self.schema.items():
-                if prop_key == 'default':
-                    return prop_value
-        return None
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/groups.py b/tosca2heat/tosca-parser-0.3.0/toscaparser/groups.py
deleted file mode 100644 (file)
index 40ebcf5..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-
-class NodeGroup(object):
-
-    def __init__(self, name, group_templates, member_nodes):
-        self.name = name
-        self.tpl = group_templates
-        self.members = member_nodes
-
-    @property
-    def member_names(self):
-        return self.tpl.get('members')
-
-    @property
-    def policies(self):
-        return self.tpl.get('policies')
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip b/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip
deleted file mode 100644 (file)
index d644259..0000000
Binary files a/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip and /dev/null differ
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error1.yaml b/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error1.yaml
deleted file mode 100644 (file)
index 591ee97..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-description: >
-  TOSCA simple profile missing version section.
-
-topology_template:
-  inputs:
-    cpus:
-      type: integer
-      description: Number of CPUs for the server.
-      constraints:
-        - valid_values: [ 1, 2, 4, 8 ]
-
-  node_templates:
-    server:
-      type: tosca.nodes.Compute
-      capabilities:
-        host:
-          properties:
-            disk_size: 10 GB
-            num_cpus: { get_input: cpus }
-            mem_size: 4096 MB
-        os:
-          properties:
-            architecture: x86_64
-            type: Linux
-            distribution: Fedora
-            version: 18.0
-
-  outputs:
-    server_address:
-      description: IP address of server instance.
-      value: { get_property: [server, private_address] }
diff --git a/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error2.yaml b/tosca2heat/tosca-parser-0.3.0/toscaparser/tests/data/test_tosca_top_level_error2.yaml
deleted file mode 100644 (file)
index 683e623..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-description: >
-  TOSCA simple profile with invalid top-level key: 'node_template'.
-
-topology_template:
-  inputs:
-    cpus:
-      type: integer
-      description: Number of CPUs for the server.
-      constraints:
-        - valid_values: [ 1, 2, 4, 8 ]
-
-  node_template:
-    server:
-      type: tosca.nodes.Compute
-      capabilities:
-        host:
-          properties:
-            disk_size: 10 GB
-            num_cpus: { get_input: cpus }
-            mem_size: 4096 MB
-        os:
-          properties:
-            architecture: x86_64
-            type: Linux
-            distribution: Fedora
-            version: 18.0
-
-  outputs:
-    server_address:
-      description: IP address of server instance.
-      value: { get_property: [server, private_address] }
similarity index 63%
rename from tosca2heat/tosca-parser-0.3.0/README.rst
rename to tosca2heat/tosca-parser/README.rst
index 51161ec..d80d75b 100644 (file)
@@ -12,16 +12,18 @@ and creates an in-memory graph of TOSCA nodes and their relationship.
 Architecture
 ------------
 
-The TOSCA Parser takes TOSCA YAML template as an input, with optional input of
-dictionary of needed parameters with their values, and produces in-memory
-objects of different TOSCA elements with their relationship to each other. It
-also creates a graph of TOSCA node templates and their relationship. The support
-for parsing template within TOSCA CSAR is under development.
+The TOSCA Parser takes TOSCA YAML template or TOSCA Cloud Service Archive (CSAR)
+file as an input, with optional input of dictionary of needed parameters with their
+values, and produces in-memory objects of different TOSCA elements with their
+relationship to each other. It also creates a graph of TOSCA node templates and their
+relationship.
 
 The ToscaTemplate class located in the toscaparser/tosca_template.py is an entry
 class of the parser and various functionality of parser can be used by initiating
-this class. In order to see an example usage, refer to the heat-translator
-class TranslateTemplate located in the translator/osc/v1/translate.py module.
+this class. In order to see an example usage of TOSCA Parser from a separate tool,
+refer to the OpenStack heat-translator class TranslateTemplate located in the
+translator/osc/v1/translate.py module. The toscaparser/shell.py module of tosca-parser
+also provides a good reference on how to invoke TOSCA Parser from Command Line Interface.
 
 The toscaparser/elements sub-directory contains various modules to handle
 various TOSCA type elements like node type, relationship type etc. The
@@ -10,6 +10,17 @@ The TOSCA Parser is developed to parse TOSCA Simple Profile in YAML. It reads
 the TOSCA templates and creates an in-memory graph of TOSCA nodes and their
 relationship.
 
+The TOSCA Parser can also be used for parsing TOSCA Simple Profile for Network
+Functions Virtualization (NFV). The work to provide such a support was started
+with the release of TOSCA Parser 0.4.0 PyPI release and it is ongoing.
+The TOSCA Simple Profile for NFV can be accessed by using TOSCA version
+"tosca_simple_profile_for_nfv_1_0_0" in the template.
+
+The TOSCA Parser now supports profile definition extensions that can be
+accessed via a custom tosca_definitions_version.  Extensions can be added by
+creating a module in the "toscaparser/extensions" directory.  See the "nfv"
+module for an example.
+
 Contents:
 
 .. toctree::
similarity index 58%
rename from tosca2heat/heat-translator-0.3.0/requirements.txt
rename to tosca2heat/tosca-parser/requirements.txt
index 50d48f9..dd27a53 100644 (file)
@@ -1,10 +1,9 @@
 # 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
-Babel>=1.3
-cliff>=1.15.0 # Apache-2.0
-PyYAML>=3.1.0
-python-dateutil>=2.4.2
-six>=1.9.0
-tosca-parser>=0.3.0
+pbr>=1.6 # Apache-2.0
+Babel>=1.3 # BSD
+cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0
+PyYAML>=3.1.0 # MIT
+python-dateutil>=2.4.2 # BSD
+six>=1.9.0 # MIT
similarity index 53%
rename from tosca2heat/tosca-parser-0.3.0/setup.cfg
rename to tosca2heat/tosca-parser/setup.cfg
index 74cd2a3..747d88c 100644 (file)
@@ -1,30 +1,30 @@
 [metadata]
 name = tosca-parser
 summary = Parser for TOSCA Simple Profile in YAML.
-description-file = 
-       README.rst
+description-file =
+    README.rst
 author = OpenStack
 author-email = openstack-dev@lists.openstack.org
 home-page = http://www.openstack.org/
-classifier = 
-       Environment :: OpenStack
-       Intended Audience :: Information Technology
-       Intended Audience :: System Administrators
-       License :: OSI Approved :: Apache Software License
-       Operating System :: POSIX :: Linux
-       Programming Language :: Python
-       Programming Language :: Python :: 2
-       Programming Language :: Python :: 2.7
-       Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.4
+classifier =
+    Environment :: OpenStack
+    Intended Audience :: Information Technology
+    Intended Audience :: System Administrators
+    License :: OSI Approved :: Apache Software License
+    Operating System :: POSIX :: Linux
+    Programming Language :: Python
+    Programming Language :: Python :: 2
+    Programming Language :: Python :: 2.7
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.4
 
 [files]
-packages = 
-       toscaparser
+packages =
+    toscaparser
 
 [entry_points]
-console_scripts = 
-       tosca-parser = toscaparser.shell:main
+console_scripts =
+    tosca-parser = toscaparser.shell:main
 
 [build_sphinx]
 source-dir = doc/source
@@ -47,9 +47,3 @@ input_file = toscaparser/locale/toscaparser.pot
 keywords = _ gettext ngettext l_ lazy_gettext
 mapping_file = babel.cfg
 output_file = toscaparser/locale/toscaparser.pot
-
-[egg_info]
-tag_date = 0
-tag_svn_revision = 0
-tag_build = 
-
similarity index 96%
rename from tosca2heat/tosca-parser-0.3.0/setup.py
rename to tosca2heat/tosca-parser/setup.py
index d8080d0..782bb21 100644 (file)
@@ -25,5 +25,5 @@ except ImportError:
     pass
 
 setuptools.setup(
-    setup_requires=['pbr>=1.3'],
+    setup_requires=['pbr>=1.8'],
     pbr=True)
diff --git a/tosca2heat/tosca-parser/test-requirements.txt b/tosca2heat/tosca-parser/test-requirements.txt
new file mode 100644 (file)
index 0000000..2b9cae7
--- /dev/null
@@ -0,0 +1,14 @@
+# 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.
+hacking<0.11,>=0.10.0
+coverage>=3.6 # Apache-2.0
+discover # BSD
+fixtures>=1.3.1 # Apache-2.0/BSD
+oslotest>=1.10.0 # Apache-2.0
+oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
+python-subunit>=0.0.18 # Apache-2.0/BSD
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+testrepository>=0.0.18 # Apache-2.0/BSD
+testscenarios>=0.4 # Apache-2.0/BSD
+testtools>=1.4.0 # MIT
@@ -49,6 +49,18 @@ class TOSCAException(Exception):
     def __str__(self):
         return self.message
 
+    @staticmethod
+    def generate_inv_schema_property_error(self, attr, value, valid_values):
+        msg = (_('Schema definition of "%(propname)s" has '
+                 '"%(attr)s" attribute with invalid value '
+                 '"%(value1)s". The value must be one of '
+                 '"%(value2)s".') % {"propname": self.name,
+                                     "attr": attr,
+                                     "value1": value,
+                                     "value2": valid_values})
+        ExceptionCollector.appendException(
+            InvalidSchemaError(message=msg))
+
     @staticmethod
     def set_fatal_format_exception(flag):
         if isinstance(flag, bool):
@@ -105,6 +117,22 @@ class URLException(TOSCAException):
     msg_fmt = _('%(what)s')
 
 
+class ToscaExtImportError(TOSCAException):
+    msg_fmt = _('Unable to import extension "%(ext_name)s". '
+                'Check to see that it exists and has no '
+                'language definition errors.')
+
+
+class ToscaExtAttributeError(TOSCAException):
+    msg_fmt = _('Missing attribute in extension "%(ext_name)s". '
+                'Check to see that it has required attributes '
+                '"%(attrs)s" defined.')
+
+
+class InvalidGroupTargetException(TOSCAException):
+    msg_fmt = _('"%(message)s"')
+
+
 class ExceptionCollector(object):
 
     exceptions = []
@@ -97,7 +97,11 @@ class DataEntity(object):
                 # check if field value meets constraints defined
                 if prop_schema.constraints:
                     for constraint in prop_schema.constraints:
-                        constraint.validate(value)
+                        if isinstance(value, list):
+                            for val in value:
+                                constraint.validate(val)
+                        else:
+                            constraint.validate(value)
 
         return self.value
 
@@ -122,6 +126,8 @@ class DataEntity(object):
             return validateutils.validate_number(value)
         elif type == Schema.BOOLEAN:
             return validateutils.validate_boolean(value)
+        elif type == Schema.RANGE:
+            return validateutils.validate_range(value)
         elif type == Schema.TIMESTAMP:
             validateutils.validate_timestamp(value)
             return value
@@ -32,9 +32,9 @@ tosca.nodes.Root:
       type: string
     state:
       type: string
-    capabilities:
-      feature:
-        type: tosca.capabilities.Node
+  capabilities:
+    feature:
+      type: tosca.capabilities.Node
   requirements:
     - dependency:
         capability: tosca.capabilities.Node
@@ -52,6 +52,14 @@ tosca.nodes.Compute:
       type: string
     public_address:
       type: string
+    networks:
+      type: map
+      entry_schema:
+        type: tosca.datatypes.network.NetworkInfo
+    ports:
+      type: map
+      entry_schema:
+        type: tosca.datatypes.network.PortInfo
   capabilities:
       host:
          type: tosca.capabilities.Container
@@ -90,12 +98,12 @@ tosca.nodes.DBMS:
   derived_from: tosca.nodes.SoftwareComponent
   properties:
     port:
-      required: no
+      required: false
       type: integer
       description: >
         The port the DBMS service will listen to for data and requests.
     root_password:
-      required: no
+      required: false
       type: string
       description: >
         The root password for the DBMS service.
@@ -108,17 +116,23 @@ tosca.nodes.Database:
   derived_from: tosca.nodes.Root
   properties:
     user:
-      required: no
+      required: false
       type: string
       description: >
         User account name for DB administration
+    port:
+      required: false
+      type: integer
+      description:  >
+        The port the database service will use to listen for incoming data and
+        requests.
     name:
-      required: no
+      required: false
       type: string
       description: >
         The name of the database.
     password:
-      required: no
+      required: false
       type: string
       description: >
         The password for the DB user account
@@ -184,7 +198,7 @@ tosca.nodes.network.Network:
   properties:
     ip_version:
       type: integer
-      required: no
+      required: false
       default: 4
       constraints:
         - valid_values: [ 4, 6 ]
@@ -193,29 +207,29 @@ tosca.nodes.network.Network:
         or 6 for ipv6.
     cidr:
       type: string
-      required: no
+      required: false
       description: >
         The cidr block of the requested network.
     start_ip:
       type: string
-      required: no
+      required: false
       description: >
          The IP address to be used as the start of a pool of addresses within
          the full IP range derived from the cidr block.
     end_ip:
       type: string
-      required: no
+      required: false
       description: >
           The IP address to be used as the end of a pool of addresses within
           the full IP range derived from the cidr block.
     gateway_ip:
       type: string
-      required: no
+      required: false
       description: >
          The gateway IP address.
     network_name:
       type: string
-      required: no
+      required: false
       description: >
          An identifier that represents an existing Network instance in the
          underlying cloud infrastructure or can be used as the name of the
@@ -226,7 +240,7 @@ tosca.nodes.network.Network:
          be created.
     network_id:
       type: string
-      required: no
+      required: false
       description: >
          An identifier that represents an existing Network instance in the
          underlying cloud infrastructure. This property is mutually exclusive
@@ -234,13 +248,27 @@ tosca.nodes.network.Network:
          or together with network_name to identify an existing network.
     segmentation_id:
       type: string
-      required: no
+      required: false
       description: >
          A segmentation identifier in the underlying cloud infrastructure.
          E.g. VLAN ID, GRE tunnel ID, etc..
+    network_type:
+      type: string
+      required: false
+      description: >
+         It specifies the nature of the physical network in the underlying
+         cloud infrastructure. Examples are flat, vlan, gre or vxlan.
+         For flat and vlan types, physical_network should be provided too.
+    physical_network:
+      type: string
+      required: false
+      description: >
+         It identifies the physical network on top of which the network is
+         implemented, e.g. physnet1. This property is required if network_type
+         is flat or vlan.
     dhcp_enabled:
       type: boolean
-      required: no
+      required: false
       default: true
       description: >
         Indicates should DHCP service be enabled on the network or not.
@@ -257,12 +285,12 @@ tosca.nodes.network.Port:
   properties:
     ip_address:
       type: string
-      required: no
+      required: false
       description: >
         Allow the user to set a static IP.
     order:
       type: integer
-      required: no
+      required: false
       default: 0
       constraints:
         - greater_or_equal: 0
@@ -270,7 +298,7 @@ tosca.nodes.network.Port:
         The order of the NIC on the compute instance (e.g. eth2).
     is_default:
       type: boolean
-      required: no
+      required: false
       default: false
       description: >
         If is_default=true this port will be used for the default gateway
@@ -278,13 +306,13 @@ tosca.nodes.network.Port:
         set as is_default=true.
     ip_range_start:
       type: string
-      required: no
+      required: false
       description: >
         Defines the starting IP of a range to be allocated for the compute
         instances that are associated with this Port.
     ip_range_end:
       type: string
-      required: no
+      required: false
       description: >
         Defines the ending IP of a range to be allocated for the compute
         instances that are associated with this Port.
@@ -295,16 +323,18 @@ tosca.nodes.network.Port:
     - binding:
         description: >
           Binding requirement expresses the relationship between Port and
-          Compute nodes. Effectevely it indicates that the Port will be
+          Compute nodes. Effectively it indicates that the Port will be
           attached to specific Compute node instance
         capability: tosca.capabilities.network.Bindable
         relationship: tosca.relationships.network.BindsTo
+        node: tosca.nodes.Compute
     - link:
         description: >
           Link requirement expresses the relationship between Port and Network
           nodes. It indicates which network this port will connect to.
         capability: tosca.capabilities.network.Linkable
         relationship: tosca.relationships.network.LinksTo
+        node: tosca.nodes.network.Network
 
 tosca.nodes.ObjectStorage:
   derived_from: tosca.nodes.Root
@@ -315,19 +345,19 @@ tosca.nodes.ObjectStorage:
   properties:
     name:
       type: string
-      required: yes
+      required: true
       description: >
         The logical name of the object store (or container).
     size:
       type: scalar-unit.size
-      required: no
+      required: false
       constraints:
         - greater_or_equal: 0 GB
       description: >
         The requested initial storage size.
     maxsize:
       type: scalar-unit.size
-      required: no
+      required: false
       constraints:
         - greater_or_equal: 0 GB
       description: >
@@ -336,6 +366,47 @@ tosca.nodes.ObjectStorage:
     storage_endpoint:
       type: tosca.capabilities.Endpoint
 
+tosca.nodes.LoadBalancer:
+  derived_from: tosca.nodes.Root
+  properties:
+    algorithm:
+      type: string
+      required: false
+      status: experimental
+  capabilities:
+    client:
+      type: tosca.capabilities.Endpoint.Public
+      occurrences: [0, UNBOUNDED]
+      description: the Floating (IP) client’s on the public network can connect to
+  requirements:
+    - application:
+        capability: tosca.capabilities.Endpoint
+        relationship: tosca.relationships.RoutesTo
+        occurrences: [0, UNBOUNDED]
+        description: Connection to one or more load balanced applications
+
+tosca.nodes.Container.Application:
+  derived_from: tosca.nodes.Root
+  requirements:
+    - host:
+        capability: tosca.capabilities.Container
+        node: tosca.nodes.Container
+        relationship: tosca.relationships.HostedOn
+
+tosca.nodes.Container.Runtime:
+  derived_from: tosca.nodes.SoftwareComponent
+  capabilities:
+    host:
+      type: tosca.capabilities.Container
+    scalable:
+      type: tosca.capabilities.Scalable
+
+tosca.nodes.Container.Application.Docker:
+  derived_from: tosca.nodes.Container.Application
+  requirements:
+    - host:
+        capability: tosca.capabilities.Container.Docker
+
 ##########################################################################
 # Relationship Type.
 # A Relationship Type is a reusable entity that defines the type of one
@@ -381,6 +452,10 @@ tosca.relationships.AttachesTo:
       required: false
       type: string
 
+tosca.relationships.RoutesTo:
+  derived_from: tosca.relationships.ConnectsTo
+  valid_target_types: [ tosca.capabilities.Endpoint ]
+
 tosca.relationships.network.LinksTo:
   derived_from: tosca.relationships.DependsOn
   valid_target_types: [ tosca.capabilities.network.Linkable ]
@@ -406,22 +481,22 @@ tosca.capabilities.Container:
   derived_from: tosca.capabilities.Root
   properties:
     num_cpus:
-      required: no
+      required: false
       type: integer
       constraints:
         - greater_or_equal: 1
     cpu_frequency:
-      required: no
+      required: false
       type: scalar-unit.frequency
       constraints:
         - greater_or_equal: 0.1 GHz
     disk_size:
-      required: no
+      required: false
       type: scalar-unit.size
       constraints:
         - greater_or_equal: 0 MB
     mem_size:
-      required: no
+      required: false
       type: scalar-unit.size
       constraints:
         - greater_or_equal: 0 MB
@@ -431,12 +506,14 @@ tosca.capabilities.Endpoint:
   properties:
     protocol:
       type: string
+      required: true
       default: tcp
     port:
       type: tosca.datatypes.network.PortDef
       required: false
     secure:
       type: boolean
+      required: false
       default: false
     url_path:
       type: string
@@ -449,6 +526,7 @@ tosca.capabilities.Endpoint:
       required: false
     initiator:
       type: string
+      required: false
       default: source
       constraints:
         - valid_values: [source, target, peer]
@@ -499,7 +577,7 @@ tosca.capabilities.Scalable:
   properties:
     min_instances:
       type: integer
-      required: yes
+      required: true
       default: 1
       description: >
         This property is used to indicate the minimum number of instances
@@ -507,7 +585,7 @@ tosca.capabilities.Scalable:
         a TOSCA orchestrator.
     max_instances:
       type: integer
-      required: yes
+      required: true
       default: 1
       description: >
         This property is used to indicate the maximum number of instances
@@ -515,7 +593,7 @@ tosca.capabilities.Scalable:
         a TOSCA orchestrator.
     default_instances:
       type: integer
-      required: no
+      required: false
       description: >
         An optional property that indicates the requested default number
         of instances that should be the starting number of instances a
@@ -570,6 +648,60 @@ tosca.capabilities.OperatingSystem:
       description: >
         The host Operating System version.
 
+tosca.capabilities.Container.Docker:
+  derived_from: tosca.capabilities.Container
+  properties:
+    version:
+      type: list
+      required: false
+      entry_schema:
+        type: version
+      description: >
+        The Docker version capability.
+    publish_all:
+      type: boolean
+      default: false
+      required: false
+      description: >
+        Indicates that all ports (ranges) listed in the dockerfile
+        using the EXPOSE keyword be published.
+    publish_ports:
+      type: list
+      entry_schema:
+        type: PortSpec
+      required: false
+      description: >
+        List of ports mappings from source (Docker container)
+        to target (host) ports to publish.
+    expose_ports:
+      type: list
+      entry_schema:
+        type: PortSpec
+      required: false
+      description: >
+        List of ports mappings from source (Docker container) to expose
+        to other Docker containers (not accessible outside host).
+    volumes:
+      type: list
+      entry_schema:
+        type: string
+      required: false
+      description: >
+        The dockerfile VOLUME command which is used to enable access
+        from the Docker container to a directory on the host machine.
+    host_id:
+      type: string
+      required: false
+      description: >
+          The optional identifier of an existing host resource
+          that should be used to run this container on.
+    volume_id:
+      type: string
+      required: false
+      description: >
+        The optional identifier of an existing storage volume (resource)
+        that should be used to create the container's mount point(s) on.
+
 ##########################################################################
  # Interfaces Type.
  # The Interfaces element describes a list of one or more interface
@@ -663,14 +795,18 @@ tosca.datatypes.network.PortSpec:
         - valid_values: [ udp, tcp, igmp ]
     target:
       type: PortDef
+      required: false
     target_range:
       type: range
+      required: false
       constraints:
         - in_range: [ 1, 65535 ]
     source:
       type: PortDef
+      required: false
     source_range:
       type: range
+      required: false
       constraints:
         - in_range: [ 1, 65535 ]
 
@@ -776,3 +912,15 @@ tosca.policies.Performance:
   derived_from: tosca.policies.Root
   description: The TOSCA Policy Type definition that is used to declare
     performance requirements for TOSCA nodes or groups of nodes.
+
+##########################################################################
+ # Group Type.
+ # Group Type represents logical grouping of TOSCA nodes that have an
+ # implied membership relationship and may need to be orchestrated or
+ # managed together to achieve some result.
+##########################################################################
+tosca.groups.Root:
+  description: The TOSCA Group Type all other TOSCA Group Types derive from
+  interfaces:
+    Standard:
+      type: tosca.interfaces.node.lifecycle.Standard
@@ -25,7 +25,7 @@ class CapabilityTypeDef(StatefulEntityType):
         self.properties = None
         if self.PROPERTIES in self.defs:
             self.properties = self.defs[self.PROPERTIES]
-        self.parent_capabilities = self._get_parent_capabilities()
+        self.parent_capabilities = self._get_parent_capabilities(custom_def)
 
     def get_properties_def_objects(self):
         '''Return a list of property definition objects.'''
@@ -42,7 +42,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.items():
+                        prop not in self.properties.keys():
                         properties.append(PropertyDef(prop, None, schema))
         return properties
 
@@ -57,12 +57,15 @@ class CapabilityTypeDef(StatefulEntityType):
         if props_def and name in props_def:
             return props_def[name].value
 
-    def _get_parent_capabilities(self):
+    def _get_parent_capabilities(self, custom_def=None):
         capabilities = {}
         parent_cap = self.parent_type
         if parent_cap:
             while parent_cap != 'tosca.capabilities.Root':
-                capabilities[parent_cap] = self.TOSCA_DEF[parent_cap]
+                if parent_cap in self.TOSCA_DEF.keys():
+                    capabilities[parent_cap] = self.TOSCA_DEF[parent_cap]
+                elif custom_def and parent_cap in custom_def.keys():
+                    capabilities[parent_cap] = custom_def[parent_cap]
                 parent_cap = capabilities[parent_cap]['derived_from']
         return capabilities
 
@@ -33,12 +33,12 @@ class Schema(collections.Mapping):
     )
 
     PROPERTY_TYPES = (
-        INTEGER, STRING, BOOLEAN, FLOAT,
+        INTEGER, STRING, BOOLEAN, FLOAT, RANGE,
         NUMBER, TIMESTAMP, LIST, MAP,
         SCALAR_UNIT_SIZE, SCALAR_UNIT_FREQUENCY, SCALAR_UNIT_TIME,
         PORTDEF, VERSION
     ) = (
-        'integer', 'string', 'boolean', 'float',
+        'integer', 'string', 'boolean', 'float', 'range',
         'number', 'timestamp', 'list', 'map',
         'scalar-unit.size', 'scalar-unit.frequency', 'scalar-unit.time',
         'PortDef', 'version'
@@ -127,6 +127,8 @@ class Constraint(object):
                    'less_or_equal', 'in_range', 'valid_values', 'length',
                    'min_length', 'max_length', 'pattern')
 
+    UNBOUNDED = 'UNBOUNDED'
+
     def __new__(cls, property_name, property_type, constraint):
         if cls is not Constraint:
             return super(Constraint, cls).__new__(cls)
@@ -372,11 +374,11 @@ class InRange(Constraint):
     constraint_key = Constraint.IN_RANGE
 
     valid_types = (int, float, datetime.date,
-                   datetime.time, datetime.datetime)
+                   datetime.time, datetime.datetime, str)
 
     valid_prop_types = (Schema.INTEGER, Schema.FLOAT, Schema.TIMESTAMP,
                         Schema.SCALAR_UNIT_SIZE, Schema.SCALAR_UNIT_FREQUENCY,
-                        Schema.SCALAR_UNIT_TIME)
+                        Schema.SCALAR_UNIT_TIME, Schema.RANGE)
 
     def __init__(self, property_name, property_type, constraint):
         super(InRange, self).__init__(property_name, property_type, constraint)
@@ -386,21 +388,31 @@ class InRange(Constraint):
                 InvalidSchemaError(message=_('The property "in_range" '
                                              'expects a list.')))
 
+        msg = _('The property "in_range" expects comparable values.')
         for value in self.constraint_value:
             if not isinstance(value, self.valid_types):
                 ExceptionCollector.appendException(
-                    InvalidSchemaError(_('The property "in_range" expects '
-                                         'comparable values.')))
+                    InvalidSchemaError(message=msg))
+            # The only string we allow for range is the special value
+            # 'UNBOUNDED'
+            if(isinstance(value, str) and value != self.UNBOUNDED):
+                ExceptionCollector.appendException(
+                    InvalidSchemaError(message=msg))
 
         self.min = self.constraint_value[0]
         self.max = self.constraint_value[1]
 
     def _is_valid(self, value):
-        if value < self.min:
+        if not isinstance(self.min, str):
+            if value < self.min:
+                return False
+        elif self.min != self.UNBOUNDED:
             return False
-        if value > self.max:
+        if not isinstance(self.max, str):
+            if value > self.max:
+                return False
+        elif self.max != self.UNBOUNDED:
             return False
-
         return True
 
     def _err_msg(self, value):
@@ -487,7 +499,7 @@ class MinLength(Constraint):
 
     valid_types = (int, )
 
-    valid_prop_types = (Schema.STRING, )
+    valid_prop_types = (Schema.STRING, Schema.MAP)
 
     def __init__(self, property_name, property_type, constraint):
         super(MinLength, self).__init__(property_name, property_type,
@@ -498,7 +510,8 @@ class MinLength(Constraint):
                                              'expects an integer.')))
 
     def _is_valid(self, value):
-        if isinstance(value, str) and len(value) >= self.constraint_value:
+        if ((isinstance(value, str) or isinstance(value, dict)) and
+           len(value) >= self.constraint_value):
             return True
 
         return False
@@ -521,7 +534,7 @@ class MaxLength(Constraint):
 
     valid_types = (int, )
 
-    valid_prop_types = (Schema.STRING, )
+    valid_prop_types = (Schema.STRING, Schema.MAP)
 
     def __init__(self, property_name, property_type, constraint):
         super(MaxLength, self).__init__(property_name, property_type,
@@ -532,7 +545,8 @@ class MaxLength(Constraint):
                                              'expects an integer.')))
 
     def _is_valid(self, value):
-        if isinstance(value, str) and len(value) <= self.constraint_value:
+        if ((isinstance(value, str) or isinstance(value, dict)) and
+           len(value) <= self.constraint_value):
             return True
 
         return False
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import copy
 import logging
 import os
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import ValidationError
+from toscaparser.extensions.exttools import ExtTools
 import toscaparser.utils.yamlparser
 
 log = logging.getLogger('tosca')
@@ -49,6 +53,7 @@ class EntityType(object):
     INTERFACE_PREFIX = 'tosca.interfaces.'
     ARTIFACT_PREFIX = 'tosca.artifacts.'
     POLICY_PREFIX = 'tosca.policies.'
+    GROUP_PREFIX = 'tosca.groups.'
     # currently the data types are defined only for network
     # but may have changes in the future.
     DATATYPE_PREFIX = 'tosca.datatypes.network.'
@@ -81,26 +86,42 @@ class EntityType(object):
         value = None
         if defs is None:
             if not hasattr(self, 'defs'):
-                return
+                return None
             defs = self.defs
         if ndtype in defs:
-            value = defs[ndtype]
-        if parent and not value:
-            p = self.parent_type
-            while value is None:
-                # check parent node
-                if not p:
-                    break
-                if p and p.type == 'tosca.nodes.Root':
-                    break
-                value = p.get_value(ndtype)
-                p = p.parent_type
+            # copy the value to avoid that next operations add items in the
+            # item definitions
+            value = copy.copy(defs[ndtype])
+        if parent:
+            p = self
+            if p:
+                while p:
+                    if ndtype in p.defs:
+                        # get the parent value
+                        parent_value = p.defs[ndtype]
+                        if value:
+                            if isinstance(value, dict):
+                                for k, v in parent_value.items():
+                                    if k not in value.keys():
+                                        value[k] = v
+                            if isinstance(value, list):
+                                for p_value in parent_value:
+                                    if p_value not in value:
+                                        value.append(p_value)
+                        else:
+                            value = copy.copy(parent_value)
+                    p = p.parent_type
         return value
 
     def get_definition(self, ndtype):
         value = None
-        defs = self.defs
-        if ndtype in defs:
+        if not hasattr(self, 'defs'):
+            defs = None
+            ExceptionCollector.appendException(
+                ValidationError(message="defs is " + str(defs)))
+        else:
+            defs = self.defs
+        if defs is not None and ndtype in defs:
             value = defs[ndtype]
         p = self.parent_type
         if p:
@@ -113,3 +134,12 @@ class EntityType(object):
                     inherited.update(value)
                     value.update(inherited)
         return value
+
+
+def update_definitions(version):
+    exttools = ExtTools()
+    extension_defs_file = exttools.get_defs_file(version)
+
+    loader = toscaparser.utils.yamlparser.load_yaml
+
+    EntityType.TOSCA_DEF.update(loader(extension_defs_file))
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py b/tosca2heat/tosca-parser/toscaparser/elements/grouptype.py
new file mode 100644 (file)
index 0000000..ec5571c
--- /dev/null
@@ -0,0 +1,86 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidTypeError
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.elements.statefulentitytype import StatefulEntityType
+
+
+class GroupType(StatefulEntityType):
+    '''TOSCA built-in group type.'''
+
+    SECTIONS = (DERIVED_FROM, VERSION, METADATA, DESCRIPTION, PROPERTIES,
+                MEMBERS, INTERFACES) = \
+               ("derived_from", "version", "metadata", "description",
+                "properties", "members", "interfaces")
+
+    def __init__(self, grouptype, custom_def=None):
+        super(GroupType, self).__init__(grouptype, self.GROUP_PREFIX,
+                                        custom_def)
+        self.custom_def = custom_def
+        self.grouptype = grouptype
+        self._validate_fields()
+        self.group_description = None
+        if self.DESCRIPTION in self.defs:
+            self.group_description = self.defs[self.DESCRIPTION]
+
+        self.group_version = None
+        if self.VERSION in self.defs:
+            self.group_version = self.defs[self.VERSION]
+
+        self.group_properties = None
+        if self.PROPERTIES in self.defs:
+            self.group_properties = self.defs[self.PROPERTIES]
+
+        self.group_members = None
+        if self.MEMBERS in self.defs:
+            self.group_members = self.defs[self.MEMBERS]
+
+        if self.METADATA in self.defs:
+            self.meta_data = self.defs[self.METADATA]
+            self._validate_metadata(self.meta_data)
+
+    @property
+    def description(self):
+        return self.group_description
+
+    @property
+    def version(self):
+        return self.group_version
+
+    @property
+    def interfaces(self):
+        return self.get_value(self.INTERFACES)
+
+    def _validate_fields(self):
+        if self.defs:
+            for name in self.defs.keys():
+                if name not in self.SECTIONS:
+                    ExceptionCollector.appendException(
+                        UnknownFieldError(what='Group Type %s'
+                                          % self.grouptype, field=name))
+
+    def _validate_metadata(self, meta_data):
+        if not meta_data.get('type') in ['map', 'tosca:map']:
+            ExceptionCollector.appendException(
+                InvalidTypeError(what='"%s" defined in group for '
+                                 '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':
+                ExceptionCollector.appendException(
+                    InvalidTypeError(what='"%s" defined in group for '
+                                     'metadata "%s"'
+                                     % (entry_schema_type.get('type'),
+                                        entry_schema)))
@@ -10,6 +10,9 @@
 #    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.common.exception import ValidationError
 from toscaparser.elements.capabilitytype import CapabilityTypeDef
 import toscaparser.elements.interfaces as ifaces
 from toscaparser.elements.interfaces import InterfacesDef
@@ -19,16 +22,22 @@ from toscaparser.elements.statefulentitytype import StatefulEntityType
 
 class NodeType(StatefulEntityType):
     '''TOSCA built-in node type.'''
+    SECTIONS = (DERIVED_FROM, METADATA, PROPERTIES, VERSION, DESCRIPTION, ATTRIBUTES, REQUIREMENTS, CAPABILITIES, INTERFACES, ARTIFACTS) = \
+               ('derived_from', 'metadata', 'properties', 'version',
+                'description', 'attributes', 'requirements', 'capabilities',
+                'interfaces', 'artifacts')
 
     def __init__(self, ntype, custom_def=None):
         super(NodeType, self).__init__(ntype, self.NODE_PREFIX, custom_def)
+        self.ntype = ntype
         self.custom_def = custom_def
+        self._validate_keys()
 
     @property
     def parent_type(self):
         '''Return a node this node is derived from.'''
         if not hasattr(self, 'defs'):
-            return
+            return None
         pnode = self.derived_from(self.defs)
         if pnode:
             return NodeType(pnode, self.custom_def)
@@ -78,7 +87,7 @@ class NodeType(StatefulEntityType):
                             relation = self._get_relation(key, value)
                             keyword = key
                             node_type = value
-                rtype = RelationshipType(relation, keyword, req)
+                rtype = RelationshipType(relation, keyword, self.custom_def)
                 relatednode = NodeType(node_type, self.custom_def)
                 relationship[rtype] = relatednode
         return relationship
@@ -128,10 +137,12 @@ class NodeType(StatefulEntityType):
     def get_capabilities_objects(self):
         '''Return a list of capability objects.'''
         typecapabilities = []
-        caps = self.get_value(self.CAPABILITIES)
+        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> }
             for name, value in caps.items():
                 ctype = value.get('type')
                 cap = CapabilityTypeDef(name, ctype, self.type,
@@ -146,14 +157,19 @@ class NodeType(StatefulEntityType):
 
     @property
     def requirements(self):
-        return self.get_value(self.REQUIREMENTS)
+        return self.get_value(self.REQUIREMENTS, None, True)
 
     def get_all_requirements(self):
         requires = self.requirements
         parent_node = self.parent_type
         if requires is None:
             requires = self.get_value(self.REQUIREMENTS, None, True)
-            parent_node = parent_node.parent_type
+            if parent_node is None:
+                ExceptionCollector.appendException(
+                    ValidationError(message="parent_node is "
+                                    + str(parent_node)))
+            else:
+                parent_node = parent_node.parent_type
         if parent_node:
             while parent_node.type != 'tosca.nodes.Root':
                 req = parent_node.get_value(self.REQUIREMENTS, None, True)
@@ -200,3 +216,11 @@ class NodeType(StatefulEntityType):
         captype = self.get_capability(name)
         if captype and name in captype.keys():
             return captype[name].value
+
+    def _validate_keys(self):
+        if self.defs:
+            for key in self.defs.keys():
+                if key not in self.SECTIONS:
+                    ExceptionCollector.appendException(
+                        UnknownFieldError(what='Nodetype"%s"' % self.ntype,
+                                          field=key))
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/policytype.py b/tosca2heat/tosca-parser/toscaparser/elements/policytype.py
new file mode 100644 (file)
index 0000000..04cbab5
--- /dev/null
@@ -0,0 +1,115 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidTypeError
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.elements.statefulentitytype import StatefulEntityType
+from toscaparser.utils.validateutils import TOSCAVersionProperty
+
+
+class PolicyType(StatefulEntityType):
+
+    '''TOSCA built-in policies type.'''
+    SECTIONS = (DERIVED_FROM, METADATA, PROPERTIES, VERSION, DESCRIPTION, TARGETS) = \
+               ('derived_from', 'metadata', 'properties', 'version',
+                'description', 'targets')
+
+    def __init__(self, ptype, custom_def=None):
+        super(PolicyType, self).__init__(ptype, self.POLICY_PREFIX,
+                                         custom_def)
+        self.type = ptype
+        self._validate_keys()
+
+        self.meta_data = None
+        if self.METADATA in self.defs:
+            self.meta_data = self.defs[self.METADATA]
+            self._validate_metadata(self.meta_data)
+
+        self.properties = None
+        if self.PROPERTIES in self.defs:
+            self.properties = self.defs[self.PROPERTIES]
+        self.parent_policies = self._get_parent_policies()
+
+        self.policy_version = None
+        if self.VERSION in self.defs:
+            self.policy_version = TOSCAVersionProperty(
+                self.defs[self.VERSION]).get_version()
+
+        self.policy_description = self.defs[self.DESCRIPTION] \
+            if self.DESCRIPTION in self.defs else None
+
+        self.targets_list = None
+        if self.TARGETS in self.defs:
+            self.targets_list = self.defs[self.TARGETS]
+            self._validate_targets(self.targets_list, custom_def)
+
+    def _get_parent_policies(self):
+        policies = {}
+        parent_policy = self.parent_type
+        if parent_policy:
+            while parent_policy != 'tosca.policies.Root':
+                policies[parent_policy] = self.TOSCA_DEF[parent_policy]
+                parent_policy = policies[parent_policy]['derived_from']
+        return policies
+
+    @property
+    def parent_type(self):
+        '''Return a policy this policy is derived from.'''
+        return self.derived_from(self.defs)
+
+    def get_policy(self, name):
+        '''Return the definition of a policy field by name.'''
+        if name in self.defs:
+            return self.defs[name]
+
+    @property
+    def targets(self):
+        '''Return targets.'''
+        return self.targets_list
+
+    @property
+    def description(self):
+        return self.policy_description
+
+    @property
+    def version(self):
+        return self.policy_version
+
+    def _validate_keys(self):
+        for key in self.defs.keys():
+            if key not in self.SECTIONS:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Policy "%s"' % self.type,
+                                      field=key))
+
+    def _validate_targets(self, targets_list, custom_def):
+        for nodetype in targets_list:
+            if nodetype not in custom_def:
+                ExceptionCollector.appendException(
+                    InvalidTypeError(what='"%s" defined in targets for '
+                                     'policy "%s"' % (nodetype, self.type)))
+
+    def _validate_metadata(self, meta_data):
+        if not meta_data.get('type') in ['map', 'tosca:map']:
+            ExceptionCollector.appendException(
+                InvalidTypeError(what='"%s" defined in policy for '
+                                 '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':
+                ExceptionCollector.appendException(
+                    InvalidTypeError(what='"%s" defined in policy for '
+                                     'metadata "%s"'
+                                     % (entry_schema_type.get('type'),
+                                        entry_schema)))
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/property_definition.py b/tosca2heat/tosca-parser/toscaparser/elements/property_definition.py
new file mode 100644 (file)
index 0000000..a242ddf
--- /dev/null
@@ -0,0 +1,100 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidSchemaError
+from toscaparser.common.exception import TOSCAException
+from toscaparser.utils.gettextutils import _
+
+
+class PropertyDef(object):
+    '''TOSCA built-in Property type.'''
+
+    VALID_PROPERTY_KEYNAMES = (PROPERTY_KEYNAME_DEFAULT,
+                               PROPERTY_KEYNAME_REQUIRED,
+                               PROPERTY_KEYNAME_STATUS) = \
+        ('default', 'required', 'status')
+
+    PROPERTY_REQUIRED_DEFAULT = True
+
+    VALID_REQUIRED_VALUES = ['true', 'false']
+    VALID_STATUS_VALUES = (PROPERTY_STATUS_SUPPORTED,
+                           PROPERTY_STATUS_EXPERIMENTAL) = \
+        ('supported', 'experimental')
+
+    PROPERTY_STATUS_DEFAULT = PROPERTY_STATUS_SUPPORTED
+
+    def __init__(self, name, value=None, schema=None):
+        self.name = name
+        self.value = value
+        self.schema = schema
+        self._status = self.PROPERTY_STATUS_DEFAULT
+        self._required = self.PROPERTY_REQUIRED_DEFAULT
+
+        # Validate required 'type' property exists
+        try:
+            self.schema['type']
+        except KeyError:
+            msg = (_('Schema definition of "%(pname)s" must have a "type" '
+                     'attribute.') % dict(pname=self.name))
+            ExceptionCollector.appendException(
+                InvalidSchemaError(message=msg))
+
+        if self.schema:
+            self._load_required_attr_from_schema()
+            self._load_status_attr_from_schema()
+
+    @property
+    def default(self):
+        if self.schema:
+            for prop_key, prop_value in self.schema.items():
+                if prop_key == self.PROPERTY_KEYNAME_DEFAULT:
+                    return prop_value
+        return None
+
+    @property
+    def required(self):
+        return self._required
+
+    def _load_required_attr_from_schema(self):
+        # IF 'required' keyname exists verify it's a boolean,
+        # if so override default
+        if self.PROPERTY_KEYNAME_REQUIRED in self.schema:
+            value = self.schema[self.PROPERTY_KEYNAME_REQUIRED]
+            if isinstance(value, bool):
+                self._required = value
+            else:
+                valid_values = ', '.join(self.VALID_REQUIRED_VALUES)
+                attr = self.PROPERTY_KEYNAME_REQUIRED
+                TOSCAException.generate_inv_schema_property_error(self,
+                                                                  attr,
+                                                                  value,
+                                                                  valid_values)
+
+    @property
+    def status(self):
+        return self._status
+
+    def _load_status_attr_from_schema(self):
+        # IF 'status' keyname exists verify it's a valid value,
+        # if so override default
+        if self.PROPERTY_KEYNAME_STATUS in self.schema:
+            value = self.schema[self.PROPERTY_KEYNAME_STATUS]
+            if value in self.VALID_STATUS_VALUES:
+                self._status = value
+            else:
+                valid_values = ', '.join(self.VALID_STATUS_VALUES)
+                attr = self.PROPERTY_KEYNAME_STATUS
+                TOSCAException.generate_inv_schema_property_error(self,
+                                                                  attr,
+                                                                  value,
+                                                                  valid_values)
@@ -24,10 +24,10 @@ class StatefulEntityType(EntityType):
                                             'configure', 'start',
                                             'stop', 'delete']
 
-    interfaces_relationship_confiure_operations = ['post_configure_source',
-                                                   'post_configure_target',
-                                                   'add_target',
-                                                   'remove_target']
+    interfaces_relationship_configure_operations = ['post_configure_source',
+                                                    'post_configure_target',
+                                                    'add_target',
+                                                    'remove_target']
 
     def __init__(self, entitytype, prefix, custom_def=None):
         entire_entitytype = entitytype
@@ -39,6 +39,7 @@ class StatefulEntityType(EntityType):
         elif custom_def and entitytype in list(custom_def.keys()):
             self.defs = custom_def[entitytype]
         else:
+            self.defs = None
             ExceptionCollector.appendException(
                 InvalidTypeError(what=entitytype))
         self.type = entitytype
@@ -65,7 +66,7 @@ class StatefulEntityType(EntityType):
 
     def get_attributes_def_objects(self):
         '''Return a list of attribute definition objects.'''
-        attrs = self.get_value(self.ATTRIBUTES)
+        attrs = self.get_value(self.ATTRIBUTES, parent=True)
         if attrs:
             return [AttributeDef(attr, None, schema)
                     for attr, schema in attrs.items()]
diff --git a/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py b/tosca2heat/tosca-parser/toscaparser/elements/tosca_type_validation.py
new file mode 100644 (file)
index 0000000..16764bc
--- /dev/null
@@ -0,0 +1,58 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidTemplateVersion
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.extensions.exttools import ExtTools
+
+
+class TypeValidation(object):
+
+    ALLOWED_TYPE_SECTIONS = (DEFINITION_VERSION, DESCRIPTION, IMPORTS,
+                             DSL_DEFINITIONS, NODE_TYPES, REPOSITORIES,
+                             DATA_TYPES, ARTIFACT_TYPES, GROUP_TYPES,
+                             RELATIONSHIP_TYPES, CAPABILITY_TYPES,
+                             INTERFACE_TYPES, POLICY_TYPES) = \
+        ('tosca_definitions_version', 'description', 'imports',
+         'dsl_definitions', 'node_types', 'repositories',
+         'data_types', 'artifact_types', 'group_types',
+         'relationship_types', 'capability_types',
+         'interface_types', 'policy_types')
+    VALID_TEMPLATE_VERSIONS = ['tosca_simple_yaml_1_0']
+    exttools = ExtTools()
+    VALID_TEMPLATE_VERSIONS.extend(exttools.get_versions())
+
+    def __init__(self, custom_types, import_def):
+        self.import_def = import_def
+        self._validate_type_keys(custom_types)
+
+    def _validate_type_keys(self, custom_type):
+        version = custom_type[self.DEFINITION_VERSION] \
+            if self.DEFINITION_VERSION in custom_type \
+            else None
+        if version:
+            self._validate_type_version(version)
+            self.version = version
+
+        for name in custom_type:
+            if name not in self.ALLOWED_TYPE_SECTIONS:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Template ' + (self.import_def),
+                                      field=name))
+
+    def _validate_type_version(self, version):
+        if version not in self.VALID_TEMPLATE_VERSIONS:
+            ExceptionCollector.appendException(
+                InvalidTemplateVersion(
+                    what=version + ' in ' + self.import_def,
+                    valid_versions=', '. join(self.VALID_TEMPLATE_VERSIONS)))
@@ -15,10 +15,13 @@ from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import MissingRequiredFieldError
 from toscaparser.common.exception import UnknownFieldError
 from toscaparser.common.exception import ValidationError
+from toscaparser.elements.grouptype import GroupType
 from toscaparser.elements.interfaces import InterfacesDef
 from toscaparser.elements.nodetype import NodeType
+from toscaparser.elements.policytype import PolicyType
 from toscaparser.elements.relationshiptype import RelationshipType
 from toscaparser.properties import Property
+from toscaparser.utils.gettextutils import _
 
 
 class EntityTemplate(object):
@@ -30,9 +33,9 @@ class EntityTemplate(object):
                ('derived_from', 'properties', 'requirements', 'interfaces',
                 'capabilities', 'type', 'description', 'directives',
                 'attributes', 'artifacts', 'node_filter', 'copy')
-    REQUIREMENTS_SECTION = (NODE, CAPABILITY, RELATIONSHIP, OCCURRENCES) = \
+    REQUIREMENTS_SECTION = (NODE, CAPABILITY, RELATIONSHIP, OCCURRENCES, NODE_FILTER) = \
                            ('node', 'capability', 'relationship',
-                            'occurrences')
+                            'occurrences', 'node_filter')
     # Special key names
     SPECIAL_SECTIONS = (METADATA) = ('metadata')
 
@@ -56,6 +59,19 @@ class EntityTemplate(object):
                 type = self.entity_tpl['type']
             self.type_definition = RelationshipType(type,
                                                     None, custom_def)
+        if entity_name == 'policy_type':
+            type = self.entity_tpl.get('type')
+            if not type:
+                msg = (_('Policy definition of "%(pname)s" must have'
+                       ' a "type" ''attribute.') % dict(pname=name))
+                ExceptionCollector.appendException(
+                    ValidationError(msg))
+
+            self.type_definition = PolicyType(type, custom_def)
+        if entity_name == 'group_type':
+            type = self.entity_tpl.get('type')
+            self.type_definition = GroupType(type, custom_def) \
+                if type is not None else None
         self._properties = None
         self._interfaces = None
         self._requirements = None
@@ -126,13 +142,24 @@ class EntityTemplate(object):
     def _create_capabilities(self):
         capability = []
         caps = self.type_definition.get_value(self.CAPABILITIES,
-                                              self.entity_tpl)
+                                              self.entity_tpl, True)
         if caps:
             for name, props in caps.items():
                 capabilities = self.type_definition.get_capabilities()
                 if name in capabilities.keys():
                     c = capabilities[name]
-                    cap = Capability(name, props['properties'], c)
+                    properties = {}
+                    # first use the definition default value
+                    if c.properties:
+                        for property_name in c.properties.keys():
+                            prop_def = c.properties[property_name]
+                            if 'default' in prop_def:
+                                properties[property_name] = prop_def['default']
+                    # then update (if available) with the node properties
+                    if 'properties' in props and props['properties']:
+                        properties.update(props['properties'])
+
+                    cap = Capability(name, properties, c)
                     capability.append(cap)
         return capability
 
@@ -182,27 +209,31 @@ class EntityTemplate(object):
         required_props = []
         for p in entitytype.get_properties_def_objects():
             allowed_props.append(p.name)
-            if p.required:
+            # If property is 'required' and has no 'default' value then record
+            if p.required and p.default is None:
                 required_props.append(p.name)
+        # validate all required properties have values
         if properties:
+            req_props_no_value_or_default = []
             self._common_validate_field(properties, allowed_props,
                                         'properties')
             # make sure it's not missing any property required by a tosca type
-            missingprop = []
             for r in required_props:
                 if r not in properties.keys():
-                    missingprop.append(r)
-            if missingprop:
+                    req_props_no_value_or_default.append(r)
+            # Required properties found without value or a default value
+            if req_props_no_value_or_default:
                 ExceptionCollector.appendException(
                     MissingRequiredFieldError(
                         what='"properties" of template "%s"' % self.name,
-                        required=missingprop))
+                        required=req_props_no_value_or_default))
         else:
+            # Required properties in schema, but not in template
             if required_props:
                 ExceptionCollector.appendException(
                     MissingRequiredFieldError(
                         what='"properties" of template "%s"' % self.name,
-                        required=missingprop))
+                        required=required_props))
 
     def _validate_field(self, template):
         if not isinstance(template, dict):
@@ -252,16 +283,19 @@ class EntityTemplate(object):
         type_interfaces = None
         if isinstance(self.type_definition, RelationshipType):
             if isinstance(self.entity_tpl, dict):
-                for rel_def, value in self.entity_tpl.items():
-                    if rel_def != 'type':
-                        rel_def = self.entity_tpl.get(rel_def)
-                        rel = None
-                        if isinstance(rel_def, dict):
-                            rel = rel_def.get('relationship')
-                        if rel:
-                            if self.INTERFACES in rel:
-                                type_interfaces = rel[self.INTERFACES]
-                                break
+                if self.INTERFACES in self.entity_tpl:
+                    type_interfaces = self.entity_tpl[self.INTERFACES]
+                else:
+                    for rel_def, value in self.entity_tpl.items():
+                        if rel_def != 'type':
+                            rel_def = self.entity_tpl.get(rel_def)
+                            rel = None
+                            if isinstance(rel_def, dict):
+                                rel = rel_def.get('relationship')
+                            if rel:
+                                if self.INTERFACES in rel:
+                                    type_interfaces = rel[self.INTERFACES]
+                                    break
         else:
             type_interfaces = self.type_definition.get_value(self.INTERFACES,
                                                              self.entity_tpl)
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/exttools.py b/tosca2heat/tosca-parser/toscaparser/extensions/exttools.py
new file mode 100644 (file)
index 0000000..963b958
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import importlib
+import logging
+import os
+
+from toscaparser.common.exception import ToscaExtAttributeError
+from toscaparser.common.exception import ToscaExtImportError
+
+log = logging.getLogger("tosca.model")
+
+REQUIRED_ATTRIBUTES = ['VERSION', 'DEFS_FILE']
+
+
+class ExtTools(object):
+    def __init__(self):
+        self.EXTENSION_INFO = self._load_extensions()
+
+    def _load_extensions(self):
+        '''Dynamically load all the extensions .'''
+        extensions = {}
+
+        # Use the absolute path of the class path
+        abs_path = os.path.dirname(os.path.abspath(__file__))
+
+        extdirs = [e for e in os.listdir(abs_path) if
+                   not e.startswith('tests') and
+                   not e.endswith('.pyc') and not e.endswith('.py')]
+
+        for e in extdirs:
+            log.info(e)
+            extpath = abs_path + '/' + e
+            # Grab all the extension files in the given path
+            ext_files = [f for f in os.listdir(extpath) if f.endswith('.py')
+                         and not f.startswith('__init__')]
+
+            # For each module, pick out the target translation class
+            for f in ext_files:
+                log.info(f)
+                ext_name = 'toscaparser/extensions/' + e + '/' + f.strip('.py')
+                ext_name = ext_name.replace('/', '.')
+                try:
+                    extinfo = importlib.import_module(ext_name)
+                    version = getattr(extinfo, 'VERSION')
+                    defs_file = extpath + '/' + getattr(extinfo, 'DEFS_FILE')
+
+                    # Sections is an optional attribute
+                    sections = getattr(extinfo, 'SECTIONS', ())
+
+                    extensions[version] = {'sections': sections,
+                                           'defs_file': defs_file}
+                except ImportError:
+                    raise ToscaExtImportError(ext_name=ext_name)
+                except AttributeError:
+                    attrs = ', '.join(REQUIRED_ATTRIBUTES)
+                    raise ToscaExtAttributeError(ext_name=ext_name,
+                                                 attrs=attrs)
+
+        return extensions
+
+    def get_versions(self):
+        return self.EXTENSION_INFO.keys()
+
+    def get_sections(self):
+        sections = {}
+        for version in self.EXTENSION_INFO.keys():
+            sections[version] = self.EXTENSION_INFO[version]['sections']
+
+        return sections
+
+    def get_defs_file(self, version):
+        versiondata = self.EXTENSION_INFO.get(version)
+
+        if versiondata:
+            return versiondata.get('defs_file')
+        else:
+            return None
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/TOSCA_nfv_definition_1_0.yaml
new file mode 100644 (file)
index 0000000..b82250e
--- /dev/null
@@ -0,0 +1,251 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+##########################################################################
+# The content of this file reflects TOSCA NFV Profile in YAML version
+# 1.0.0. It describes the definition for TOSCA NFV types including Node Type,
+# Relationship Type, Capability Type and Interfaces.
+##########################################################################
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+##########################################################################
+# Node Type.
+# A Node Type is a reusable entity that defines the type of one or more
+# Node Templates.
+##########################################################################
+
+tosca.nodes.nfv.VNF:
+  derived_from: tosca.nodes.Root   # Or should this be its own top - level type?
+  properties:
+    id:
+      type: string
+      description: ID of this VNF
+    vendor:
+      type: string
+      description: name of the vendor who generate this VNF
+    version:
+      type: version
+      description: version of the software for this VNF
+  requirements:
+    - virtualLink:
+        capability: tosca.capabilities.nfv.VirtualLinkable
+        relationship: tosca.relationships.nfv.VirtualLinksTo
+        node: tosca.nodes.nfv.VL
+
+tosca.nodes.nfv.VDU:
+  derived_from: tosca.nodes.Compute
+  capabilities:
+    high_availability:
+      type: tosca.capabilities.nfv.HA
+    virtualbinding:
+      type: tosca.capabilities.nfv.VirtualBindable
+    monitoring_parameter:
+      type: tosca.capabilities.nfv.Metric
+  requirements:
+    - high_availability:
+        capability: tosca.capabilities.nfv.HA
+        relationship: tosca.relationships.nfv.HA
+        node: tosca.nodes.nfv.VDU
+        occurrences: [ 0, 1 ]
+
+tosca.nodes.nfv.CP:
+  derived_from: tosca.nodes.network.Port
+  properties:
+    type:
+      type: string
+      required: false
+  requirements:
+    - virtualLink:
+        capability: tosca.capabilities.VirtualLinkable
+        relationship: tosca.relationships.nfv.VirtualLinksTo
+        node: tosca.nodes.nfv.VL
+    - virtualBinding:
+        capability: tosca.capabilities.nfv.VirtualBindable
+        relationship: tosca.relationships.nfv.VirtualBindsTo
+        node: tosca.nodes.nfv.VDU
+  attributes:
+    IP_address:
+      type: string
+      required: false
+
+tosca.nodes.nfv.VL:
+  derived_from: tosca.nodes.network.Network
+  properties:
+    vendor:
+      type: string
+      required: true
+      description: name of the vendor who generate this VL
+  capabilities:
+    virtual_linkable:
+      type: tosca.capabilities.nfv.VirtualLinkable
+
+tosca.nodes.nfv.VL.ELine:
+  derived_from: tosca.nodes.nfv.VL
+  capabilities:
+    virtual_linkable:
+      occurrences: 2
+
+tosca.nodes.nfv.VL.ELAN:
+  derived_from: tosca.nodes.nfv.VL
+
+tosca.nodes.nfv.VL.ETree:
+  derived_from: tosca.nodes.nfv.VL
+
+tosca.nodes.nfv.FP:
+  derived_from: tosca.nodes.Root
+  properties:
+    policy:
+      type: string
+      required: false
+      description: name of the vendor who generate this VL
+  requirements:
+    - forwarder:
+        capability: tosca.capabilities.nfv.Forwarder
+        relationship: tosca.relationships.nfv.ForwardsTo
+
+##########################################################################
+# Relationship Type.
+# A Relationship Type is a reusable entity that defines the type of one
+# or more relationships between Node Types or Node Templates.
+##########################################################################
+
+tosca.relationships.nfv.VirtualLinksTo:
+  derived_from: tosca.relationships.network.LinksTo
+  valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]
+
+tosca.relationships.nfv.VirtualBindsTo:
+  derived_from: tosca.relationships.network.BindsTo
+  valid_target_types: [ tosca.capabilities.nfv.VirtualBindable ]
+
+tosca.relationships.nfv.HA:
+  derived_from: tosca.relationships.Root
+  valid_target_types: [ tosca.capabilities.nfv.HA ]
+
+tosca.relationships.nfv.Monitor:
+  derived_from: tosca.relationships.ConnectsTo
+  valid_target_types: [ tosca.capabilities.nfv.Metric ]
+
+tosca.relationships.nfv.ForwardsTo:
+  derived_from: tosca.relationships.root
+  valid_target_types: [ tosca.capabilities.nfv.Forwarder]
+
+##########################################################################
+# Capability Type.
+# A Capability Type is a reusable entity that describes a kind of
+# capability that a Node Type can declare to expose.
+##########################################################################
+
+tosca.capabilities.nfv.VirtualLinkable:
+  derived_from: tosca.capabilities.network.Linkable
+
+tosca.capabilities.nfv.VirtualBindable:
+  derived_from: tosca.capabilities.network.Bindable
+
+tosca.capabilities.nfv.HA:
+  derived_from: tosca.capabilities.Root
+  valid_source_types: [ tosca.nodes.nfv.VDU ]
+
+tosca.capabilities.nfv.HA.ActiveActive:
+  derived_from: tosca.capabilities.nfv.HA
+
+tosca.capabilities.nfv.HA.ActivePassive:
+  derived_from: tosca.capabilities.nfv.HA
+
+tosca.capabilities.nfv.Metric:
+  derived_from: tosca.capabilities.Root
+
+tosca.capabilities.nfv.Forwarder:
+  derived_from: tosca.capabilities.Root
+
+##########################################################################
+ # Interfaces Type.
+ # The Interfaces element describes a list of one or more interface
+ # definitions for a modelable entity (e.g., a Node or Relationship Type)
+ # as defined within the TOSCA Simple Profile specification.
+##########################################################################
+
+##########################################################################
+ # Data Type.
+ # A Datatype is a complex data type declaration which contains other
+ # complex or simple data types.
+##########################################################################
+
+##########################################################################
+ # Artifact Type.
+ # An Artifact Type is a reusable entity that defines the type of one or more
+ # files which Node Types or Node Templates can have dependent relationships
+ # and used during operations such as during installation or deployment.
+##########################################################################
+
+##########################################################################
+ # Policy Type.
+ # TOSCA Policy Types represent logical grouping of TOSCA nodes that have
+ # an implied relationship and need to be orchestrated or managed together
+ # to achieve some result.
+##########################################################################
+
+##########################################################################
+ # Group Type
+ #
+##########################################################################
+tosca.groups.nfv.VNFFG:
+  derived_from: tosca.groups.Root
+
+  properties:
+    vendor:
+      type: string
+      required: true
+      description: name of the vendor who generate this VNFFG
+
+    version:
+      type: string
+      required: true
+      description: version of this VNFFG
+
+    number_of_endpoints:
+      type: integer
+      required: true
+      description: count of the external endpoints included in this VNFFG
+
+    dependent_virtual_link:
+      type: list
+      entry_schema:
+        type: string
+      required: true
+      description: Reference to a VLD  used in this Forwarding Graph
+
+    connection_point:
+      type: list
+      entry_schema:
+        type: string
+      required: true
+      description: Reference to Connection Points forming the VNFFG
+
+    constituent_vnfs:
+      type: list
+      entry_schema:
+        type: string
+      required: true
+      description: Reference to a list of  VNFD used in this VNF Forwarding Graph
+
+    targets:
+      type: list
+      entry_schema:
+        type: string
+      required: false
+      description: list of  Network Forwarding Path within the VNFFG
+
+  requirements:
+    - forwarder:
+        capability: tosca.capabilities.nfv.Forwarder
+        relationship: tosca.relationships.nfv.ForwardsTo
+
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/nfv.py
new file mode 100644 (file)
index 0000000..0c7c2b9
--- /dev/null
@@ -0,0 +1,19 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+# VERSION and DEFS_FILE are required for all extensions
+
+VERSION = 'tosca_simple_profile_for_nfv_1_0_0'
+
+DEFS_FILE = "TOSCA_nfv_definition_1_0.yaml"
+
+SECTIONS = ('metadata')
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/__init__.py b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/tosca_helloworld_nfv.yaml b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/data/tosca_helloworld_nfv.yaml
new file mode 100644 (file)
index 0000000..6afa9f0
--- /dev/null
@@ -0,0 +1,31 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+
+description: Template for deploying a single server with predefined properties.
+
+metadata:
+  template_name: TOSCA NFV Sample Template
+
+topology_template:
+  node_templates:
+    VNF1:
+      type: tosca.nodes.nfv.VNF
+      properties:
+        id: vnf1
+        vendor: acmetelco
+        version: 1.0
+
+    VDU1:
+      type: tosca.nodes.nfv.VDU
+
+    CP1:
+      type: tosca.nodes.nfv.CP
+      properties:
+        type: vPort
+      requirements:
+        - virtualLink: PrivateNetwork
+        - virtualBinding: VDU1
+
+    PrivateNetwork:
+      type: tosca.nodes.nfv.VL
+      properties:
+        vendor: ACME Networks
diff --git a/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_nfv_tpl.py b/tosca2heat/tosca-parser/toscaparser/extensions/nfv/tests/test_tosca_nfv_tpl.py
new file mode 100644 (file)
index 0000000..b166d83
--- /dev/null
@@ -0,0 +1,29 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import os
+
+from toscaparser.tests.base import TestCase
+from toscaparser.tosca_template import ToscaTemplate
+
+
+class ToscaNFVTemplateTest(TestCase):
+
+    '''TOSCA NFV template.'''
+    tosca_tpl = os.path.join(
+        os.path.dirname(os.path.abspath(__file__)),
+        "data/tosca_helloworld_nfv.yaml")
+    tosca = ToscaTemplate(tosca_tpl)
+
+    def test_version(self):
+        self.assertEqual(self.tosca.version,
+                         "tosca_simple_profile_for_nfv_1_0_0")
@@ -18,15 +18,20 @@ import six
 from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import UnknownInputError
 from toscaparser.dataentity import DataEntity
+from toscaparser.elements.entity_type import EntityType
+from toscaparser.elements.relationshiptype import RelationshipType
 from toscaparser.utils.gettextutils import _
 
 
 GET_PROPERTY = 'get_property'
 GET_ATTRIBUTE = 'get_attribute'
 GET_INPUT = 'get_input'
+CONCAT = 'concat'
 
 SELF = 'SELF'
 HOST = 'HOST'
+TARGET = 'TARGET'
+SOURCE = 'SOURCE'
 
 HOSTED_ON = 'tosca.relationships.HostedOn'
 
@@ -119,18 +124,34 @@ class GetAttribute(Function):
 
     * { get_attribute: [ server, private_address ] }
     * { get_attribute: [ HOST, private_address ] }
+    * { get_attribute: [ HOST, private_address, 0 ] }
     """
 
     def validate(self):
-        if len(self.args) != 2:
+        if len(self.args) != 2 and len(self.args) != 3:
             ExceptionCollector.appendException(
                 ValueError(_('Illegal arguments for function "{0}". Expected '
                              'arguments: "node-template-name", '
                              '"attribute-name"').format(GET_ATTRIBUTE)))
-        self._find_node_template_containing_attribute()
+        node_tpl = self._find_node_template_containing_attribute()
+        if len(self.args) > 2:
+            # Currently we only check the first level
+            attrs_def = node_tpl.type_definition.get_attributes_def()
+            attr_def = attrs_def[self.attribute_name]
+            if attr_def.schema['type'] == "list":
+                if not isinstance(self.args[2], int):
+                    ExceptionCollector.appendException(
+                        ValueError(_('Illegal arguments for function "{0}". '
+                                     'Third argument must be a positive'
+                                     ' integer') .format(GET_ATTRIBUTE)))
+            elif attr_def.schema['type'] != "map":
+                ExceptionCollector.appendException(
+                    ValueError(_('Illegal arguments for function "{0}". '
+                                 'Expected arguments: "node-template-name", '
+                                 '"attribute-name"').format(GET_ATTRIBUTE)))
 
     def result(self):
-        return self.args
+        return self
 
     def get_referenced_node_template(self):
         """Gets the NodeTemplate instance the get_attribute function refers to.
@@ -179,7 +200,6 @@ class GetAttribute(Function):
     def _find_host_containing_attribute(self, node_template_name=SELF):
         node_template = self._find_node_template(node_template_name)
         if node_template:
-            from toscaparser.elements.entity_type import EntityType
             hosted_on_rel = EntityType.TOSCA_DEF[HOSTED_ON]
             for r in node_template.requirements:
                 for requirement, target_name in r.items():
@@ -194,6 +214,20 @@ class GetAttribute(Function):
                                 target_name)
 
     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) \
@@ -220,7 +254,7 @@ class GetProperty(Function):
 
     Arguments:
 
-    * Node template name.
+    * Node template name | SELF | HOST | SOURCE | TARGET.
     * Requirement or capability name (optional).
     * Property name.
 
@@ -239,10 +273,11 @@ class GetProperty(Function):
     * { get_property: [ mysql_server, port ] }
     * { get_property: [ SELF, db_port ] }
     * { get_property: [ SELF, database_endpoint, port ] }
+    * { get_property: [ SELF, database_endpoint, port, 1 ] }
     """
 
     def validate(self):
-        if len(self.args) < 2 or len(self.args) > 3:
+        if len(self.args) < 2:
             ExceptionCollector.appendException(
                 ValueError(_(
                     'Expected arguments: "node-template-name", "req-or-cap" '
@@ -255,15 +290,31 @@ class GetProperty(Function):
             prop = found_prop.value
             if not isinstance(prop, Function):
                 get_function(self.tosca_tpl, self.context, prop)
-        elif len(self.args) == 3:
-            get_function(self.tosca_tpl,
-                         self.context,
-                         self._find_req_or_cap_property(self.args[1],
-                                                        self.args[2]))
-        else:
-            ExceptionCollector.appendException(
-                NotImplementedError(_(
-                    'Nested properties are not supported.')))
+        elif len(self.args) >= 3:
+            # do not use _find_property to avoid raise KeyError
+            # if the prop is not found
+            # First check if there is property with this name
+            node_tpl = self._find_node_template(self.args[0])
+            props = node_tpl.get_properties() if node_tpl else []
+            index = 2
+            found = [props[self.args[1]]] if self.args[1] in props else []
+            if found:
+                property_value = found[0].value
+            else:
+                index = 3
+                # then check the req or caps
+                property_value = self._find_req_or_cap_property(self.args[1],
+                                                                self.args[2])
+            if len(self.args) > index:
+                for elem in self.args[index:]:
+                    if isinstance(property_value, list):
+                        int_elem = int(elem)
+                        property_value = self._get_index_value(property_value,
+                                                               int_elem)
+                    else:
+                        property_value = self._get_attribute_value(
+                            property_value,
+                            elem)
 
     def _find_req_or_cap_property(self, req_or_cap, property_name):
         node_tpl = self._find_node_template(self.args[0])
@@ -328,6 +379,23 @@ class GetProperty(Function):
     def _find_node_template(self, node_template_name):
         if node_template_name == SELF:
             return self.context
+        # enable the HOST value in the function
+        if node_template_name == HOST:
+            return self._find_host_containing_property()
+        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
         if not hasattr(self.tosca_tpl, 'nodetemplates'):
             return
         for node_template in self.tosca_tpl.nodetemplates:
@@ -338,10 +406,98 @@ class GetProperty(Function):
                 'Node template "{0}" was not found.'
                 ).format(node_template_name)))
 
+    def _get_index_value(self, value, index):
+        if isinstance(value, list):
+            if index < len(value):
+                return value[index]
+            else:
+                ExceptionCollector.appendException(
+                    KeyError(_(
+                        "Property '{0}' found in capability '{1}'"
+                        " referenced from node template {2}"
+                        " must have an element with index {3}.").
+                        format(self.args[2],
+                               self.args[1],
+                               self.context.name,
+                               index)))
+        else:
+            ExceptionCollector.appendException(
+                KeyError(_(
+                    "Property '{0}' found in capability '{1}'"
+                    " referenced from node template {2}"
+                    " must be a list.").format(self.args[2],
+                                               self.args[1],
+                                               self.context.name)))
+
+    def _get_attribute_value(self, value, attibute):
+        if isinstance(value, dict):
+            if attibute in value:
+                return value[attibute]
+            else:
+                ExceptionCollector.appendException(
+                    KeyError(_(
+                        "Property '{0}' found in capability '{1}'"
+                        " referenced from node template {2}"
+                        " must have an attribute named {3}.").
+                        format(self.args[2],
+                               self.args[1],
+                               self.context.name,
+                               attibute)))
+        else:
+            ExceptionCollector.appendException(
+                KeyError(_(
+                    "Property '{0}' found in capability '{1}'"
+                    " referenced from node template {2}"
+                    " must be a dict.").format(self.args[2],
+                                               self.args[1],
+                                               self.context.name)))
+
+    # Add this functions similar to get_attribute case
+    def _find_host_containing_property(self, node_template_name=SELF):
+        node_template = self._find_node_template(node_template_name)
+        hosted_on_rel = EntityType.TOSCA_DEF[HOSTED_ON]
+        for r in node_template.requirements:
+            for requirement, target_name in r.items():
+                target_node = self._find_node_template(target_name)
+                target_type = target_node.type_definition
+                for capability in target_type.get_capabilities_objects():
+                    if capability.type in hosted_on_rel['valid_target_types']:
+                        if self._property_exists_in_type(target_type):
+                            return target_node
+                        return self._find_host_containing_property(
+                            target_name)
+        return None
+
+    def _property_exists_in_type(self, type_definition):
+        props_def = type_definition.get_properties_def()
+        found = [props_def[self.args[1]]] \
+            if self.args[1] in props_def else []
+        return len(found) == 1
+
     def result(self):
-        if len(self.args) == 3:
-            property_value = self._find_req_or_cap_property(self.args[1],
-                                                            self.args[2])
+        if len(self.args) >= 3:
+            # First check if there is property with this name
+            node_tpl = self._find_node_template(self.args[0])
+            props = node_tpl.get_properties() if node_tpl else []
+            index = 2
+            found = [props[self.args[1]]] if self.args[1] in props else []
+            if found:
+                property_value = found[0].value
+            else:
+                index = 3
+                # then check the req or caps
+                property_value = self._find_req_or_cap_property(self.args[1],
+                                                                self.args[2])
+            if len(self.args) > index:
+                for elem in self.args[index:]:
+                    if isinstance(property_value, list):
+                        int_elem = int(elem)
+                        property_value = self._get_index_value(property_value,
+                                                               int_elem)
+                    else:
+                        property_value = self._get_attribute_value(
+                            property_value,
+                            elem)
         else:
             property_value = self._find_property(self.args[1]).value
         if isinstance(property_value, Function):
@@ -367,10 +523,39 @@ class GetProperty(Function):
         return None
 
 
+class Concat(Function):
+    """Validate the function and provide an instance of the function
+
+    Concatenation of values are supposed to be produced at runtime and
+    therefore its the responsibility of the TOSCA engine to implement the
+    evaluation of Concat functions.
+
+    Arguments:
+
+    * List of strings that needs to be concatenated
+
+    Example:
+
+      [ 'http://',
+        get_attribute: [ server, public_address ],
+        ':' ,
+        get_attribute: [ server, port ] ]
+    """
+
+    def validate(self):
+        if len(self.args) < 1:
+            ExceptionCollector.appendException(
+                ValueError(_('Invalid arguments for function "{0}". Expected '
+                             'at least one arguments.').format(CONCAT)))
+
+    def result(self):
+        return self
+
 function_mappings = {
     GET_PROPERTY: GetProperty,
     GET_INPUT: GetInput,
-    GET_ATTRIBUTE: GetAttribute
+    GET_ATTRIBUTE: GetAttribute,
+    CONCAT: Concat
 }
 
 
diff --git a/tosca2heat/tosca-parser/toscaparser/groups.py b/tosca2heat/tosca-parser/toscaparser/groups.py
new file mode 100644 (file)
index 0000000..5fd5dec
--- /dev/null
@@ -0,0 +1,55 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.entity_template import EntityTemplate
+from toscaparser.utils import validateutils
+
+SECTIONS = (TYPE, METADATA, DESCRIPTION, PROPERTIES, TARGETS, INTERFACES) = \
+           ('type', 'metadata', 'description',
+            'properties', 'members', 'interfaces')
+
+
+class Group(EntityTemplate):
+
+    def __init__(self, name, group_templates, member_nodes, custom_defs=None):
+        super(Group, self).__init__(name,
+                                    group_templates,
+                                    'group_type',
+                                    custom_defs)
+        self.name = name
+        self.tpl = group_templates
+        self.meta_data = None
+        if self.METADATA in self.tpl:
+            self.meta_data = self.tpl.get(self.METADATA)
+            validateutils.validate_map(self.meta_data)
+        self.member_nodes = member_nodes
+        self._validate_keys()
+
+    @property
+    def members(self):
+        return self.entity_tpl.get('members')
+
+    @property
+    def description(self):
+        return self.entity_tpl.get('description')
+
+    def get_member_nodes(self):
+        return self.member_nodes
+
+    def _validate_keys(self):
+        for key in self.entity_tpl.keys():
+            if key not in SECTIONS:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Groups "%s"' % self.name,
+                                      field=key))
@@ -17,6 +17,7 @@ from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import MissingRequiredFieldError
 from toscaparser.common.exception import UnknownFieldError
 from toscaparser.common.exception import ValidationError
+from toscaparser.elements.tosca_type_validation import TypeValidation
 from toscaparser.utils.gettextutils import _
 import toscaparser.utils.urlutils
 import toscaparser.utils.yamlparser
@@ -31,14 +32,18 @@ class ImportsLoader(object):
                       ('file', 'repository', 'namespace_uri',
                        'namespace_prefix')
 
-    def __init__(self, importslist, path, type_definition_list=None):
+    def __init__(self, importslist, path, type_definition_list=None,
+                 tpl=None):
         self.importslist = importslist
         self.custom_defs = {}
-        if not path:
+        if not path and not tpl:
             msg = _('Input tosca template is not provided.')
             log.warning(msg)
             ExceptionCollector.appendException(ValidationError(message=msg))
         self.path = path
+        self.repositories = {}
+        if tpl and tpl.get('repositories'):
+            self.repositories = tpl.get('repositories')
         self.type_definition_list = []
         if type_definition_list:
             if isinstance(type_definition_list, list):
@@ -73,14 +78,22 @@ class ImportsLoader(object):
 
                     custom_type = self._load_import_template(import_name,
                                                              import_uri)
-                    self._update_custom_def(custom_type)
+                    namespace_prefix = None
+                    if isinstance(import_uri, dict):
+                        namespace_prefix = import_uri.get(
+                            self.NAMESPACE_PREFIX)
+                    if custom_type:
+                        TypeValidation(custom_type, import_def)
+                        self._update_custom_def(custom_type, namespace_prefix)
             else:  # old style of imports
                 custom_type = self._load_import_template(None,
                                                          import_def)
                 if custom_type:
-                    self._update_custom_def(custom_type)
+                    TypeValidation(
+                        custom_type, import_def)
+                    self._update_custom_def(custom_type, None)
 
-    def _update_custom_def(self, custom_type):
+    def _update_custom_def(self, custom_type, namespace_prefix):
         outer_custom_types = {}
         for type_def in self.type_definition_list:
             outer_custom_types = custom_type.get(type_def)
@@ -88,7 +101,16 @@ class ImportsLoader(object):
                 if type_def == "imports":
                     self.custom_defs.update({'imports': outer_custom_types})
                 else:
-                    self.custom_defs.update(outer_custom_types)
+                    if namespace_prefix:
+                        prefix_custom_types = {}
+                        for type_def_key in outer_custom_types.keys():
+                            namespace_prefix_to_key = (namespace_prefix +
+                                                       "." + type_def_key)
+                            prefix_custom_types[namespace_prefix_to_key] = \
+                                outer_custom_types[type_def_key]
+                        self.custom_defs.update(prefix_custom_types)
+                    else:
+                        self.custom_defs.update(outer_custom_types)
 
     def _validate_import_keys(self, import_name, import_uri_def):
         if self.FILE not in import_uri_def.keys():
@@ -122,6 +144,8 @@ class ImportsLoader(object):
         +----------+--------+------------------------------+
         | file     | file   | OK                           |
         | file     | URL    | OK                           |
+        | preparsed| file   | file must be a full path     |
+        | preparsed| URL    | OK                           |
         | URL      | file   | file must be a relative path |
         | URL      | URL    | OK                           |
         +----------+--------+------------------------------+
@@ -132,13 +156,9 @@ class ImportsLoader(object):
             self._validate_import_keys(import_name, import_uri_def)
             file_name = import_uri_def.get(self.FILE)
             repository = import_uri_def.get(self.REPOSITORY)
-            namespace_uri = import_uri_def.get(self.NAMESPACE_URI)
-            # TODO(anyone) : will be extended this namespace_prefix in
-            # the next patch after design discussion with PTL.
-            # namespace_prefix = import_uri_def.get(self.NAMESPACE_PREFIX)
         else:
             file_name = import_uri_def
-            namespace_uri = None
+            repository = None
             short_import_notation = True
 
         if not file_name:
@@ -151,30 +171,62 @@ class ImportsLoader(object):
 
         if toscaparser.utils.urlutils.UrlUtils.validate_url(file_name):
             return YAML_LOADER(file_name, False)
-        elif not namespace_uri:
+        elif not repository:
             import_template = None
-            a_file = True
-            main_a_file = os.path.isfile(self.path)
-            if main_a_file:
-                if os.path.isfile(file_name):
+            if self.path:
+                if toscaparser.utils.urlutils.UrlUtils.validate_url(self.path):
+                    if os.path.isabs(file_name):
+                        msg = (_('Absolute file name "%(name)s" cannot be '
+                                 'used in a URL-based input template '
+                                 '"%(template)s".')
+                               % {'name': file_name, 'template': self.path})
+                        log.error(msg)
+                        ExceptionCollector.appendException(ImportError(msg))
+                        return
+                    import_template = toscaparser.utils.urlutils.UrlUtils.\
+                        join_url(self.path, file_name)
+                    a_file = False
+                else:
+                    a_file = True
+                    main_a_file = os.path.isfile(self.path)
+
+                    if main_a_file:
+                        if os.path.isfile(file_name):
+                            import_template = file_name
+                        else:
+                            full_path = os.path.join(
+                                os.path.dirname(os.path.abspath(self.path)),
+                                file_name)
+                            if os.path.isfile(full_path):
+                                import_template = full_path
+                            else:
+                                file_path = file_name.rpartition("/")
+                                dir_path = os.path.dirname(os.path.abspath(
+                                    self.path))
+                                if file_path[0] != '' and dir_path.endswith(
+                                    file_path[0]):
+                                        import_template = dir_path + "/" +\
+                                            file_path[2]
+                                        if not os.path.isfile(import_template):
+                                            msg = (_('"%(import_template)s" is'
+                                                     'not a valid file')
+                                                   % {'import_template':
+                                                      import_template})
+                                            log.error(msg)
+                                            ExceptionCollector.appendException
+                                            (ValueError(msg))
+            else:  # template is pre-parsed
+                if os.path.isabs(file_name) and os.path.isfile(file_name):
+                    a_file = True
                     import_template = file_name
                 else:
-                    full_path = os.path.join(
-                        os.path.dirname(os.path.abspath(self.path)),
-                        file_name)
-                    if os.path.isfile(full_path):
-                        import_template = full_path
-            else:  # main_a_url
-                if os.path.isabs(file_name):
-                    msg = (_('Absolute file name "%(name)s" cannot be used '
-                             'in a URL-based input template "%(template)s".')
-                           % {'name': file_name, 'template': self.path})
+                    msg = (_('Relative file name "%(name)s" cannot be used '
+                             'in a pre-parsed input template.')
+                           % {'name': file_name})
                     log.error(msg)
                     ExceptionCollector.appendException(ImportError(msg))
                     return
-                import_template = toscaparser.utils.urlutils.UrlUtils.\
-                    join_url(self.path, file_name)
-                a_file = False
+
             if not import_template:
                 log.error(_('Import "%(name)s" is not valid.') %
                           {'name': import_uri_def})
@@ -188,21 +240,31 @@ class ImportsLoader(object):
             log.error(_('Import "%(name)s" is not valid.') % import_uri_def)
             ExceptionCollector.appendException(
                 ImportError(_('Import "%s" is not valid.') % import_uri_def))
+            return
 
-        # Remove leading, ending spaces and strip the last character if "/"
-        namespace_uri = ((namespace_uri).strip()).rstrip("//")
+        full_url = ""
+        if repository:
+            if self.repositories:
+                for repo_name, repo_def in self.repositories.items():
+                    if repo_name == repository:
+                        # Remove leading, ending spaces and strip
+                        # the last character if "/"
+                        repo_url = ((repo_def['url']).strip()).rstrip("//")
+                        full_url = repo_url + "/" + file_name
 
-        if toscaparser.utils.urlutils.UrlUtils.validate_url(namespace_uri):
-            full_url = None
-            if repository:
-                repository = ((repository).strip()).rstrip("//")
-                full_url = namespace_uri + "/" + repository + "/" + file_name
-            else:
-                full_url = namespace_uri + "/" + file_name
+            if not full_url:
+                msg = (_('referenced repository "%(n_uri)s" in import '
+                         'definition "%(tpl)s" not found.')
+                       % {'n_uri': repository, 'tpl': import_name})
+                log.error(msg)
+                ExceptionCollector.appendException(ImportError(msg))
+                return
+
+        if toscaparser.utils.urlutils.UrlUtils.validate_url(full_url):
             return YAML_LOADER(full_url, False)
         else:
-            msg = (_('namespace_uri "%(n_uri)s" is not valid in import '
+            msg = (_('repository url "%(n_uri)s" is not valid in import '
                      'definition "%(tpl)s".')
-                   % {'n_uri': namespace_uri, 'tpl': import_name})
+                   % {'n_uri': repo_url, 'tpl': import_name})
             log.error(msg)
             ExceptionCollector.appendException(ImportError(msg))
@@ -18,6 +18,7 @@ from toscaparser.common.exception import InvalidPropertyValueError
 from toscaparser.common.exception import MissingRequiredFieldError
 from toscaparser.common.exception import TypeMismatchError
 from toscaparser.common.exception import UnknownFieldError
+from toscaparser.common.exception import ValidationError
 from toscaparser.dataentity import DataEntity
 from toscaparser.elements.interfaces import CONFIGURE
 from toscaparser.elements.interfaces import CONFIGURE_SHORTNAME
@@ -93,22 +94,30 @@ class NodeTemplate(EntityTemplate):
             # check if it's type has relationship defined
             if not relationship:
                 parent_reqs = self.type_definition.get_all_requirements()
-                for key in req.keys():
-                    for req_dict in parent_reqs:
-                        if key in req_dict.keys():
-                            relationship = (req_dict.get(key).
-                                            get('relationship'))
-                            break
+                if parent_reqs is None:
+                    ExceptionCollector.appendException(
+                        ValidationError(message='parent_req is ' +
+                                        str(parent_reqs)))
+                else:
+                    for key in req.keys():
+                        for req_dict in parent_reqs:
+                            if key in req_dict.keys():
+                                relationship = (req_dict.get(key).
+                                                get('relationship'))
+                                break
             if relationship:
                 found_relationship_tpl = False
                 # apply available relationship templates if found
-                for tpl in self.available_rel_tpls:
-                    if tpl.name == relationship:
-                        rtype = RelationshipType(tpl.type, None,
-                                                 self.custom_def)
-                        explicit_relation[rtype] = related_tpl
-                        self.relationship_tpl.append(tpl)
-                        found_relationship_tpl = True
+                if self.available_rel_tpls:
+                    for tpl in self.available_rel_tpls:
+                        if tpl.name == relationship:
+                            rtype = RelationshipType(tpl.type, None,
+                                                     self.custom_def)
+                            explicit_relation[rtype] = related_tpl
+                            tpl.target = related_tpl
+                            tpl.source = self
+                            self.relationship_tpl.append(tpl)
+                            found_relationship_tpl = True
                 # create relationship template object.
                 rel_prfx = self.type_definition.RELATIONSHIP_PREFIX
                 if not found_relationship_tpl:
@@ -130,7 +139,8 @@ class NodeTemplate(EntityTemplate):
                         if rtype.type == relationship:
                             explicit_relation[rtype] = related_tpl
                             related_tpl._add_relationship_template(req,
-                                                                   rtype.type)
+                                                                   rtype.type,
+                                                                   self)
                         elif self.available_rel_types:
                             if relationship in self.available_rel_types.keys():
                                 rel_type_def = self.available_rel_types.\
@@ -144,13 +154,13 @@ class NodeTemplate(EntityTemplate):
                                         explicit_relation[rtype] = related_tpl
                                         related_tpl.\
                                             _add_relationship_template(
-                                                req, rtype.type)
+                                                req, rtype.type, self)
         return explicit_relation
 
-    def _add_relationship_template(self, requirement, rtype):
+    def _add_relationship_template(self, requirement, rtype, source):
         req = requirement.copy()
         req['type'] = rtype
-        tpl = RelationshipTemplate(req, rtype, None)
+        tpl = RelationshipTemplate(req, rtype, self.custom_def, self, source)
         self.relationship_tpl.append(tpl)
 
     def get_relationship_template(self):
@@ -244,7 +254,7 @@ class NodeTemplate(EntityTemplate):
                     elif name in (CONFIGURE, CONFIGURE_SHORTNAME):
                         self._common_validate_field(
                             value, InterfacesDef.
-                            interfaces_relationship_confiure_operations,
+                            interfaces_relationship_configure_operations,
                             'interfaces')
                     else:
                         ExceptionCollector.appendException(
diff --git a/tosca2heat/tosca-parser/toscaparser/policy.py b/tosca2heat/tosca-parser/toscaparser/policy.py
new file mode 100644 (file)
index 0000000..61c09ec
--- /dev/null
@@ -0,0 +1,77 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+import logging
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.entity_template import EntityTemplate
+from toscaparser.triggers import Triggers
+from toscaparser.utils import validateutils
+
+
+SECTIONS = (TYPE, METADATA, DESCRIPTION, PROPERTIES, TARGETS, TRIGGERS) = \
+           ('type', 'metadata', 'description',
+            'properties', 'targets', 'triggers')
+
+log = logging.getLogger('tosca')
+
+
+class Policy(EntityTemplate):
+    '''Policies defined in Topology template.'''
+    def __init__(self, name, policy, targets, targets_type, custom_def=None):
+        super(Policy, self).__init__(name,
+                                     policy,
+                                     'policy_type',
+                                     custom_def)
+        self.meta_data = None
+        if self.METADATA in policy:
+            self.meta_data = policy.get(self.METADATA)
+            validateutils.validate_map(self.meta_data)
+        self.targets_list = targets
+        self.targets_type = targets_type
+        self.triggers = self._triggers(policy.get(TRIGGERS))
+        self._validate_keys()
+
+    @property
+    def targets(self):
+        return self.entity_tpl.get('targets')
+
+    @property
+    def description(self):
+        return self.entity_tpl.get('description')
+
+    @property
+    def metadata(self):
+        return self.entity_tpl.get('metadata')
+
+    def get_targets_type(self):
+        return self.targets_type
+
+    def get_targets_list(self):
+        return self.targets_list
+
+    def _triggers(self, triggers):
+        triggerObjs = []
+        if triggers:
+            for name, trigger_tpl in triggers.items():
+                triggersObj = Triggers(name, trigger_tpl)
+                triggerObjs.append(triggersObj)
+        return triggerObjs
+
+    def _validate_keys(self):
+        for key in self.entity_tpl.keys():
+            if key not in SECTIONS:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Policy "%s"' % self.name,
+                                      field=key))
diff --git a/tosca2heat/tosca-parser/toscaparser/prereq/__init__.py b/tosca2heat/tosca-parser/toscaparser/prereq/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
@@ -26,12 +26,15 @@ log = logging.getLogger('tosca')
 
 class RelationshipTemplate(EntityTemplate):
     '''Relationship template.'''
-    def __init__(self, relationship_template, name, custom_def=None):
+    def __init__(self, relationship_template, name, custom_def=None,
+                 target=None, source=None):
         super(RelationshipTemplate, self).__init__(name,
                                                    relationship_template,
                                                    'relationship_type',
                                                    custom_def)
         self.name = name.lower()
+        self.target = target
+        self.source = source
 
     def get_properties_objects(self):
         '''Return properties objects for this template.'''
@@ -43,6 +46,13 @@ class RelationshipTemplate(EntityTemplate):
         props = []
         properties = {}
         relationship = self.entity_tpl.get('relationship')
+
+        if not relationship:
+            for value in self.entity_tpl.values():
+                if isinstance(value, dict):
+                    relationship = value.get('relationship')
+                    break
+
         if relationship:
             properties = self.type_definition.get_value(self.PROPERTIES,
                                                         relationship) or {}
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/__init__.py b/tosca2heat/tosca-parser/toscaparser/tests/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip
new file mode 100644 (file)
index 0000000..9dc6c9a
Binary files /dev/null and b/tosca2heat/tosca-parser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip differ
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml
new file mode 100644 (file)
index 0000000..3487433
--- /dev/null
@@ -0,0 +1,13 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Compute node type with a list attribute
+
+node_types:
+  tosca.nodes.ComputeWithAttrList:
+    derived_from: tosca.nodes.Compute
+    attributes:
+      attr_list:
+        type: map
+        entry_schema:
+          type: string
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_prop.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/compute_with_prop.yaml
new file mode 100644 (file)
index 0000000..93a82af
--- /dev/null
@@ -0,0 +1,13 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  Compute node type with a parameter for the get property with host test
+
+node_types:
+  tosca.nodes.ComputeWithProp:
+    derived_from: tosca.nodes.Compute
+    properties:
+      test:
+        required: false
+        type: integer
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_caps_def.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_caps_def.yaml
new file mode 100644 (file)
index 0000000..337c38f
--- /dev/null
@@ -0,0 +1,22 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  Definition of a node with a capiblity and a parent capability
+  defined in an imported file
+
+capability_types:
+
+  tosca.capabilities.SomeCap:
+    derived_from: tosca.capabilities.Root
+
+  tosca.capabilities.SomeChildCap:
+    derived_from: tosca.capabilities.SomeCap
+
+node_types:
+
+  tosca.nodes.SomeNode:
+    derived_from: tosca.nodes.Root
+    capabilities:
+        lrms:
+          type: tosca.capabilities.SomeChildCap
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml
new file mode 100644 (file)
index 0000000..cf5c2b4
--- /dev/null
@@ -0,0 +1,23 @@
+node_types:
+  tosca.nodes.HACompute:
+    derived_from: tosca.nodes.Compute
+    capabilities:
+      high_availability:
+        type: tosca.capabilities.HA
+    requirements:
+      - high_availability:
+          capability: tosca.capabilities.HA
+          relationship: tosca.relationships.HA
+          node: tosca.nodes.HACompute
+          occurences: [ 0, 1 ]
+
+relationship_types:
+  tosca.relationships.HA:
+    derived_from: tosca.relationships.Root
+    valid_target_types: [ tosca.capabilities.HA ]
+
+capability_types:
+  tosca.capabilities.HA:
+    derived_from: tosca.capabilities.Root
+    valid_source_types: [ tosca.nodes.HACompute ]
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/db_with_list_param.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/db_with_list_param.yaml
new file mode 100644 (file)
index 0000000..57ce279
--- /dev/null
@@ -0,0 +1,10 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+node_types:
+  tosca.nodes.DatabaseWithListParam:
+    derived_from: tosca.nodes.Database
+    properties:
+      list_prop:
+        type: list
+        entry_schema:
+          type: integer
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
new file mode 100644 (file)
index 0000000..70d0b0f
--- /dev/null
@@ -0,0 +1,34 @@
+tosca1_definitions_version: tosca_simple_yaml_1_0
+tosca_definitions_version: tosca_simple_yaml_1_10
+
+descriptions: >
+  Pizza store app that allows you to explore the features provided by PayPal's REST APIs.
+  More detail can be found at https://github.com/paypal/rest-api-sample-app-nodejs/
+
+node_typess:
+node_types:
+  tosca.nodes.SoftwareComponent.Logstash:
+    derived_from: tosca.nodes.SoftwareComponent
+    requirements:
+        - search_endpoint:
+            capability: tosca.capabilities.Endpoint
+            node: tosca.nodes.SoftwareComponent.Elasticsearch
+            relationship:
+              type: tosca.relationships.ConnectsTo
+              interfaces:
+                Configure:
+                  pre_configure_source:
+                    inputs:
+                      elasticsearch_ip:
+                        type: string
+    capabilities1:
+      log_endpoint:
+         type: tosca.capabilities.Endpoint
+policy_types1:
+policy_types:
+  mycompany.mytypes.myScalingPolicy:
+    derived1_from: tosca.policies.Scaling
+    metadata:
+     type: map
+     entry_schema:
+       type: string
@@ -8,7 +8,7 @@ imports:
        file: custom_types/logstash.yaml
 
 node_types:
-  tosca.nodes.SoftwareComponent.Rsyslog:
+  Rsyslog:
     derived_from: tosca.nodes.SoftwareComponent
     requirements:
       - log_endpoint:
@@ -1,9 +1,18 @@
 tosca_definitions_version: tosca_simple_yaml_1_0
 imports:
-  -  rsyslog: custom_types/nested_rsyslog.yaml
+  - test_prefix_defs:
+      file: custom_types/nested_rsyslog.yaml
+      namespace_prefix: test_namespace_prefix
+  - test_second_time_with_another_prefix:
+      file: custom_types/nested_rsyslog.yaml
+      namespace_prefix: test_2nd_namespace_prefix
+
 node_types:
   tosca.nodes.SoftwareComponent.Rsyslog.TestRsyslogType:
-    derived_from: tosca.nodes.SoftwareComponent.Rsyslog
+    derived_from: test_namespace_prefix.Rsyslog
+
+  Test2ndRsyslogType:
+    derived_from: test_2nd_namespace_prefix.Rsyslog
 
   tosca.nodes.WebApplication.WordPress:
     derived_from: tosca.nodes.WebApplication
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/node_with_cap.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/custom_types/node_with_cap.yaml
new file mode 100644 (file)
index 0000000..11e1b51
--- /dev/null
@@ -0,0 +1,30 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  Node type that has a requirement of a capability with a defined value
+
+node_types:
+  tosca.capabilities.SomeCap:
+    derived_from: tosca.capabilities.Root
+    properties:
+      type:
+        type: string
+        required: true
+        default: someval
+        constraints:
+          - equal: someval
+
+  tosca.nodes.SomeNode:
+    derived_from: tosca.nodes.Root
+    requirements:
+      - some_req:
+          capability: tosca.capabilities.SomeCap
+          node: tosca.nodes.NodeWithCap
+          relationship: tosca.relationships.HostedOn
+
+  tosca.nodes.NodeWithCap:
+    derived_from: tosca.nodes.Root
+    capabilities:
+        some_req:
+          type: tosca.capabilities.SomeCap
+
@@ -9,7 +9,7 @@ node_types:
     derived_from: tosca.nodes.WebApplication
     properties:
       github_url:
-        required: no
+        required: false
         type: string
         description: location of the application on the github.
         default: https://github.com/sample.git
@@ -10,7 +10,7 @@ node_types:
       people:
         type: tosca.my.datatypes.People
 
-datatype_definitions:
+data_types:
   tosca.my.datatypes.PeopleBase:
     properties:
       name:
@@ -20,6 +20,7 @@ datatype_definitions:
           - min_length: 2
       gender:
         type: string
+        required: false
         default: unknown
 
   tosca.my.datatypes.People:
@@ -27,10 +28,12 @@ datatype_definitions:
     properties:
       addresses:
         type: map
+        required: false
         entry_schema:
           type: string
       contacts:
         type: list
+        required: false
         entry_schema:
           type: tosca.my.datatypes.ContactInfo
 
@@ -44,5 +47,7 @@ datatype_definitions:
           - min_length: 2
       contact_email:
         type: string
+        required: false
       contact_phone:
         type: string
+        required: false
@@ -10,7 +10,7 @@ node_types:
       people:
         type: tosca.my.datatypes.People
 
-datatype_definitions:
+data_types:
   tosca.my.datatypes.PeopleBase:
     properties:
       name:
@@ -20,6 +20,7 @@ datatype_definitions:
           - min_length: 2
       gender:
         type: string
+        required: false
         default: unknown
 
   tosca.my.datatypes.People:
@@ -27,10 +28,12 @@ datatype_definitions:
     properties:
       addresses:
         type: map
+        required: false
         entry_schema:
           type: string
       contacts:
         type: list
+        required: false
         entry_schema:
           type: tosca.my.datatypes.ContactInfo
 
@@ -44,8 +47,10 @@ datatype_definitions:
           - min_length: 2
       contact_email:
         type: string
+        required: false
       contact_phone:
         type: string
+        required: false
 
 topology_template:
   node_templates:
@@ -62,4 +67,4 @@ topology_template:
               contact_phone: '123456789'}
             - {contact_name: Jerry,
               contact_email: jerry@email.com,
-              contact_phone: '321654987'}
\ No newline at end of file
+              contact_phone: '321654987'}
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml
new file mode 100644 (file)
index 0000000..f0bec84
--- /dev/null
@@ -0,0 +1,25 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile to test the attribute inheritance
+
+imports:
+  - ../custom_types/node_with_cap.yaml
+
+topology_template:
+
+  node_templates:
+
+    some_node:
+      type: tosca.nodes.SomeNode
+      requirements:
+        - some_req: node_cap
+      interfaces:
+        Standard:
+          configure:
+            implementation: some_script.sh
+            inputs:
+              some_input: { get_property: [ SELF, some_req, type ] }
+
+    node_cap:
+      type: tosca.nodes.NodeWithCap
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat.yaml
new file mode 100644 (file)
index 0000000..22fcfb4
--- /dev/null
@@ -0,0 +1,30 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with concat function.
+
+topology_template:
+  node_templates:
+    server:
+      type: tosca.nodes.Compute
+      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
+  outputs:
+    url:
+      description: Concatenate the URL for a server from template values.
+      value: { concat: [ 'http://',
+                         get_attribute: [ server, public_address ],
+                         ':' ,
+                         get_attribute: [ server, port ] ] }
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat_invalid.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_concat_invalid.yaml
new file mode 100644 (file)
index 0000000..7c7b0aa
--- /dev/null
@@ -0,0 +1,9 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template for deploying a single server with invalid concat function.
+
+topology_template:
+  outputs:
+    invalid_concat_syntax:
+      description: test concat with invalid syntax.
+      value: { concat: []}
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml
new file mode 100644 (file)
index 0000000..047387f
--- /dev/null
@@ -0,0 +1,30 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA template for testing get_attribute with TARGET ans SOURCE keywords.
+
+topology_template:
+
+  node_templates:
+
+    mysql:
+      type: tosca.nodes.DBMS
+      properties:
+        root_password: rootpw
+        port: 3306
+      requirements:
+        - host:
+            node: db_server
+            relationship:
+              type: tosca.relationships.HostedOn
+              interfaces:
+                Configure:
+                  pre_configure_source:
+                    implementation: some_script.sh
+                    inputs:
+                      target_test: { get_attribute: [ TARGET, public_address ] }
+                      source_port: { get_attribute: [ SOURCE, tosca_name ] }
+
+    db_server:
+      type: tosca.nodes.Compute
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml
new file mode 100644 (file)
index 0000000..5766490
--- /dev/null
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA template for testing get_attribute with a list attribute and an index
+
+imports:
+  - ../custom_types/compute_with_attribute_list.yaml
+
+topology_template:
+  node_templates:
+    server:
+      type: tosca.nodes.ComputeWithAttrList
+      interfaces:
+        Standard:
+          configure:
+            implementation: configure.sh
+            inputs:
+              ip_address: { get_attribute: [ SELF, attr_list, 0 ] }
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml
new file mode 100644 (file)
index 0000000..88a2721
--- /dev/null
@@ -0,0 +1,19 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA template for testing get_attribute with a list attribute and an index
+
+imports:
+  - ../custom_types/compute_with_attribute_list.yaml
+
+topology_template:
+  node_templates:
+    server:
+      type: tosca.nodes.ComputeWithAttrList
+      interfaces:
+        Standard:
+          configure:
+            implementation: configure.sh
+            inputs:
+              ip_address: { get_attribute: [ SELF, private_address, 0 ] }
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml
new file mode 100644 (file)
index 0000000..c460257
--- /dev/null
@@ -0,0 +1,35 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA template for testing get_property with TARGET ans SOURCE keywords.
+
+imports:
+  - ../custom_types/compute_with_prop.yaml
+
+topology_template:
+
+  node_templates:
+
+    mysql:
+      type: tosca.nodes.DBMS
+      properties:
+        root_password: rootpw
+        port: 3306
+      requirements:
+        - host:
+            node: db_server
+            relationship:
+              type: tosca.relationships.HostedOn
+              interfaces:
+                Configure:
+                  pre_configure_source:
+                    implementation: some_script.sh
+                    inputs:
+                      target_test: { get_property: [ TARGET, test ] }
+                      source_port: { get_property: [ SOURCE, port ] }
+
+    db_server:
+      type: tosca.nodes.ComputeWithProp
+      properties:
+        test: 1
+
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
new file mode 100644 (file)
index 0000000..1ca69ca
--- /dev/null
@@ -0,0 +1,65 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA simple profile to test the get property function with HOST parameter
+
+imports:
+  - ../custom_types/compute_with_prop.yaml
+
+topology_template:
+  inputs:
+    db_name:
+      type: string
+      description: The name of the database.
+      default: wordpress
+    db_user:
+      type: string
+      description: The user name of the DB user.
+      default: wp_user
+    db_pwd:
+      type: string
+      description: The WordPress database admin account password.
+      default: wp_pass
+    db_root_pwd:
+      type: string
+      description: Root password for MySQL.
+    db_port:
+      type: PortDef
+      description: Port for the MySQL database.
+      default: 3306
+
+  node_templates:
+
+    mysql_database:
+      type: tosca.nodes.Database
+      properties:
+        name: { get_input: db_name }
+        user: { get_input: db_user }
+        password: { get_input: db_pwd }
+      capabilities:
+        database_endpoint:
+          properties:
+            port: { get_input: db_port }
+      requirements:
+        - host: mysql_dbms
+      interfaces:
+        Standard:
+          configure:
+            implementation: mysql/mysql_database_configure.sh
+            inputs:
+              db_port: { get_property: [ HOST, port ] }
+              test: { get_property: [ HOST, test ] }
+
+    mysql_dbms:
+      type: tosca.nodes.DBMS
+      properties:
+        root_password: { get_input: db_root_pwd }
+        port: { get_input: db_port }
+      requirements:
+        - host: server
+
+    server:
+      type: tosca.nodes.ComputeWithProp
+      properties:
+        test: 1
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml
new file mode 100644 (file)
index 0000000..8fb7b96
--- /dev/null
@@ -0,0 +1,47 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile with nested property names or indexes.
+
+imports:
+  - ../custom_types/wordpress.yaml
+  - ../custom_types/db_with_list_param.yaml
+
+topology_template:
+
+  node_templates:
+
+    wordpress:
+      type: tosca.nodes.WebApplication.WordPress
+      requirements:
+        - host: server
+        - database_endpoint: mysql_database
+      interfaces:
+        Standard:
+          configure:
+            implementation: wordpress/wordpress_configure.sh
+            inputs:
+              wp_endpoint_protocol: { get_property: [ SELF, database_endpoint, ports, user_port, protocol ] }
+              wp_list_prop: { get_property: [ mysql_database, list_prop, 2 ] }
+
+    mysql_database:
+      type: tosca.nodes.DatabaseWithListParam
+      properties:
+        list_prop: [1,2,3]
+      capabilities:
+        database_endpoint:
+          properties:
+            ports:
+              user_port:
+                protocol: tcp
+                target: 50000
+                source: 9000
+      requirements:
+        - host: mysql_dbms
+
+    mysql_dbms:
+      type: tosca.nodes.DBMS
+      requirements:
+        - host: server
+
+    server:
+      type: tosca.nodes.Compute
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/groups/definitions.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/groups/definitions.yaml
new file mode 100644 (file)
index 0000000..40c1d8b
--- /dev/null
@@ -0,0 +1,10 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+group_types:
+  mycompany.mytypes.groups.placement:
+    description: My company's group type for placing nodes of type Compute
+    members: [ tosca.nodes.Compute ]
+    metadata:
+     type: map
+     entry_schema:
+       type: string
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/groups/tosca_group_template.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/groups/tosca_group_template.yaml
new file mode 100644 (file)
index 0000000..0e94240
--- /dev/null
@@ -0,0 +1,54 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  Service template with topology_template, act as a nested system inside another system.
+
+imports:
+  - definitions.yaml
+
+topology_template:
+  description: Template of a database including its hosting stack.
+
+  inputs:
+    mq_server_ip:
+      type: string
+      description: IP address of the message queuing server to receive messages from.
+    receiver_port:
+      type: string
+      description: Port to be used for receiving messages.
+    my_cpus:
+      type: integer
+      description: Number of CPUs for the server.
+      constraints:
+        - valid_values: [ 1, 2, 4, 8 ]
+
+  node_templates:
+    websrv:
+      type: tosca.nodes.WebServer
+      capabilities:
+        data_endpoint:
+          properties:
+            port_name: { get_input: receiver_port }
+      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
+
+  groups:
+    webserver_group:
+      type: mycompany.mytypes.groups.placement
+      members: [ websrv, server ]
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/policies/custom_definitions.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/policies/custom_definitions.yaml
new file mode 100644 (file)
index 0000000..7f15ade
--- /dev/null
@@ -0,0 +1,10 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+policy_types:
+  mycompany.mytypes.myScalingPolicy:
+    derived_from: tosca.policies.Scaling
+    metadata:
+     type: map
+     entry_schema:
+       type: string
+
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
new file mode 100644 (file)
index 0000000..92bebe5
--- /dev/null
@@ -0,0 +1,85 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  Template for deploying servers based on policies.
+
+imports:
+  - custom_definitions.yaml
+
+topology_template:
+  node_templates:
+    my_server_1:
+      type: tosca.nodes.Compute
+      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
+
+    my_server_2:
+      type: tosca.nodes.Compute
+      capabilities:
+        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
+
+  groups:
+    webserver_group:
+      members: [ my_server_1, my_server_2 ]
+      type: tosca.groups.Root
+      metadata: { user1: 1008, user2: 1002 }
+
+
+  policies:
+    - my_compute_placement_policy:
+        type: tosca.policies.Placement
+        description: Apply placement policy to servers
+        metadata: { user1: 1001, user2: 1002 }
+        targets: [ my_server_1, my_server_2 ]
+        triggers:
+           resize_compute:
+             description: trigger
+             event_type: tosca.events.resource.utilization
+             schedule:
+               start_time: "2015-05-07T07:00:00Z"
+               end_time: "2015-06-07T07:00:00Z"
+             target_filter:
+               node: master-container
+               requirement: host
+               capability: Container
+             condition:
+               constraint: utilization greater_than 50%
+               period: 60
+               evaluations: 1
+               method: average
+             action:
+               resize: # Operation name
+                inputs:
+                 strategy: LEAST_USED
+                 implementation: Senlin.webhook()
+    - my_groups_placement:
+        type: mycompany.mytypes.myScalingPolicy
+        targets: [ webserver_group ]
+        description: my company scaling policy
+        metadata:
+          user1: 1001
+          user2: 1003
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_attributes_inheritance.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_attributes_inheritance.yaml
new file mode 100644 (file)
index 0000000..0649c11
--- /dev/null
@@ -0,0 +1,28 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile to test the attribute inheritance
+
+imports:
+  - custom_types/compute_with_prop.yaml
+
+topology_template:
+
+  node_templates:
+
+    server:
+      type: tosca.nodes.ComputeWithProp
+      properties:
+         test: yes
+      capabilities:
+        host:
+         properties:
+           num_cpus: 1
+           mem_size: 1 GB
+        os:
+          properties:
+            type: linux
+
+  outputs:
+    server_ip:
+     value: { get_attribute: [ server, public_address ] }
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_available_rel_tpls.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_available_rel_tpls.yaml
new file mode 100644 (file)
index 0000000..e8d9045
--- /dev/null
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA test for bug 1527214
+
+topology_template:
+
+  node_templates:
+
+    test_db:
+      type: tosca.nodes.Database
+      requirements:
+        - host:
+            node: mysql
+
+    mysql:
+      type: tosca.nodes.DBMS
+      requirements:
+        - host:
+            node: db_server
+
+    db_server:
+      type: tosca.nodes.Compute
+
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_caps_def.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_caps_def.yaml
new file mode 100644 (file)
index 0000000..0b0984a
--- /dev/null
@@ -0,0 +1,13 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: TOSCA simple profile to test a custom defined capability
+
+imports:
+  - custom_types/custom_caps_def.yaml
+
+topology_template:
+
+  node_templates:
+
+    server:
+      type: tosca.nodes.SomeNode
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_relationships.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_custom_relationships.yaml
new file mode 100644 (file)
index 0000000..9c8171d
--- /dev/null
@@ -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
@@ -16,7 +16,7 @@ topology_template:
       type: tosca.nodes.SoftwareComponent.Rsyslog.TestRsyslogType
 
     rsyslog:
-      type: tosca.nodes.SoftwareComponent.Rsyslog
+      type: Test2ndRsyslogType
 
     logstash:
       type: tosca.nodes.SoftwareComponent.Logstash
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_node_filter.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_node_filter.yaml
new file mode 100644 (file)
index 0000000..3dd8e26
--- /dev/null
@@ -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/test_repositories_definition.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_repositories_definition.yaml
new file mode 100644 (file)
index 0000000..2145d8f
--- /dev/null
@@ -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/
+    namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0a
+    namespace_prefix: oasis_tosca
+
+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/test_tosca_custom_rel_with_script.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_custom_rel_with_script.yaml
new file mode 100644 (file)
index 0000000..18a94a3
--- /dev/null
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Test template of a custom relationship with a configure script
+
+topology_template:
+
+  node_templates:
+    apache:
+      type: tosca.nodes.WebServer
+      requirements:
+        - host:
+            node: web_server
+            relationship: my_custom_rel
+
+    web_server:
+      type: tosca.nodes.Compute
+
+  relationship_templates:
+    my_custom_rel:
+      type: HostedOn
+      interfaces:
+        Configure:
+          pre_configure_source: scripts/wp_db_configure.sh
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error1.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error1.yaml
new file mode 100644 (file)
index 0000000..d35c022
--- /dev/null
@@ -0,0 +1,2 @@
+description: >
+  TOSCA simple profile missing version section.
\ No newline at end of file
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error2.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/test_tosca_top_level_error2.yaml
new file mode 100644 (file)
index 0000000..b3e80f9
--- /dev/null
@@ -0,0 +1,11 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+  TOSCA simple profile with invalid top-level key: 'node_template'.
+
+topology_template:
+
+  node_template:
+    server:
+      type: tosca.nodes.Compute
+
@@ -21,8 +21,11 @@ topology_template:
     trans1:
       type: example.TransactionSubsystem
       properties:
-        # to be updated when substitution_mapping is implemented
+        # TODO to be updated when substitution_mapping is implemented
         # mq_server_ip: { get_attribute: [ mq, server_ip ] }
+        # for now, we will use the loopback address to avoid errors as
+        # this property is required in the schema
+        mq_server_ip: 127.0.0.1
         receiver_port: 8080
       # capabilities:
         # message_receiver:
@@ -33,8 +36,11 @@ topology_template:
     trans2:
       type: example.TransactionSubsystem
       properties:
-        # to be updated when substitution_mapping is implemented
+        # TODO to be updated when substitution_mapping is implemented
         # mq_server_ip: { get_attribute: [ mq, server_ip ] }
+        # for now, we will use the loopback address to avoid errors as
+        # this property is required in the schema
+        mq_server_ip: 127.0.0.1
         receiver_port: 8080
       # capabilities:
         # message_receiver:
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_imports_validation.yaml
new file mode 100644 (file)
index 0000000..9c3fef4
--- /dev/null
@@ -0,0 +1,39 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Template to test invalid imports.
+
+imports:
+  - custom_types/imported_sample.yaml
+
+topology_template:
+ node_templates:
+    logstash:
+      type: tosca.nodes.SoftwareComponent.Logstash
+      requirements:
+        - search_endpoint:
+            capability: search_endpoint
+            relationship:
+              type: tosca.relationships.ConnectsTo
+              interfaces:
+                Configure:
+                  pre_configure_source:
+                    implementation: logstash/configure_elasticsearch.py
+                    inputs:
+                      elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] }
+      interfaces:
+        Standard:
+          create: logstash/create.sh
+          start: logstash/start.sh
+ policies:
+    - my_compute_placement_policy:
+        type: tosca.policies.Placement
+        description: Apply placement policy to servers
+        metadata: { user1: 1001, user2: 1002 }
+        targets: [ my_server_1, my_server_2 ]
+    - my_groups_placement:
+        type: mycompany.mytypes.myScalingPolicy
+        targets: [ webserver_group ]
+        description: my company scaling policy
+        metadata:
+          user1: 1001
+          user2: 1003
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_load_balancer.yaml b/tosca2heat/tosca-parser/toscaparser/tests/data/tosca_load_balancer.yaml
new file mode 100644 (file)
index 0000000..2fcdb48
--- /dev/null
@@ -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/
+
@@ -355,3 +355,19 @@ class ConstraintTest(TestCase):
                                   constraint.validate, 'abc')
         self.assertEqual(_('The value "abc" of property "prop" does not '
                            'match pattern "[0-9]*".'), str(error))
+
+    def test_min_length_with_map(self):
+        schema = {'min_length': 1}
+        constraint = Constraint('prop', Schema.MAP, schema)
+        try:
+            constraint.validate({"k": "v"})
+        except Exception as ex:
+            self.fail(ex)
+
+    def test_max_length_with_map(self):
+        schema = {'max_length': 1}
+        constraint = Constraint('prop', Schema.MAP, schema)
+        try:
+            constraint.validate({"k": "v"})
+        except Exception as ex:
+            self.fail(ex)
diff --git a/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py b/tosca2heat/tosca-parser/toscaparser/tests/test_custom_relationships.py
new file mode 100644 (file)
index 0000000..71de0c2
--- /dev/null
@@ -0,0 +1,35 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import os
+
+from toscaparser.tests.base import TestCase
+from toscaparser.tosca_template import ToscaTemplate
+
+
+class CustomRelationshipTypesTest(TestCase):
+
+    '''TOSCA template.'''
+    tosca_tpl = os.path.join(
+        os.path.dirname(os.path.abspath(__file__)),
+        "data/test_custom_relationships.yaml")
+    tosca = ToscaTemplate(tosca_tpl)
+
+    def test_version(self):
+        self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0")
+
+    def test_custom_types(self):
+        expected_custom_types = ['tosca.capabilities.HA',
+                                 'tosca.nodes.HACompute',
+                                 'tosca.relationships.HA']
+        self.assertItemsEqual(self.tosca.topology_template.custom_defs.keys(),
+                              expected_custom_types)
@@ -42,10 +42,12 @@ class DataTypeTest(TestCase):
       properties:
         addresses:
           type: map
+          required: false
           entry_schema:
             type: string
         contacts:
           type: list
+          required: false
           entry_schema:
             type: tosca.my.datatypes.ContactInfo
 
@@ -61,6 +63,19 @@ class DataTypeTest(TestCase):
           type: string
         contact_phone:
           type: string
+
+    tosca.my.datatypes.TestLab:
+      properties:
+        temperature:
+          type: range
+          required: false
+          constraints:
+            - in_range: [-256, UNBOUNDED]
+        humidity:
+          type: range
+          required: false
+          constraints:
+            - in_range: [-256, INFINITY]
     '''
     custom_type_def = yamlparser.simple_parse(custom_type_schema)
 
@@ -69,6 +84,15 @@ class DataTypeTest(TestCase):
         value = yamlparser.simple_parse(value_snippet)
         self.assertEqual(value, {})
 
+    # TODO(Matt) - opened as bug 1555300
+    # Need a test for PortSpec normative data type
+    # that tests the spec. requirement: "A valid PortSpec
+    # must have at least one of the following properties:
+    # target, target_range, source or source_range."
+    # TODO(Matt) - opened as bug 1555310
+    # test PortSpec value for source and target
+    # against the source_range and target_range
+    # when specified.
     def test_built_in_datatype(self):
         value_snippet = '''
         private_network:
@@ -274,7 +298,7 @@ class DataTypeTest(TestCase):
         error = self.assertRaises(ValueError, data.validate)
         self.assertEqual(_('"1" is not a string.'), error.__str__())
 
-    # contact_pone is an invalid field name in nested datatype
+    # 'contact_pone' is an invalid attribute name in nested datatype below
     def test_validation_in_nested_datatype(self):
         value_snippet = '''
         name: Mike
@@ -325,3 +349,60 @@ class DataTypeTest(TestCase):
         self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
         exception.ExceptionCollector.assertExceptionMessage(
             ValueError, _('"123456789" is not a string.'))
+
+    def test_valid_range_type(self):
+        value_snippet = '''
+        user_port:
+          protocol: tcp
+          target_range:  [20000, 60000]
+          source_range:  [1000, 3000]
+        '''
+        value = yamlparser.simple_parse(value_snippet)
+        data = DataEntity('PortSpec', value.get('user_port'))
+        self.assertIsNotNone(data.validate())
+
+    def test_invalid_range_datatype(self):
+        value_snippet = '''
+        user_port:
+          protocol: tcp
+          target_range: [20000]
+        '''
+        value = yamlparser.simple_parse(value_snippet)
+        data = DataEntity('PortSpec', value.get('user_port'))
+        err = self.assertRaises(ValueError, data.validate)
+        self.assertEqual(_('"[20000]" is not a valid range.'
+                           ),
+                         err.__str__())
+
+        value_snippet = '''
+        user_port:
+          protocol: tcp
+          target_range: [20000, 3000]
+        '''
+        value = yamlparser.simple_parse(value_snippet)
+        data = DataEntity('PortSpec', value.get('user_port'))
+        err = self.assertRaises(ValueError, data.validate)
+        self.assertEqual(_('"[20000, 3000]" is not a valid range.'
+                           ),
+                         err.__str__())
+
+        value_snippet = '''
+        humidity: [-100, 100]
+        '''
+        value = yamlparser.simple_parse(value_snippet)
+        data = DataEntity('tosca.my.datatypes.TestLab',
+                          value, DataTypeTest.custom_type_def)
+        err = self.assertRaises(exception.InvalidSchemaError,
+                                lambda: data.validate())
+        self.assertEqual(_('The property "in_range" expects comparable values.'
+                           ),
+                         err.__str__())
+
+    def test_range_unbounded(self):
+        value_snippet = '''
+        temperature: [-100, 999999]
+        '''
+        value = yamlparser.simple_parse(value_snippet)
+        data = DataEntity('tosca.my.datatypes.TestLab', value,
+                          DataTypeTest.custom_type_def)
+        self.assertIsNotNone(data.validate())
@@ -27,9 +27,11 @@ class IntrinsicFunctionsTest(TestCase):
     params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user'}
     tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
 
-    def _get_node(self, node_name):
+    def _get_node(self, node_name, tosca=None):
+        if tosca is None:
+            tosca = self.tosca
         return [
-            node for node in self.tosca.nodetemplates
+            node for node in tosca.nodetemplates
             if node.name == node_name][0]
 
     def _get_operation(self, interfaces, operation):
@@ -116,6 +118,65 @@ class IntrinsicFunctionsTest(TestCase):
                                                 'root_password')
         self.assertIsNone(dbms_root_password.result())
 
+    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))
+        operation = self._get_operation(mysql_database.interfaces, 'configure')
+        db_port = operation.inputs['db_port']
+        self.assertTrue(isinstance(db_port, functions.GetProperty))
+        result = db_port.result()
+        self.assertEqual(3306, result)
+        test = operation.inputs['test']
+        self.assertTrue(isinstance(test, functions.GetProperty))
+        result = test.result()
+        self.assertEqual(1, result)
+
+    def test_get_property_with_nested_params(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/functions/tosca_nested_property_names_indexes.yaml")
+        webserver = self._get_node('wordpress', ToscaTemplate(tosca_tpl))
+        operation = self._get_operation(webserver.interfaces, 'configure')
+        wp_endpoint_prot = operation.inputs['wp_endpoint_protocol']
+        self.assertTrue(isinstance(wp_endpoint_prot, functions.GetProperty))
+        self.assertEqual('tcp', wp_endpoint_prot.result())
+        wp_list_prop = operation.inputs['wp_list_prop']
+        self.assertTrue(isinstance(wp_list_prop, functions.GetProperty))
+        self.assertEqual(3, wp_list_prop.result())
+
+    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))
+        operation = self._get_operation(some_node.interfaces, 'configure')
+        some_input = operation.inputs['some_input']
+        self.assertTrue(isinstance(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)
+
+        for node in tosca.nodetemplates:
+            for relationship, trgt in node.relationships.items():
+                rel_template = trgt.get_relationship_template()[0]
+                break
+
+        operation = self._get_operation(rel_template.interfaces,
+                                        'pre_configure_source')
+        target_test = operation.inputs['target_test']
+        self.assertTrue(isinstance(target_test, functions.GetProperty))
+        self.assertEqual(1, target_test.result())
+        source_port = operation.inputs['source_port']
+        self.assertTrue(isinstance(source_port, functions.GetProperty))
+        self.assertEqual(3306, source_port.result())
+
 
 class GetAttributeTest(TestCase):
 
@@ -125,6 +186,11 @@ class GetAttributeTest(TestCase):
             'data',
             filename))
 
+    def _get_operation(self, interfaces, operation):
+        return [
+            interface for interface in interfaces
+            if interface.name == operation][0]
+
     def test_get_attribute_in_outputs(self):
         tpl = self._load_template('tosca_single_instance_wordpress.yaml')
         website_url_output = [
@@ -147,7 +213,7 @@ class GetAttributeTest(TestCase):
         self.assertIn(expected_msg, six.text_type(err))
         err = self.assertRaises(ValueError,
                                 functions.get_function, None, None,
-                                {'get_attribute': ['x', 'y', 'z']})
+                                {'get_attribute': ['x', 'y', 'z', 'k']})
         self.assertIn(expected_msg, six.text_type(err))
 
     def test_get_attribute_unknown_node_template_name(self):
@@ -202,3 +268,57 @@ class GetAttributeTest(TestCase):
             ValueError,
             _('"get_attribute: [ HOST, ... ]" is not allowed in "outputs" '
               'section of the TOSCA template.'))
+
+    def test_get_attribute_with_index(self):
+        self._load_template(
+            'functions/test_get_attribute_with_index.yaml')
+
+    def test_get_attribute_with_index_error(self):
+        self.assertRaises(
+            exception.ValidationError, self._load_template,
+            'functions/test_get_attribute_with_index_error.yaml')
+        exception.ExceptionCollector.assertExceptionMessage(
+            ValueError,
+            _('Illegal arguments for function "get_attribute". '
+              'Expected arguments: "node-template-name", "attribute-name"'))
+
+    def test_get_attribute_source_target_keywords(self):
+        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)
+
+        for node in tosca.nodetemplates:
+            for relationship, trgt in node.relationships.items():
+                rel_template = trgt.get_relationship_template()[0]
+                break
+
+        operation = self._get_operation(rel_template.interfaces,
+                                        'pre_configure_source')
+        target_test = operation.inputs['target_test']
+        self.assertTrue(isinstance(target_test, functions.GetAttribute))
+        source_port = operation.inputs['source_port']
+        self.assertTrue(isinstance(source_port, functions.GetAttribute))
+
+
+class ConcatTest(TestCase):
+
+    def _load_template(self, filename):
+        return ToscaTemplate(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            filename))
+
+    def test_validate_concat(self):
+        tosca = self._load_template("data/functions/test_concat.yaml")
+        server_url_output = [
+            output for output in tosca.outputs if output.name == 'url'][0]
+        func = functions.get_function(self, tosca.outputs,
+                                      server_url_output.value)
+        self.assertIsInstance(func, functions.Concat)
+
+        self.assertRaises(exception.ValidationError, self._load_template,
+                          'data/functions/test_concat_invalid.yaml')
+        exception.ExceptionCollector.assertExceptionMessage(
+            ValueError,
+            _('Invalid arguments for function "concat". Expected at least '
+              'one arguments.'))
@@ -108,8 +108,8 @@ class CSARPrereqTest(TestCase):
                             "data/CSAR/csar_wordpress_invalid_import_path.zip")
         csar = CSAR(path)
         error = self.assertRaises(ImportError, csar.validate)
-        self.assertEqual(_('Import "Definitions/wordpress.yaml" is not '
-                           'valid.'), str(error))
+        self.assertEqual(_('Import "Invalid_import_path/wordpress.yaml" is'
+                           ' not valid.'), str(error))
         self.assertTrue(csar.temp_dir is None or
                         not os.path.exists(csar.temp_dir))
 
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from testtools import matchers
+
 from toscaparser.common import exception
 from toscaparser.elements.property_definition import PropertyDef
+from toscaparser.nodetemplate import NodeTemplate
 from toscaparser.properties import Property
 from toscaparser.tests.base import TestCase
 from toscaparser.utils.gettextutils import _
@@ -179,10 +182,12 @@ class PropertyTest(TestCase):
     def test_timestamp_invalid(self):
         test_property_schema = {'type': 'timestamp'}
         # invalid timestamp - day out of range
-        propertyInstance = Property('test_property', '2015-04-115T02:59:43.1Z',
+        value = '2015-04-115T02:59:43.1Z'
+        propertyInstance = Property('test_property', value,
                                     test_property_schema)
         error = self.assertRaises(ValueError, propertyInstance.validate)
-        self.assertEqual(_('day is out of range for month'), str(error))
+        expected_message = (_('"%s" is not a valid timestamp.') % value)
+        self.assertThat(str(error), matchers.StartsWith(expected_message))
 
     def test_required(self):
         test_property_schema = {'type': 'string'}
@@ -191,7 +196,6 @@ class PropertyTest(TestCase):
         self.assertEqual(True, propertyInstance.required)
 
     def test_proprety_inheritance(self):
-        from toscaparser.nodetemplate import NodeTemplate
 
         tosca_custom_def = '''
           tosca.nodes.SoftwareComponent.MySoftware:
@@ -214,11 +218,7 @@ class PropertyTest(TestCase):
         expected_properties = ['component_version',
                                'install_path']
 
-        nodetemplates = yamlparser.\
-            simple_parse(tosca_node_template)['node_templates']
-        custom_def = yamlparser.simple_parse(tosca_custom_def)
-        name = list(nodetemplates.keys())[0]
-        tpl = NodeTemplate(name, nodetemplates, custom_def)
+        tpl = self._get_nodetemplate(tosca_node_template, tosca_custom_def)
         self.assertIsNone(tpl.validate())
         self.assertEqual(expected_properties,
                          sorted(tpl.get_properties().keys()))
@@ -234,3 +234,135 @@ class PropertyTest(TestCase):
                                   'prop', None, schema['properties']['prop'])
         self.assertEqual(_('Schema definition of "prop" must have a "type" '
                            'attribute.'), str(error))
+
+    def test_invalid_required_value(self):
+        tpl_snippet = '''
+         properties:
+           prop:
+             type: tosca.mytesttype.Test
+             required: dunno
+        '''
+        schema = yamlparser.simple_parse(tpl_snippet)
+        error = self.assertRaises(exception.InvalidSchemaError, PropertyDef,
+                                  'prop', None, schema['properties']['prop'])
+
+        valid_values = ', '.join(PropertyDef.VALID_REQUIRED_VALUES)
+        expected_message = (_('Schema definition of "prop" has "required" '
+                              'attribute with invalid value "dunno". The '
+                              'value must be one of "%s".') % valid_values)
+        self.assertEqual(expected_message, str(error))
+
+    def test_invalid_property_status(self):
+        tpl_snippet = '''
+         properties:
+           prop:
+             type: string
+             status: unknown
+        '''
+        schema = yamlparser.simple_parse(tpl_snippet)
+        error = self.assertRaises(exception.InvalidSchemaError, PropertyDef,
+                                  'prop', None, schema['properties']['prop'])
+
+        valid_values = ', '.join(PropertyDef.VALID_STATUS_VALUES)
+        expected_message = (_('Schema definition of "prop" has "status" '
+                              'attribute with invalid value "unknown". The '
+                              'value must be one of "%s".') % valid_values)
+        self.assertEqual(expected_message, str(error))
+
+    def test_capability_proprety_inheritance(self):
+        tosca_custom_def_example1 = '''
+          tosca.capabilities.ScalableNew:
+            derived_from: tosca.capabilities.Scalable
+            properties:
+              max_instances:
+                type: integer
+                default: 0
+                required: no
+
+          tosca.nodes.ComputeNew:
+            derived_from: tosca.nodes.Compute
+            capabilities:
+              scalable:
+                type: tosca.capabilities.ScalableNew
+        '''
+
+        tosca_node_template_example1 = '''
+          node_templates:
+            compute_instance:
+              type: tosca.nodes.ComputeNew
+              capabilities:
+                scalable:
+                  properties:
+                    min_instances: 1
+        '''
+
+        tosca_custom_def_example2 = '''
+          tosca.nodes.ComputeNew:
+            derived_from: tosca.nodes.Compute
+            capabilities:
+              new_cap:
+                type: tosca.capabilities.Scalable
+        '''
+
+        tosca_node_template_example2 = '''
+          node_templates:
+            db_server:
+                type: tosca.nodes.ComputeNew
+                capabilities:
+                  host:
+                   properties:
+                     num_cpus: 1
+        '''
+
+        tpl1 = self._get_nodetemplate(tosca_node_template_example1,
+                                      tosca_custom_def_example1)
+        self.assertIsNone(tpl1.validate())
+
+        tpl2 = self._get_nodetemplate(tosca_node_template_example2,
+                                      tosca_custom_def_example2)
+        self.assertIsNone(tpl2.validate())
+
+    def _get_nodetemplate(self, tpl_snippet,
+                          custom_def_snippet=None):
+        nodetemplates = yamlparser.\
+            simple_parse(tpl_snippet)['node_templates']
+        custom_def = []
+        if custom_def_snippet:
+            custom_def = yamlparser.simple_parse(custom_def_snippet)
+        name = list(nodetemplates.keys())[0]
+        tpl = NodeTemplate(name, nodetemplates, custom_def)
+        return tpl
+
+    def test_explicit_relationship_proprety(self):
+
+        tosca_node_template = '''
+          node_templates:
+
+            client_node:
+              type: tosca.nodes.Compute
+              requirements:
+                - local_storage:
+                    node: my_storage
+                    relationship:
+                      type: AttachesTo
+                      properties:
+                        location: /mnt/disk
+
+            my_storage:
+              type: tosca.nodes.BlockStorage
+              properties:
+                size: 1 GB
+        '''
+
+        expected_properties = ['location']
+
+        nodetemplates = yamlparser.\
+            simple_parse(tosca_node_template)['node_templates']
+        tpl = NodeTemplate('client_node', nodetemplates, [])
+
+        self.assertIsNone(tpl.validate())
+        rel_tpls = []
+        for relationship, trgt in tpl.relationships.items():
+            rel_tpls.extend(trgt.get_relationship_template())
+        self.assertEqual(expected_properties,
+                         sorted(rel_tpls[0].get_properties().keys()))
@@ -288,17 +288,17 @@ class ScalarUnitNegativeTest(TestCase):
       derived_from: tosca.nodes.Root
       properties:
         cpu_frequency:
-          required: no
+          required: false
           type: scalar-unit.frequency
           constraints:
             - greater_or_equal: 0.1 GHz
         disk_size:
-          required: no
+          required: false
           type: scalar-unit.size
           constraints:
             - greater_or_equal: 1 GB
         mem_size:
-          required: no
+          required: false
           type: scalar-unit.size
           constraints:
             - in_range: [1 MiB, 1 GiB]
@@ -76,7 +76,7 @@ class TopologyTemplateTest(TestCase):
         tpl_name = "app"
         expected_type = "example.SomeApp"
         expected_properties = ['admin_user', 'pool_size']
-        expected_capabilities = ['message_receiver']
+        expected_capabilities = ['feature', 'message_receiver']
         expected_requirements = [{'host': {'node': 'websrv'}}]
         expected_relationshp = ['tosca.relationships.HostedOn']
         expected_host = ['websrv']
@@ -145,8 +145,8 @@ class TopologyTemplateTest(TestCase):
     def test_groups(self):
         group = self.topo.groups[0]
         self.assertEqual('webserver_group', group.name)
-        self.assertEqual(['websrv', 'server'], group.member_names)
-        for node in group.members:
+        self.assertEqual(['websrv', 'server'], group.members)
+        for node in group.get_member_nodes():
             if node.name == 'server':
                 '''Test property value'''
                 props = node.get_properties()
@@ -13,6 +13,7 @@
 from toscaparser.common import exception
 from toscaparser.elements.artifacttype import ArtifactTypeDef
 from toscaparser.elements.entity_type import EntityType
+from toscaparser.elements.grouptype import GroupType
 import toscaparser.elements.interfaces as ifaces
 from toscaparser.elements.nodetype import NodeType
 from toscaparser.elements.policytype import PolicyType
@@ -40,6 +41,7 @@ policy_placement_type = PolicyType('tosca.policies.Placement')
 policy_scaling_type = PolicyType('tosca.policies.Scaling')
 policy_update_type = PolicyType('tosca.policies.Update')
 policy_performance_type = PolicyType('tosca.policies.Performance')
+group_type = GroupType('tosca.groups.Root')
 
 
 class ToscaDefTest(TestCase):
@@ -56,40 +58,46 @@ class ToscaDefTest(TestCase):
         self.assertEqual(network_port_type.parent_type.type,
                          "tosca.nodes.Root")
 
+    def test_group(self):
+        self.assertEqual(group_type.type, "tosca.groups.Root")
+        self.assertIn(ifaces.LIFECYCLE_SHORTNAME, group_type.interfaces)
+
     def test_capabilities(self):
+        # Assure the normative Compute node type
+        # has all the required Capability types
+        # regardless of symbloc name
+        # TODO(Matt) - since Compute IS a normative node type
+        # we SHOULD test symbolic capability names as well
         self.assertEqual(
-            sorted(['tosca.capabilities.Container',
-                    'tosca.capabilities.OperatingSystem',
-                    'tosca.capabilities.network.Bindable',
-                    'tosca.capabilities.Scalable']),
+            ['tosca.capabilities.Container',
+             'tosca.capabilities.Node',
+             'tosca.capabilities.OperatingSystem',
+             'tosca.capabilities.Scalable',
+             'tosca.capabilities.network.Bindable'],
             sorted([c.type for c in compute_type.get_capabilities_objects()]))
+        # Assure the normative Network node type
+        # hsa all the required Capability types
+        # TODO(Matt) - since Network IS a normative node type
+        # we SHOULD test symbolic capability names as well
         self.assertEqual(
-            ['tosca.capabilities.network.Linkable'],
-            [c.type for c in network_type.get_capabilities_objects()])
-        endpoint_properties = ['initiator', 'network_name', 'port',
-                               'port_name', 'ports', 'protocol',
-                               'secure', 'url_path']
+            ['tosca.capabilities.Node',
+             'tosca.capabilities.network.Linkable'],
+            sorted([c.type for c in network_type.get_capabilities_objects()]))
+
+        # Assure the normative WebServer node type's
+        # Endpoint cap. has all required property names
+        # Note: we are testing them in alphabetic sort order
         endpoint_props_def_objects = \
             self._get_capability_properties_def_objects(
                 webserver_type.get_capabilities_objects(),
                 'tosca.capabilities.Endpoint')
+        # Assure WebServer's Endpoint capability's properties have their
+        # required keyname value set correctly
         self.assertEqual(
-            endpoint_properties,
-            sorted([p.name for p in endpoint_props_def_objects]))
-        for p in endpoint_props_def_objects:
-            if p.name in endpoint_properties:
-                self.assertFalse(p.required)
-        endpoint_props_def = self._get_capability_properties_def(
-            webserver_type.get_capabilities_objects(),
-            'tosca.capabilities.Endpoint')
-        self.assertEqual(
-            endpoint_properties,
-            sorted(endpoint_props_def.keys()))
-        endpoint_prop_def = self._get_capability_property_def(
-            webserver_type.get_capabilities_objects(),
-            'tosca.capabilities.Endpoint',
-            'initiator')
-        self.assertEqual(None, endpoint_prop_def)
+            [('initiator', False), ('network_name', False), ('port', False),
+             ('port_name', False), ('ports', False), ('protocol', True),
+             ('secure', False), ('url_path', False)],
+            sorted([(p.name, p.required) for p in endpoint_props_def_objects]))
 
         os_props = self._get_capability_properties_def_objects(
             compute_type.get_capabilities_objects(),
@@ -131,36 +139,35 @@ class ToscaDefTest(TestCase):
                 break
         return properties_def
 
-    def _get_capability_property_def(self, caps, type, property):
-        property_def = None
-        for cap in caps:
-            if cap.type == type:
-                property_def = cap.get_property_def_value(property)
-                break
-        return property_def
-
     def test_properties_def(self):
         self.assertEqual(
-            ['name', 'password', 'user'],
+            ['name', 'password', 'port', 'user'],
             sorted(database_type.get_properties_def().keys()))
 
     def test_attributes_def(self):
         self.assertEqual(
-            ['private_address', 'public_address'],
+            ['networks', 'ports', 'private_address', 'public_address',
+             'state', 'tosca_id', 'tosca_name'],
             sorted(compute_type.get_attributes_def().keys()))
 
     def test_requirements(self):
         self.assertEqual(
             [{'host': {'capability': 'tosca.capabilities.Container',
                        'node': 'tosca.nodes.Compute',
-                       'relationship': 'tosca.relationships.HostedOn'}}],
+                       'relationship': 'tosca.relationships.HostedOn'}},
+             {'dependency': {'capability': 'tosca.capabilities.Node',
+                             'node': 'tosca.nodes.Root',
+                             'occurrences': [0, 'UNBOUNDED'],
+                             'relationship': 'tosca.relationships.DependsOn'}}
+             ],
             [r for r in component_type.requirements])
 
     def test_relationship(self):
         self.assertEqual(
-            [('tosca.relationships.HostedOn', 'tosca.nodes.Compute')],
-            [(relation.type, node.type) for
-             relation, node in component_type.relationship.items()])
+            [('tosca.relationships.DependsOn', 'tosca.nodes.Root'),
+             ('tosca.relationships.HostedOn', 'tosca.nodes.Compute')],
+            sorted([(relation.type, node.type) for
+                   relation, node in component_type.relationship.items()]))
         self.assertIn(
             ('tosca.relationships.HostedOn', ['tosca.capabilities.Container']),
             [(relation.type, relation.valid_target_types) for
@@ -67,7 +67,7 @@ class ToscaTemplateTest(TestCase):
         tpl_name = "mysql_database"
         expected_type = "tosca.nodes.Database"
         expected_properties = ['name', 'password', 'user']
-        expected_capabilities = ['database_endpoint']
+        expected_capabilities = ['database_endpoint', 'feature']
         expected_requirements = [{'host': 'mysql_dbms'}]
         ''' TODO: needs enhancement in tosca_elk.yaml..
         expected_relationshp = ['tosca.relationships.HostedOn']
@@ -186,6 +186,7 @@ class ToscaTemplateTest(TestCase):
             compute_type = NodeType(tpl.type)
             self.assertEqual(
                 sorted(['tosca.capabilities.Container',
+                        'tosca.capabilities.Node',
                         'tosca.capabilities.OperatingSystem',
                         'tosca.capabilities.network.Bindable',
                         'tosca.capabilities.Scalable']),
@@ -219,6 +220,22 @@ class ToscaTemplateTest(TestCase):
                             self.assertEqual(artifact,
                                              interface.implementation)
 
+    def test_relationship(self):
+        template = ToscaTemplate(self.tosca_elk_tpl)
+        for node_tpl in template.nodetemplates:
+            if node_tpl.name == 'paypal_pizzastore':
+                expected_relationships = ['tosca.relationships.ConnectsTo',
+                                          'tosca.relationships.HostedOn']
+                expected_hosts = ['tosca.nodes.Database',
+                                  'tosca.nodes.WebServer']
+                self.assertEqual(len(node_tpl.relationships), 2)
+                self.assertEqual(
+                    expected_relationships,
+                    sorted([k.type for k in node_tpl.relationships.keys()]))
+                self.assertEqual(
+                    expected_hosts,
+                    sorted([v.type for v in node_tpl.relationships.values()]))
+
     def test_template_macro(self):
         template = ToscaTemplate(self.tosca_elk_tpl)
         for node_tpl in template.nodetemplates:
@@ -331,6 +348,11 @@ class ToscaTemplateTest(TestCase):
             NotImplementedError,
             lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
 
+    # Test the following:
+    # 1. Custom node type derived from 'WebApplication' named 'TestApp'
+    #    with a custom Capability Type 'TestCapability'
+    # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
+    #    that is not defined
     def test_custom_capability_type_definition(self):
         tpl_snippet = '''
         node_templates:
@@ -341,7 +363,7 @@ class ToscaTemplateTest(TestCase):
                 properties:
                   test: 1
         '''
-        # custom definition with capability type definition
+        # custom node type definition with custom capability type definition
         custom_def = '''
         tosca.nodes.WebApplication.TestApp:
           derived_from: tosca.nodes.WebApplication
@@ -353,9 +375,9 @@ class ToscaTemplateTest(TestCase):
           properties:
             test:
               type: integer
-              required: no
+              required: false
         '''
-        expected_capabilities = ['test_cap']
+        expected_capabilities = ['app_endpoint', 'feature', 'test_cap']
         nodetemplates = (toscaparser.utils.yamlparser.
                          simple_parse(tpl_snippet))['node_templates']
         custom_def = (toscaparser.utils.yamlparser.
@@ -366,7 +388,7 @@ class ToscaTemplateTest(TestCase):
             expected_capabilities,
             sorted(tpl.get_capabilities().keys()))
 
-        # custom definition without capability type definition
+        # custom definition without valid capability type definition
         custom_def = '''
         tosca.nodes.WebApplication.TestApp:
           derived_from: tosca.nodes.WebApplication
@@ -443,7 +465,9 @@ class ToscaTemplateTest(TestCase):
             "data/test_instance_nested_imports.yaml")
         tosca = ToscaTemplate(tosca_tpl)
         expected_custom_types = ['tosca.nodes.WebApplication.WordPress',
-                                 'tosca.nodes.SoftwareComponent.Rsyslog',
+                                 'test_namespace_prefix.Rsyslog',
+                                 'Test2ndRsyslogType',
+                                 'test_2nd_namespace_prefix.Rsyslog',
                                  'tosca.nodes.SoftwareComponent.Logstash',
                                  'tosca.nodes.SoftwareComponent.Rsyslog.'
                                  'TestRsyslogType']
@@ -465,8 +489,9 @@ class ToscaTemplateTest(TestCase):
             "data/test_multiple_validation_errors.yaml")
         self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl,
                           None)
-        err1_msg = _('The template version "tosca_simple_yaml_1" is invalid. '
-                     'Valid versions are "tosca_simple_yaml_1_0".')
+        valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS)
+        err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. '
+                      'Valid versions are "%s".') % valid_versions)
         exception.ExceptionCollector.assertExceptionMessage(
             exception.InvalidTemplateVersion, err1_msg)
 
@@ -542,3 +567,166 @@ class ToscaTemplateTest(TestCase):
             "data/CSAR/csar_elk.csar")
         tosca = ToscaTemplate(tosca_tpl)
         self.assertTrue(tosca.topology_template.custom_defs)
+
+    def test_available_rel_tpls(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_available_rel_tpls.yaml")
+        tosca = ToscaTemplate(tosca_tpl)
+        for node in tosca.nodetemplates:
+            for relationship, target in node.relationships.items():
+                try:
+                    target.relationships
+                except TypeError as error:
+                    self.fail(error)
+
+    def test_no_input(self):
+        self.assertRaises(exception.ValidationError, ToscaTemplate, None,
+                          None, False, None)
+        err_msg = (('No path or yaml_dict_tpl was provided. '
+                    'There is nothing to parse.'))
+        exception.ExceptionCollector.assertExceptionMessage(ValueError,
+                                                            err_msg)
+
+    def test_path_and_yaml_dict_tpl_input(self):
+        test_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_helloworld.yaml")
+
+        yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
+
+        tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
+
+        self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
+
+    def test_yaml_dict_tpl_input(self):
+        test_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_helloworld.yaml")
+
+        yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
+
+        tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
+
+        self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
+
+    def test_yaml_dict_tpl_with_params_and_url_import(self):
+        test_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_single_instance_wordpress_with_url_import.yaml")
+
+        yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
+
+        params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+                  'db_root_pwd': 'mypasswd'}
+
+        tosca = ToscaTemplate(parsed_params=params,
+                              yaml_dict_tpl=yaml_dict_tpl)
+
+        self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
+
+    def test_yaml_dict_tpl_with_rel_import(self):
+        test_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_single_instance_wordpress.yaml")
+
+        yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
+
+        self.assertRaises(exception.ValidationError, ToscaTemplate, None,
+                          None, 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,
+                                                            err_msg)
+
+    def test_yaml_dict_tpl_with_fullpath_import(self):
+        test_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_single_instance_wordpress.yaml")
+
+        yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
+
+        yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname(
+            os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")]
+
+        params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
+                  'db_root_pwd': 'mypasswd'}
+
+        tosca = ToscaTemplate(parsed_params=params,
+                              yaml_dict_tpl=yaml_dict_tpl)
+
+        self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
+
+    def test_policies_for_node_templates(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/policies/tosca_policy_template.yaml")
+        tosca = ToscaTemplate(tosca_tpl)
+
+        for policy in tosca.topology_template.policies:
+            if policy.name == 'my_compute_placement_policy':
+                self.assertEqual('tosca.policies.Placement', policy.type)
+                self.assertEqual(['my_server_1', 'my_server_2'],
+                                 policy.targets)
+                self.assertEqual('node_templates', policy.get_targets_type())
+                for node in policy.targets_list:
+                    if node.name == 'my_server_1':
+                        '''Test property value'''
+                        props = node.get_properties()
+                        if props and 'mem_size' in props.keys():
+                            self.assertEqual(props['mem_size'].value,
+                                             '4096 MB')
+
+    def test_policies_for_groups(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/policies/tosca_policy_template.yaml")
+        tosca = ToscaTemplate(tosca_tpl)
+
+        for policy in tosca.topology_template.policies:
+            if policy.name == 'my_groups_placement':
+                self.assertEqual('mycompany.mytypes.myScalingPolicy',
+                                 policy.type)
+                self.assertEqual(['webserver_group'], policy.targets)
+                self.assertEqual('groups', policy.get_targets_type())
+                group = policy.get_targets_list()[0]
+                for node in group.get_member_nodes():
+                    if node.name == 'my_server_2':
+                        '''Test property value'''
+                        props = node.get_properties()
+                        if props and 'mem_size' in props.keys():
+                            self.assertEqual(props['mem_size'].value,
+                                             '4096 MB')
+
+    def test_node_filter(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_node_filter.yaml")
+        ToscaTemplate(tosca_tpl)
+
+    def test_attributes_inheritance(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_attributes_inheritance.yaml")
+        ToscaTemplate(tosca_tpl)
+
+    def test_repositories_definition(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_repositories_definition.yaml")
+        ToscaTemplate(tosca_tpl)
+
+    def test_custom_caps_def(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_custom_caps_def.yaml")
+        ToscaTemplate(tosca_tpl)
+
+    def test_custom_rel_with_script(self):
+        tosca_tpl = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/test_tosca_custom_rel_with_script.yaml")
+        tosca = ToscaTemplate(tosca_tpl)
+        rel = tosca.relationship_templates[0]
+        self.assertEqual(len(rel.interfaces), 1)
+        self.assertEqual(rel.interfaces[0].type, "Configure")
@@ -18,9 +18,12 @@ from toscaparser.imports import ImportsLoader
 from toscaparser.nodetemplate import NodeTemplate
 from toscaparser.parameters import Input
 from toscaparser.parameters import Output
+from toscaparser.policy import Policy
 from toscaparser.relationship_template import RelationshipTemplate
 from toscaparser.tests.base import TestCase
+from toscaparser.topology_template import TopologyTemplate
 from toscaparser.tosca_template import ToscaTemplate
+from toscaparser.triggers import Triggers
 from toscaparser.utils.gettextutils import _
 
 import toscaparser.utils.yamlparser
@@ -53,6 +56,48 @@ class ToscaTemplateValidationTest(TestCase):
             _('Template contains unknown field "node_template". Refer to the '
               'definition to verify valid values.'))
 
+    def test_template_with_imports_validation(self):
+        tpl_path = os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "data/tosca_imports_validation.yaml")
+        self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path)
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Template custom_types/imported_sample.yaml contains unknown '
+              'field "descriptions". Refer to the definition'
+              ' to verify valid values.'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Template custom_types/imported_sample.yaml contains unknown '
+              'field "node_typess". Refer to the definition to '
+              'verify valid values.'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Template custom_types/imported_sample.yaml contains unknown '
+              'field "tosca1_definitions_version". Refer to the definition'
+              ' to verify valid values.'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.InvalidTemplateVersion,
+            _('The template version "tosca_simple_yaml_1_10 in '
+              'custom_types/imported_sample.yaml" is invalid. '
+              'Valid versions are "tosca_simple_yaml_1_0, '
+              'tosca_simple_profile_for_nfv_1_0_0".'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Template custom_types/imported_sample.yaml contains unknown '
+              'field "policy_types1". Refer to the definition to '
+              'verify valid values.'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Nodetype"tosca.nodes.SoftwareComponent.Logstash" contains '
+              'unknown field "capabilities1". Refer to the definition '
+              'to verify valid values.'))
+        exception.ExceptionCollector.assertExceptionMessage(
+            exception.UnknownFieldError,
+            _('Policy "mycompany.mytypes.myScalingPolicy" contains unknown '
+              'field "derived1_from". Refer to the definition to '
+              'verify valid values.'))
+
     def test_inputs(self):
         tpl_snippet = '''
         inputs:
@@ -123,17 +168,29 @@ tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
         imports:
           - some_definitions: custom_types/paypalpizzastore_nodejs_app.yaml
           - more_definitions:
-              file: toscaparser/tests/data/custom_types/wordpress.yaml
-              repository: tosca-parser/master
-              namespace_uri: https://raw.githubusercontent.com/openstack
+              file: 'https://raw.githubusercontent.com/openstack/tosca-parser\
+/master/toscaparser/tests/data/custom_types/wordpress.yaml'
               namespace_prefix: single_instance_wordpress
         '''
         path = 'toscaparser/tests/data/tosca_elk.yaml'
         custom_defs = self._imports_content_test(tpl_snippet,
                                                  path,
                                                  "node_types")
-        self.assertTrue(custom_defs.get("tosca.nodes."
-                                        "WebApplication.WordPress"))
+        self.assertTrue(custom_defs.get("single_instance_wordpress.tosca."
+                                        "nodes.WebApplication.WordPress"))
+
+    def test_imports_wth_namespace_prefix(self):
+        tpl_snippet = '''
+        imports:
+          - more_definitions:
+              file: custom_types/nested_rsyslog.yaml
+              namespace_prefix: testprefix
+        '''
+        path = 'toscaparser/tests/data/tosca_elk.yaml'
+        custom_defs = self._imports_content_test(tpl_snippet,
+                                                 path,
+                                                 "node_types")
+        self.assertTrue(custom_defs.get("testprefix.Rsyslog"))
 
     def test_imports_with_no_main_template(self):
         tpl_snippet = '''
@@ -187,7 +244,6 @@ tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
           - more_definitions:
               file: https://raw.githubusercontent.com/openstack/\
 tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml
-              namespace_prefix: mycompany
         '''
         path = 'https://raw.githubusercontent.com/openstack/\
 tosca-parser/master/toscaparser/tests/data/\
@@ -202,33 +258,31 @@ tosca_single_instance_wordpress_with_url_import.yaml'
         tpl_snippet = '''
         imports:
           - more_definitions:
-              file: heat-translator/master/translator/tests/data/\
-custom_types/wordpress.yaml
-              namespace_uri: https://raw.githubusercontent.com/openstack/
-              namespace_prefix: mycompany
+             file: https://raw.githubusercontent.com/openstack/\
+heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
+             namespace_prefix: mycompany
+             namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
         '''
         path = 'toscaparser/tests/data/tosca_elk.yaml'
         custom_defs = self._imports_content_test(tpl_snippet,
                                                  path,
                                                  "node_types")
-        self.assertTrue(custom_defs.get("tosca.nodes."
+        self.assertTrue(custom_defs.get("mycompany.tosca.nodes."
                                         "WebApplication.WordPress"))
 
-    def test_import_error_namespace_uri(self):
+    def test_import_error_file_uri(self):
         tpl_snippet = '''
         imports:
           - more_definitions:
-              file: toscaparser/tests/data/tosca_elk.yaml
-              namespace_uri: mycompany.com/ns/tosca/2.0
-              namespace_prefix: mycompany
+             file: mycompany.com/ns/tosca/2.0/toscaparser/tests/data\
+/tosca_elk.yaml
+             namespace_prefix: mycompany
+             namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0
         '''
-        errormsg = _('namespace_uri "mycompany.com/ns/tosca/2.0" is not '
-                     'valid in import definition "more_definitions".')
         path = 'toscaparser/tests/data/tosca_elk.yaml'
-        err = self.assertRaises(ImportError,
-                                self._imports_content_test,
-                                tpl_snippet, path, None)
-        self.assertEqual(errormsg, err.__str__())
+        self.assertRaises(ImportError,
+                          self._imports_content_test,
+                          tpl_snippet, path, None)
 
     def test_import_single_line_error(self):
         tpl_snippet = '''
@@ -281,6 +335,137 @@ custom_types/wordpress.yaml
                                'to verify valid values.'),
                              err.__str__())
 
+    def test_groups(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            requirements:
+              - log_endpoint:
+                  capability: log_endpoint
+
+          mysql_dbms:
+            type: tosca.nodes.DBMS
+            properties:
+              root_password: aaa
+              port: 3376
+
+        groups:
+          webserver_group:
+            type: tosca.groups.Root
+            members: [ server, mysql_dbms ]
+        '''
+        tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+        TopologyTemplate(tpl, None)
+
+    def test_groups_with_missing_required_field(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            requirements:
+              - log_endpoint:
+                  capability: log_endpoint
+
+          mysql_dbms:
+            type: tosca.nodes.DBMS
+            properties:
+              root_password: aaa
+              port: 3376
+
+        groups:
+          webserver_group:
+              members: ['server', 'mysql_dbms']
+        '''
+        tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+        err = self.assertRaises(exception.MissingRequiredFieldError,
+                                TopologyTemplate, tpl, None)
+        expectedmessage = _('Template "webserver_group" is missing '
+                            'required field "type".')
+        self.assertEqual(expectedmessage, err.__str__())
+
+    def test_groups_with_unknown_target(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            requirements:
+              - log_endpoint:
+                  capability: log_endpoint
+
+          mysql_dbms:
+            type: tosca.nodes.DBMS
+            properties:
+              root_password: aaa
+              port: 3376
+
+        groups:
+          webserver_group:
+            type: tosca.groups.Root
+            members: [ serv, mysql_dbms ]
+        '''
+        tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+        expectedmessage = _('"Target member "serv" is not found in '
+                            'node_templates"')
+        err = self.assertRaises(exception.InvalidGroupTargetException,
+                                TopologyTemplate, tpl, None)
+        self.assertEqual(expectedmessage, err.__str__())
+
+    def test_groups_with_repeated_targets(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            requirements:
+              - log_endpoint:
+                  capability: log_endpoint
+
+          mysql_dbms:
+            type: tosca.nodes.DBMS
+            properties:
+              root_password: aaa
+              port: 3376
+
+        groups:
+          webserver_group:
+            type: tosca.groups.Root
+            members: [ server, server, mysql_dbms ]
+        '''
+        tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+        expectedmessage = _('"Member nodes '
+                            '"[\'server\', \'server\', \'mysql_dbms\']" '
+                            'should be >= 1 and not repeated"')
+        err = self.assertRaises(exception.InvalidGroupTargetException,
+                                TopologyTemplate, tpl, None)
+        self.assertEqual(expectedmessage, err.__str__())
+
+    def test_groups_with_only_one_target(self):
+        tpl_snippet = '''
+        node_templates:
+          server:
+            type: tosca.nodes.Compute
+            requirements:
+              - log_endpoint:
+                  capability: log_endpoint
+
+          mysql_dbms:
+            type: tosca.nodes.DBMS
+            properties:
+              root_password: aaa
+              port: 3376
+
+        groups:
+          webserver_group:
+            type: tosca.groups.Root
+            members: []
+        '''
+        tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet))
+        expectedmessage = _('"Member nodes "[]" should be >= 1 '
+                            'and not repeated"')
+        err = self.assertRaises(exception.InvalidGroupTargetException,
+                                TopologyTemplate, tpl, None)
+        self.assertEqual(expectedmessage, err.__str__())
+
     def _custom_types(self):
         custom_types = {}
         def_file = os.path.join(
@@ -962,34 +1147,6 @@ custom_types/wordpress.yaml
                'are "%s".') % valid_versions))
 
     def test_node_template_capabilities_properties(self):
-        tpl_snippet = '''
-        node_templates:
-          server:
-            type: tosca.nodes.Compute
-            capabilities:
-              host:
-                properties:
-                  disk_size: 10 GB
-                  num_cpus: { get_input: cpus }
-                  mem_size: 4096 MB
-              os:
-                properties:
-                  architecture: x86_64
-                  type: Linux
-                  distribution: Fedora
-                  version: 18.0
-              scalable:
-                properties:
-                  min_instances: 1
-                  default_instances: 5
-        '''
-        expectedmessage = _('"properties" of template "server" is missing '
-                            'required field "[\'max_instances\']".')
-        err = self.assertRaises(
-            exception.MissingRequiredFieldError,
-            lambda: self._single_node_template_content_test(tpl_snippet))
-        self.assertEqual(expectedmessage, err.__str__())
-
         # validating capability property values
         tpl_snippet = '''
         node_templates:
@@ -1107,3 +1264,118 @@ custom_types/wordpress.yaml
             metadata: none
         '''
         self._single_node_template_content_test(tpl_snippet_metadata_inline)
+
+    def test_policy_valid_keynames(self):
+        tpl_snippet = '''
+        policies:
+          - servers_placement:
+              type: tosca.policies.Placement
+              description: Apply placement policy to servers
+              metadata: { user1: 1001, user2: 1002 }
+              targets: [ serv1, serv2 ]
+        '''
+        policies = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet))['policies'][0]
+        name = list(policies.keys())[0]
+        Policy(name, policies[name], None, None)
+
+    def test_policy_invalid_keyname(self):
+        tpl_snippet = '''
+        policies:
+          - servers_placement:
+              type: tosca.policies.Placement
+              testkey: testvalue
+        '''
+        policies = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet))['policies'][0]
+        name = list(policies.keys())[0]
+
+        expectedmessage = _('Policy "servers_placement" contains '
+                            'unknown field "testkey". Refer to the '
+                            'definition to verify valid values.')
+        err = self.assertRaises(
+            exception.UnknownFieldError,
+            lambda: Policy(name, policies[name], None, None))
+        self.assertEqual(expectedmessage, err.__str__())
+
+    def test_policy_trigger_valid_keyname(self):
+        tpl_snippet = '''
+        triggers:
+         - resize_compute:
+             description: trigger
+             event_type: tosca.events.resource.utilization
+             schedule:
+               start_time: "2015-05-07T07:00:00Z"
+               end_time: "2015-06-07T07:00:00Z"
+             target_filter:
+               node: master-container
+               requirement: host
+               capability: Container
+             condition:
+               constraint: utilization greater_than 50%
+               period: 60
+               evaluations: 1
+               method : average
+             action:
+               resize: # Operation name
+                inputs:
+                 strategy: LEAST_USED
+                 implementation: Senlin.webhook()
+        '''
+        triggers = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet))['triggers'][0]
+        name = list(triggers.keys())[0]
+        Triggers(name, triggers[name])
+
+    def test_policy_trigger_invalid_keyname(self):
+        tpl_snippet = '''
+        triggers:
+         - resize_compute:
+             description: trigger
+             event_type: tosca.events.resource.utilization
+             schedule:
+               start_time: "2015-05-07T07:00:00Z"
+               end_time: "2015-06-07T07:00:00Z"
+             target_filter1:
+               node: master-container
+               requirement: host
+               capability: Container
+             condition:
+               constraint: utilization greater_than 50%
+               period1: 60
+               evaluations: 1
+               method: average
+             action:
+               resize: # Operation name
+                inputs:
+                 strategy: LEAST_USED
+                 implementation: Senlin.webhook()
+        '''
+        triggers = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet))['triggers'][0]
+        name = list(triggers.keys())[0]
+        expectedmessage = _(
+            'Triggers "resize_compute" contains unknown field '
+            '"target_filter1". Refer to the definition '
+            'to verify valid values.')
+        err = self.assertRaises(
+            exception.UnknownFieldError,
+            lambda: Triggers(name, triggers[name]))
+        self.assertEqual(expectedmessage, err.__str__())
+
+    def test_policy_missing_required_keyname(self):
+        tpl_snippet = '''
+        policies:
+          - servers_placement:
+              description: test description
+        '''
+        policies = (toscaparser.utils.yamlparser.
+                    simple_parse(tpl_snippet))['policies'][0]
+        name = list(policies.keys())[0]
+
+        expectedmessage = _('Template "servers_placement" is missing '
+                            'required field "type".')
+        err = self.assertRaises(
+            exception.MissingRequiredFieldError,
+            lambda: Policy(name, policies[name], None, None))
+        self.assertEqual(expectedmessage, err.__str__())
@@ -10,9 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from toscaparser.common.exception import URLException
 from toscaparser.tests.base import TestCase
-from toscaparser.utils.gettextutils import _
 import toscaparser.utils.urlutils
 import toscaparser.utils.yamlparser
 
@@ -47,14 +45,3 @@ class UrlUtilsTest(TestCase):
             self.url_utils.join_url("http://github.com/proj1/scripts",
                                     "scripts/b.js"),
             "http://github.com/proj1/scripts/b.js")
-
-    def test_load_url_errors(self):
-        url = "http://www.badurl."
-        err_msg = (_('Failed to reach server "%(url)s". Reason is: '
-                   '[Errno -2] Name or service not known.')
-                   % {'url': url})
-        err = self.assertRaises(URLException,
-                                YAML_LOADER,
-                                url,
-                                False)
-        self.assertEqual(err_msg, err.__str__())
 import logging
 
 from toscaparser.common import exception
+from toscaparser.dataentity import DataEntity
 from toscaparser import functions
-from toscaparser.groups import NodeGroup
+from toscaparser.groups import Group
 from toscaparser.nodetemplate import NodeTemplate
 from toscaparser.parameters import Input
 from toscaparser.parameters import Output
+from toscaparser.policy import Policy
 from toscaparser.relationship_template import RelationshipTemplate
 from toscaparser.tpl_relationship_graph import ToscaGraph
+from toscaparser.utils.gettextutils import _
 
 
 # Topology template key names
 SECTIONS = (DESCRIPTION, INPUTS, NODE_TEMPLATES,
             RELATIONSHIP_TEMPLATES, OUTPUTS, GROUPS,
-            SUBSTITUION_MAPPINGS) = \
+            SUBSTITUION_MAPPINGS, POLICIES) = \
            ('description', 'inputs', 'node_templates',
             'relationship_templates', 'outputs', 'groups',
-            'substitution_mappings')
+            'substitution_mappings', 'policies')
 
 log = logging.getLogger("tosca.model")
 
@@ -53,6 +56,7 @@ class TopologyTemplate(object):
             if hasattr(self, 'nodetemplates'):
                 self.graph = ToscaGraph(self.nodetemplates)
             self.groups = self._groups()
+            self.policies = self._policies()
             self._process_intrinsic_functions()
 
     def _inputs(self):
@@ -99,26 +103,73 @@ class TopologyTemplate(object):
     def _substitution_mappings(self):
         pass
 
+    def _policies(self):
+        policies = []
+        for policy in self._tpl_policies():
+            for policy_name, policy_tpl in policy.items():
+                target_list = policy_tpl.get('targets')
+                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)
+        return policies
+
     def _groups(self):
         groups = []
+        member_nodes = None
         for group_name, group_tpl in self._tpl_groups().items():
             member_names = group_tpl.get('members')
-            if member_names and len(member_names) > 1:
-                group = NodeGroup(group_name, group_tpl,
-                                  self._get_group_memerbs(member_names))
-                groups.append(group)
-            else:
-                exception.ExceptionCollector.appendException(ValueError)
+            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)):
+                    exception.ExceptionCollector.appendException(
+                        exception.InvalidGroupTargetException(
+                            message=_('Member nodes "%s" should be >= 1 '
+                                      'and not repeated') % member_names))
+                else:
+                    member_nodes = self._get_group_members(member_names)
+            group = Group(group_name, group_tpl,
+                          member_nodes,
+                          self.custom_defs)
+            groups.append(group)
         return groups
 
-    def _get_group_memerbs(self, member_names):
+    def _get_group_members(self, member_names):
         member_nodes = []
+        self._validate_group_members(member_names)
         for member in member_names:
             for node in self.nodetemplates:
                 if node.name == member:
                     member_nodes.append(node)
         return member_nodes
 
+    def _get_policy_groups(self, member_names):
+        member_groups = []
+        for member in member_names:
+            for group in self.groups:
+                if group.name == member:
+                    member_groups.append(group)
+        return member_groups
+
+    def _validate_group_members(self, members):
+        node_names = []
+        for node in self.nodetemplates:
+            node_names.append(node.name)
+        for member in members:
+            if member not in node_names:
+                exception.ExceptionCollector.appendException(
+                    exception.InvalidGroupTargetException(
+                        message=_('Target member "%s" is not found in '
+                                  'node_templates') % member))
+
     # topology template can act like node template
     # it is exposed by substitution_mappings.
     def nodetype(self):
@@ -153,6 +204,9 @@ class TopologyTemplate(object):
     def _tpl_groups(self):
         return self.tpl.get(GROUPS) or {}
 
+    def _tpl_policies(self):
+        return self.tpl.get(POLICIES) or {}
+
     def _validate_field(self):
         for name in self.tpl:
             if name not in SECTIONS:
@@ -19,6 +19,8 @@ from toscaparser.common.exception import InvalidTemplateVersion
 from toscaparser.common.exception import MissingRequiredFieldError
 from toscaparser.common.exception import UnknownFieldError
 from toscaparser.common.exception import ValidationError
+from toscaparser.elements.entity_type import update_definitions
+from toscaparser.extensions.exttools import ExtTools
 import toscaparser.imports
 from toscaparser.prereq.csar import CSAR
 from toscaparser.topology_template import TopologyTemplate
@@ -32,13 +34,15 @@ 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, DATATYPE_DEFINITIONS) = \
+            CAPABILITY_TYPES, ARTIFACT_TYPES, DATA_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', 'datatype_definitions')
-# Special key names
+            'capability_types', 'artifact_types', 'data_types',
+            'policy_types', 'group_types', 'repositories')
+# Sections that are specific to individual template definitions
 SPECIAL_SECTIONS = (METADATA) = ('metadata')
 
 log = logging.getLogger("tosca.model")
@@ -47,17 +51,43 @@ YAML_LOADER = toscaparser.utils.yamlparser.load_yaml
 
 
 class ToscaTemplate(object):
+    exttools = ExtTools()
 
     VALID_TEMPLATE_VERSIONS = ['tosca_simple_yaml_1_0']
 
+    VALID_TEMPLATE_VERSIONS.extend(exttools.get_versions())
+
+    ADDITIONAL_SECTIONS = {'tosca_simple_yaml_1_0': SPECIAL_SECTIONS}
+
+    ADDITIONAL_SECTIONS.update(exttools.get_sections())
+
     '''Load the template data.'''
-    def __init__(self, path, parsed_params=None, a_file=True):
+    def __init__(self, path=None, parsed_params=None, a_file=True,
+                 yaml_dict_tpl=None):
         ExceptionCollector.start()
         self.a_file = a_file
-        self.input_path = path
-        self.path = self._get_path(path)
-        if self.path:
-            self.tpl = YAML_LOADER(self.path, self.a_file)
+        self.input_path = None
+        self.path = None
+        self.tpl = None
+        if path:
+            self.input_path = path
+            self.path = self._get_path(path)
+            if self.path:
+                self.tpl = YAML_LOADER(self.path, self.a_file)
+            if yaml_dict_tpl:
+                msg = (_('Both path and yaml_dict_tpl arguments were '
+                         'provided. Using path and ignoring yaml_dict_tpl.'))
+                log.info(msg)
+                print(msg)
+        else:
+            if yaml_dict_tpl:
+                self.tpl = yaml_dict_tpl
+            else:
+                ExceptionCollector.appendException(
+                    ValueError(_('No path or yaml_dict_tpl was provided. '
+                                 'There is nothing to parse.')))
+
+        if self.tpl:
             self.parsed_params = parsed_params
             self._validate_field()
             self.version = self._tpl_version()
@@ -70,6 +100,7 @@ class ToscaTemplate(object):
                 self.nodetemplates = self._nodetemplates()
                 self.outputs = self._outputs()
                 self.graph = ToscaGraph(self.nodetemplates)
+
         ExceptionCollector.stop()
         self.verify_template()
 
@@ -114,7 +145,7 @@ class ToscaTemplate(object):
 
     def _get_all_custom_defs(self, imports=None):
         types = [IMPORTS, NODE_TYPES, CAPABILITY_TYPES, RELATIONSHIP_TYPES,
-                 DATATYPE_DEFINITIONS]
+                 DATA_TYPES, POLICY_TYPES, GROUP_TYPES]
         custom_defs_final = {}
         custom_defs = self._get_custom_types(types, imports)
         if custom_defs:
@@ -148,7 +179,7 @@ class ToscaTemplate(object):
         if imports:
             custom_defs = toscaparser.imports.\
                 ImportsLoader(imports, self.path,
-                              type_defs).get_custom_defs()
+                              type_defs, self.tpl).get_custom_defs()
             if not custom_defs:
                 return
 
@@ -171,7 +202,8 @@ class ToscaTemplate(object):
             self.version = version
 
         for name in self.tpl:
-            if name not in SECTIONS and name not in SPECIAL_SECTIONS:
+            if (name not in SECTIONS and
+               name not in self.ADDITIONAL_SECTIONS.get(version, ())):
                 ExceptionCollector.appendException(
                     UnknownFieldError(what='Template', field=name))
 
@@ -181,6 +213,9 @@ class ToscaTemplate(object):
                 InvalidTemplateVersion(
                     what=version,
                     valid_versions=', '. join(self.VALID_TEMPLATE_VERSIONS)))
+        else:
+            if version != 'tosca_simple_yaml_1_0':
+                update_definitions(version)
 
     def _get_path(self, path):
         if path.lower().endswith('.yaml'):
@@ -199,13 +234,22 @@ class ToscaTemplate(object):
 
     def verify_template(self):
         if ExceptionCollector.exceptionsCaught():
-            raise ValidationError(
-                message=(_('\nThe input "%(path)s" failed validation with the '
-                           'following error(s): \n\n\t')
-                         % {'path': self.input_path}) +
-                '\n\t'.join(ExceptionCollector.getExceptionsReport()))
+            if self.input_path:
+                raise ValidationError(
+                    message=(_('\nThe input "%(path)s" failed validation with '
+                               'the following error(s): \n\n\t')
+                             % {'path': self.input_path}) +
+                    '\n\t'.join(ExceptionCollector.getExceptionsReport()))
+            else:
+                raise ValidationError(
+                    message=_('\nThe pre-parsed input failed validation with '
+                              'the following error(s): \n\n\t') +
+                    '\n\t'.join(ExceptionCollector.getExceptionsReport()))
         else:
-            msg = (_('The input "%(path)s" successfully passed validation.') %
-                   {'path': self.input_path})
+            if self.input_path:
+                msg = (_('The input "%(path)s" successfully passed '
+                         'validation.') % {'path': self.input_path})
+            else:
+                msg = _('The pre-parsed input successfully passed validation.')
+
             log.info(msg)
-            print(msg)
diff --git a/tosca2heat/tosca-parser/toscaparser/triggers.py b/tosca2heat/tosca-parser/toscaparser/triggers.py
new file mode 100644 (file)
index 0000000..9edeef4
--- /dev/null
@@ -0,0 +1,68 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+import logging
+
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import UnknownFieldError
+from toscaparser.entity_template import EntityTemplate
+
+SECTIONS = (DESCRIPTION, EVENT, SCHEDULE, TARGET_FILTER, CONDITION, ACTION) = \
+           ('description', 'event_type', 'schedule',
+            'target_filter', 'condition', 'action')
+CONDITION_KEYNAMES = (CONTRAINT, PERIOD, EVALUATIONS, METHOD) = \
+                     ('constraint', 'period', 'evaluations', 'method')
+log = logging.getLogger('tosca')
+
+
+class Triggers(EntityTemplate):
+
+    '''Triggers defined in policies of topology template'''
+
+    def __init__(self, name, trigger_tpl):
+        self.name = name
+        self.trigger_tpl = trigger_tpl
+        self._validate_keys()
+        self._validate_condition()
+
+    def get_description(self):
+        return self.trigger_tpl['description']
+
+    def get_event(self):
+        return self.trigger_tpl['event_type']
+
+    def get_schedule(self):
+        return self.trigger_tpl['schedule']
+
+    def get_target_filter(self):
+        return self.trigger_tpl['target_filter']
+
+    def get_condition(self):
+        return self.trigger_tpl['condition']
+
+    def get_action(self):
+        return self.trigger_tpl['action']
+
+    def _validate_keys(self):
+        for key in self.trigger_tpl.keys():
+            if key not in SECTIONS:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Triggers "%s"' % self.name,
+                                      field=key))
+
+    def _validate_condition(self):
+        for key in self.get_condition():
+            if key not in CONDITION_KEYNAMES:
+                ExceptionCollector.appendException(
+                    UnknownFieldError(what='Triggers "%s"' % self.name,
+                                      field=key))
diff --git a/tosca2heat/tosca-parser/toscaparser/utils/__init__.py b/tosca2heat/tosca-parser/toscaparser/utils/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
@@ -68,6 +68,18 @@ def validate_list(value):
     return value
 
 
+def validate_range(value):
+    validate_list(value)
+    if isinstance(value, list):
+        if len(value) != 2 or not (value[0] <= value[1]):
+            ExceptionCollector.appendException(
+                ValueError(_('"%s" is not a valid range.') % value))
+        validate_integer(value[0])
+        if not value[1] == "UNBOUNDED":
+            validate_integer(value[1])
+    return value
+
+
 def validate_map(value):
     if not isinstance(value, collections.Mapping):
         ExceptionCollector.appendException(
@@ -89,7 +101,19 @@ def validate_boolean(value):
 
 
 def validate_timestamp(value):
-    return dateutil.parser.parse(value)
+    try:
+        # Note: we must return our own exception message
+        # as dateutil's parser returns different types / values on
+        # different systems. OSX, for example, returns a tuple
+        # containing a different error message than Linux
+        dateutil.parser.parse(value)
+    except Exception as e:
+        original_err_msg = str(e)
+        log.error(original_err_msg)
+        ExceptionCollector.appendException(
+            ValueError(_('"%(val)s" is not a valid timestamp. "%(msg)s"') %
+                       {'val': value, 'msg': original_err_msg}))
+    return
 
 
 class TOSCAVersionProperty(object):
 
 import codecs
 from collections import OrderedDict
+
+from six.moves import urllib
+import yaml
+
 from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import URLException
 from toscaparser.utils.gettextutils import _
-import yaml
 
-try:
-    # Python 3.x
-    import urllib.request as urllib2
-except ImportError:
-    # Python 2.x
-    import urllib2
 
 if hasattr(yaml, 'CSafeLoader'):
     yaml_loader = yaml.CSafeLoader
@@ -34,8 +31,8 @@ def load_yaml(path, a_file=True):
     f = None
     try:
         f = codecs.open(path, encoding='utf-8', errors='strict') if a_file \
-            else urllib2.urlopen(path)
-    except urllib2.URLError as e:
+            else urllib.request.urlopen(path)
+    except urllib.error.URLError as e:
         if hasattr(e, 'reason'):
             msg = (_('Failed to reach server "%(path)s". Reason is: '
                      '%(reason)s.')
similarity index 96%
rename from tosca2heat/tosca-parser-0.3.0/tox.ini
rename to tosca2heat/tosca-parser/tox.ini
index 321d712..9e5f365 100644 (file)
@@ -1,6 +1,6 @@
 [tox]
 minversion = 1.6
-envlist = py27,py34,pypy,pep8
+envlist = py34,py27,pypy,pep8
 skipsdist = True
 
 [testenv]