From c8201c119ec686e79797721156767685fe848aca Mon Sep 17 00:00:00 2001 From: shangxdy Date: Thu, 7 Apr 2016 14:08:49 -0400 Subject: Update tosca lib to version 0.5 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 Signed-off-by: shangxdy --- .../translator/hot/__init__.py | 0 .../translator/hot/syntax/__init__.py | 0 .../translator/hot/syntax/hot_output.py | 25 -- .../translator/hot/syntax/hot_parameter.py | 47 --- .../translator/hot/syntax/hot_resource.py | 308 ---------------- .../translator/hot/syntax/hot_template.py | 78 ---- .../translator/hot/tests/__init__.py | 0 .../translator/hot/tests/test_hot_parameter.py | 44 --- .../translator/hot/tests/test_translate_inputs.py | 351 ------------------ .../translator/hot/tests/test_translate_outputs.py | 50 --- .../translator/hot/tosca/__init__.py | 0 .../translator/hot/tosca/tests/__init__.py | 0 .../hot/tosca/tests/test_tosca_blockstorage.py | 84 ----- .../hot/tosca/tests/test_tosca_compute.py | 253 ------------- .../hot/tosca/tests/test_tosca_objectstore.py | 71 ---- .../translator/hot/tosca/tosca_block_storage.py | 69 ---- .../hot/tosca/tosca_block_storage_attachment.py | 48 --- .../translator/hot/tosca/tosca_compute.py | 274 -------------- .../translator/hot/tosca/tosca_database.py | 30 -- .../translator/hot/tosca/tosca_dbms.py | 30 -- .../translator/hot/tosca/tosca_network_network.py | 120 ------ .../translator/hot/tosca/tosca_network_port.py | 117 ------ .../translator/hot/tosca/tosca_object_storage.py | 58 --- .../hot/tosca/tosca_software_component.py | 30 -- .../translator/hot/tosca/tosca_web_application.py | 30 -- .../translator/hot/tosca/tosca_webserver.py | 30 -- .../translator/hot/tosca_translator.py | 64 ---- .../translator/hot/translate_inputs.py | 153 -------- .../translator/hot/translate_node_templates.py | 408 --------------------- .../translator/hot/translate_outputs.py | 42 --- 30 files changed, 2814 deletions(-) delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/__init__.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/syntax/__init__.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_output.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_parameter.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_resource.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_template.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tests/__init__.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_hot_parameter.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_inputs.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_outputs.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/__init__.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/__init__.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_blockstorage.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_compute.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_objectstore.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage_attachment.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_database.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_dbms.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_network.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_port.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_object_storage.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_software_component.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_web_application.py delete mode 100755 tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_webserver.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/tosca_translator.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/translate_node_templates.py delete mode 100644 tosca2heat/heat-translator-0.3.0/translator/hot/translate_outputs.py (limited to 'tosca2heat/heat-translator-0.3.0/translator/hot') diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/__init__.py b/tosca2heat/heat-translator-0.3.0/translator/hot/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/__init__.py b/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_output.py b/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_output.py deleted file mode 100644 index ad77fb3..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_output.py +++ /dev/null @@ -1,25 +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 HotOutput(object): - '''Attributes for HOT output section.''' - - def __init__(self, name, value, description=None): - self.name = name - self.value = value - self.description = description - - def get_dict_output(self): - return {self.name: {'value': self.value, - 'description': self.description}} diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_parameter.py b/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_parameter.py deleted file mode 100644 index 02c27da..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_parameter.py +++ /dev/null @@ -1,47 +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 collections import OrderedDict - -KEYS = (TYPE, DESCRIPTION, DEFAULT, CONSTRAINTS, HIDDEN, LABEL) = \ - ('type', 'description', 'default', 'constraints', 'hidden', 'label') - - -class HotParameter(object): - '''Attributes for HOT parameter section.''' - - def __init__(self, name, type, label=None, description=None, default=None, - hidden=None, constraints=None): - self.name = name - self.type = type - self.label = label - self.description = description - self.default = default - self.hidden = hidden - self.constraints = constraints - - def get_dict_output(self): - param_sections = OrderedDict() - param_sections[TYPE] = self.type - if self.label: - param_sections[LABEL] = self.label - if self.description: - param_sections[DESCRIPTION] = self.description - if self.default: - param_sections[DEFAULT] = self.default - if self.hidden: - param_sections[HIDDEN] = self.hidden - if self.constraints: - param_sections[CONSTRAINTS] = self.constraints - - return {self.name: param_sections} diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_resource.py b/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_resource.py deleted file mode 100644 index 3ca9b03..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_resource.py +++ /dev/null @@ -1,308 +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 collections import OrderedDict -import six - -from toscaparser.functions import GetInput -from toscaparser.nodetemplate import NodeTemplate -from toscaparser.utils.gettextutils import _ - - -SECTIONS = (TYPE, PROPERTIES, MEDADATA, DEPENDS_ON, UPDATE_POLICY, - DELETION_POLICY) = \ - ('type', 'properties', 'metadata', - 'depends_on', 'update_policy', 'deletion_policy') - - -class HotResource(object): - '''Base class for TOSCA node type translation to Heat resource type.''' - - def __init__(self, nodetemplate, name=None, type=None, properties=None, - metadata=None, depends_on=None, - update_policy=None, deletion_policy=None): - self.nodetemplate = nodetemplate - if name: - self.name = name - else: - self.name = nodetemplate.name - self.type = type - self.properties = properties or {} - # special case for HOT softwareconfig - if type == 'OS::Heat::SoftwareConfig': - self.properties['group'] = 'script' - self.metadata = metadata - - # The difference between depends_on and depends_on_nodes is - # that depends_on defines dependency in the context of the - # HOT template and it is used during the template output. - # Depends_on_nodes defines the direct dependency between the - # tosca nodes and is not used during the output of the - # HOT template but for internal processing only. When a tosca - # node depends on another node it will be always added to - # depends_on_nodes but not always to depends_on. For example - # if the source of dependency is a server, the dependency will - # be added as properties.get_resource and not depends_on - if depends_on: - self.depends_on = depends_on - self.depends_on_nodes = depends_on - else: - self.depends_on = [] - self.depends_on_nodes = [] - self.update_policy = update_policy - self.deletion_policy = deletion_policy - self.group_dependencies = {} - # if hide_resource is set to true, then this resource will not be - # generated in the output yaml. - self.hide_resource = False - - def handle_properties(self): - # the property can hold a value or the intrinsic function get_input - # for value, copy it - # for get_input, convert to get_param - for prop in self.nodetemplate.get_properties_objects(): - pass - - def handle_life_cycle(self): - hot_resources = [] - 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'] - - # create HotResource for each interface used for deployment: - # create, start, configure - # ignore the other interfaces - # observe the order: create, start, configure - # use the current HotResource for the first interface 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: - reserve_current = operation - break - - # create the set of SoftwareDeployment and SoftwareConfig for - # the interface operations - 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' - hot_resources.append( - HotResource(self.nodetemplate, - config_name, - 'OS::Heat::SoftwareConfig', - {'config': - {'get_file': interface.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: - 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 - else: - sd_config = {'config': {'get_resource': config_name}, - 'server': {'get_resource': - hosting_on_server}} - deploy_resource = \ - HotResource(self.nodetemplate, - deploy_name, - 'OS::Heat::SoftwareDeployment', - sd_config) - hot_resources.append(deploy_resource) - deploy_lookup[interface.name] = deploy_resource - lifecycle_inputs = self._get_lifecycle_inputs(interface) - 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 - # 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) - for preceding_op in \ - reversed(interfaces_deploy_sequence[:op_index]): - preceding_hot = deploy_lookup.get(preceding_op) - if preceding_hot: - hot.depends_on.append(preceding_hot) - hot.depends_on_nodes.append(preceding_hot) - group[preceding_hot] = hot - break - - # save this dependency chain in the set of HOT resources - self.group_dependencies.update(group) - for hot in hot_resources: - hot.group_dependencies.update(group) - - return hot_resources - - def handle_connectsto(self, tosca_source, tosca_target, hot_source, - hot_target, config_location, operation): - # The ConnectsTo relationship causes a configuration operation in - # the target. - # This hot resource is the software config portion in the HOT template - # This method adds the matching software deployment with the proper - # target server and dependency - if config_location == 'target': - hosting_server = hot_target._get_hosting_server() - hot_depends = hot_target - elif config_location == 'source': - hosting_server = self._get_hosting_server() - hot_depends = hot_source - deploy_name = tosca_source.name + '_' + tosca_target.name + \ - '_connect_deploy' - sd_config = {'config': {'get_resource': self.name}, - 'server': {'get_resource': hosting_server.name}} - deploy_resource = \ - HotResource(self.nodetemplate, - deploy_name, - 'OS::Heat::SoftwareDeployment', - sd_config, - depends_on=[hot_depends]) - connect_inputs = self._get_connect_inputs(config_location, operation) - if connect_inputs: - deploy_resource.properties['input_values'] = connect_inputs - - return deploy_resource - - def handle_expansion(self): - pass - - def handle_hosting(self): - # handle hosting server for the OS:HEAT::SoftwareDeployment - # from the TOSCA nodetemplate, traverse the relationship chain - # down to the server - if self.type == 'OS::Heat::SoftwareDeployment': - # skip if already have hosting - # If type is NodeTemplate, look up corresponding HotResrouce - host_server = self.properties.get('server') - if host_server is None or not host_server['get_resource']: - raise Exception(_("Internal Error: expecting host " - "in software deployment")) - elif isinstance(host_server['get_resource'], NodeTemplate): - self.properties['server']['get_resource'] = \ - host_server['get_resource'].name - - def top_of_chain(self): - dependent = self.group_dependencies.get(self) - if dependent is None: - return self - else: - return dependent.top_of_chain() - - def get_dict_output(self): - resource_sections = OrderedDict() - resource_sections[TYPE] = self.type - if self.properties: - resource_sections[PROPERTIES] = self.properties - if self.metadata: - resource_sections[MEDADATA] = self.metadata - if self.depends_on: - resource_sections[DEPENDS_ON] = [] - for depend in self.depends_on: - resource_sections[DEPENDS_ON].append(depend.name) - if self.update_policy: - resource_sections[UPDATE_POLICY] = self.update_policy - if self.deletion_policy: - resource_sections[DELETION_POLICY] = self.deletion_policy - - return {self.name: resource_sections} - - def _get_lifecycle_inputs(self, interface): - # 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 - return {} - else: - # the interface is a dict {'implemenation': xxx, 'input': yyy} - inputs = interface.value.get('inputs') - deploy_inputs = {} - if inputs: - for name, value in six.iteritems(inputs): - deploy_inputs[name] = value - return deploy_inputs - - def _get_connect_inputs(self, config_location, operation): - if config_location == 'target': - inputs = operation.get('pre_configure_target').get('inputs') - elif config_location == 'source': - inputs = operation.get('pre_configure_source').get('inputs') - deploy_inputs = {} - if inputs: - for name, value in six.iteritems(inputs): - deploy_inputs[name] = value - return deploy_inputs - - def _get_hosting_server(self, node_template=None): - # find the server that hosts this software by checking the - # requirements and following the hosting chain - this_node_template = self.nodetemplate \ - if node_template is None else node_template - for requirement in this_node_template.requirements: - for requirement_name, assignment in six.iteritems(requirement): - for check_node in this_node_template.related_nodes: - # check if the capability is Container - if isinstance(assignment, dict): - node_name = assignment.get('node') - else: - node_name = assignment - if node_name and node_name == check_node.name: - if self._is_container_type(requirement_name, - check_node): - return check_node - elif check_node.related_nodes: - return self._get_hosting_server(check_node) - return None - - def _is_container_type(self, requirement_name, node): - # 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': - return True - else: - return False - - def get_hot_attribute(self, attribute, args): - # this is a place holder and should be implemented by the subclass - # if translation is needed for the particular attribute - raise Exception(_("No translation in TOSCA type {0} for attribute " - "{1}").format(self.nodetemplate.type, attribute)) - - def _get_tosca_props(self, properties): - tosca_props = {} - for prop in self.nodetemplate.get_properties_objects(): - if isinstance(prop.value, GetInput): - tosca_props[prop.name] = {'get_param': prop.value.input_name} - else: - tosca_props[prop.name] = prop.value - return tosca_props diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_template.py b/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_template.py deleted file mode 100644 index 5cc97c6..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/syntax/hot_template.py +++ /dev/null @@ -1,78 +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 collections import OrderedDict -import textwrap -import yaml - - -class HotTemplate(object): - '''Container for full Heat Orchestration template.''' - - SECTIONS = (VERSION, DESCRIPTION, PARAMETER_GROUPS, PARAMETERS, - RESOURCES, OUTPUTS, MAPPINGS) = \ - ('heat_template_version', 'description', 'parameter_groups', - 'parameters', 'resources', 'outputs', '__undefined__') - - VERSIONS = (LATEST,) = ('2013-05-23',) - - def __init__(self): - self.resources = [] - self.outputs = [] - self.parameters = [] - self.description = "" - - def represent_ordereddict(self, dumper, data): - nodes = [] - for key, value in data.items(): - node_key = dumper.represent_data(key) - node_value = dumper.represent_data(value) - nodes.append((node_key, node_value)) - return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', nodes) - - def output_to_yaml(self): - dict_output = OrderedDict() - # Version - version_string = self.VERSION + ": " + self.LATEST + "\n\n" - - # Description - desc_str = "" - if self.description: - # Wrap the text to a new line if the line exceeds 80 characters. - wrapped_txt = "\n ".join(textwrap.wrap(self.description, 80)) - desc_str = self.DESCRIPTION + ": >\n " + wrapped_txt + "\n\n" - - # Parameters - all_params = OrderedDict() - for parameter in self.parameters: - all_params.update(parameter.get_dict_output()) - dict_output.update({self.PARAMETERS: all_params}) - - # Resources - all_resources = OrderedDict() - for resource in self.resources: - if not resource.hide_resource: - all_resources.update(resource.get_dict_output()) - dict_output.update({self.RESOURCES: all_resources}) - - # Outputs - all_outputs = OrderedDict() - for output in self.outputs: - all_outputs.update(output.get_dict_output()) - dict_output.update({self.OUTPUTS: all_outputs}) - - yaml.add_representer(OrderedDict, self.represent_ordereddict) - yaml_string = yaml.dump(dict_output, default_flow_style=False) - # get rid of the '' from yaml.dump around numbers - yaml_string = yaml_string.replace('\'', '') - return version_string + desc_str + yaml_string diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/__init__.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_hot_parameter.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_hot_parameter.py deleted file mode 100644 index 8d3f535..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_hot_parameter.py +++ /dev/null @@ -1,44 +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 collections import OrderedDict - -from toscaparser.tests.base import TestCase -from translator.hot.syntax.hot_parameter import CONSTRAINTS -from translator.hot.syntax.hot_parameter import DEFAULT -from translator.hot.syntax.hot_parameter import DESCRIPTION -from translator.hot.syntax.hot_parameter import HIDDEN -from translator.hot.syntax.hot_parameter import HotParameter -from translator.hot.syntax.hot_parameter import LABEL -from translator.hot.syntax.hot_parameter import TYPE - -TEST_CONSTRAINTS = {'equal': 'allowed_values', 'greater_than': 'range'} - - -class HotParameterTest(TestCase): - - # This test ensures the variables set during the creation of a HotParameter - # object are returned in an OrderedDict when calling get_dict_output(). - def test_dict_output(self): - name = 'HotParameterTest' - hot_parameter = HotParameter(name, 'Type', - label='Label', - description='Description', - default='Default', - hidden=True, - constraints=TEST_CONSTRAINTS) - expected_dict = OrderedDict([(TYPE, 'Type'), (LABEL, 'Label'), - (DESCRIPTION, 'Description'), - (DEFAULT, 'Default'), (HIDDEN, True), - (CONSTRAINTS, TEST_CONSTRAINTS)]) - - self.assertEqual(hot_parameter.get_dict_output()[name], expected_dict) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_inputs.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_inputs.py deleted file mode 100644 index 2b302ab..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_inputs.py +++ /dev/null @@ -1,351 +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 collections import OrderedDict -from toscaparser.parameters import Input -from toscaparser.tests.base import TestCase -from toscaparser.utils.gettextutils import _ -import toscaparser.utils.yamlparser -from translator.common.utils import CompareUtils -from translator.hot.translate_inputs import TranslateInputs - - -class ToscaTemplateInputValidationTest(TestCase): - - def _translate_input_test(self, tpl_snippet, input_params, - expectedmessage=None, - expected_hot_params=None): - inputs_dict = (toscaparser.utils.yamlparser. - simple_parse(tpl_snippet)['inputs']) - inputs = [] - for name, attrs in inputs_dict.items(): - input = Input(name, attrs) - inputs.append(input) - - translateinput = TranslateInputs(inputs, input_params) - try: - resulted_hot_params = translateinput.translate() - if expected_hot_params: - self._compare_hot_params(resulted_hot_params, - expected_hot_params) - except Exception as err: - self.assertEqual(expectedmessage, err.__str__()) - - def _compare_hot_params(self, resulted_hot_params, - expected_hot_params): - for expected_param in expected_hot_params: - for resulted_param_obj in resulted_hot_params: - resulted_param = resulted_param_obj.get_dict_output() - result = CompareUtils.compare_dicts(expected_param, - resulted_param) - if not result: - raise Exception(_("hot input and resulted input " - "params are not equal.")) - - def test_invalid_input_type(self): - tpl_snippet = ''' - inputs: - cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - valid_values: [ 1, 2, 4, 8 ] - ''' - - input_params = {'cpus': '0.3'} - expectedmessage = _('"0.3" is not an integer.') - self._translate_input_test(tpl_snippet, input_params, - expectedmessage) - - def test_invalid_input_constraints_for_equal(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - equal: 1 - ''' - - input_params = {'num_cpus': '0'} - expectedmessage = _('The value "0" of property "num_cpus" is not ' - 'equal to "1".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_greater_or_equal(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - greater_or_equal: 1 - ''' - - input_params = {'num_cpus': '0'} - expectedmessage = _('The value "0" of property "num_cpus" must be ' - 'greater than or equal to "1".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_greater_than(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - greater_than: 1 - ''' - - input_params = {'num_cpus': '0'} - expectedmessage = _('The value "0" of property "num_cpus" must be ' - 'greater than "1".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_less_than(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - less_than: 8 - ''' - - input_params = {'num_cpus': '8'} - expectedmessage = _('The value "8" of property "num_cpus" must be ' - 'less than "8".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_less_or_equal(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - less_or_equal: 8 - ''' - - input_params = {'num_cpus': '9'} - expectedmessage = _('The value "9" of property "num_cpus" must be ' - 'less than or equal to "8".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_valid_values(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - valid_values: [ 1, 2, 4, 8 ] - ''' - - input_params = {'num_cpus': '3'} - expectedmessage = _('The value "3" of property "num_cpus" is not ' - 'valid. Expected a value from "[1, 2, 4, 8]".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_in_range(self): - tpl_snippet = ''' - inputs: - num_cpus: - type: integer - description: Number of CPUs for the server. - constraints: - - in_range: [ 1, 8 ] - ''' - - input_params = {'num_cpus': '10'} - expectedmessage = _('The value "10" of property "num_cpus" is out of ' - 'range "(min:1, max:8)".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_min_length(self): - tpl_snippet = ''' - inputs: - user_name: - type: string - description: Name of the user. - constraints: - - min_length: 8 - ''' - - input_params = {'user_name': 'abcd'} - expectedmessage = _('Length of value "abcd" of property "user_name" ' - 'must be at least "8".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_max_length(self): - tpl_snippet = ''' - inputs: - user_name: - type: string - description: Name of the user. - constraints: - - max_length: 6 - ''' - - input_params = {'user_name': 'abcdefg'} - expectedmessage = _('Length of value "abcdefg" of property ' - '"user_name" must be no greater than "6".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_invalid_input_constraints_for_pattern(self): - tpl_snippet = ''' - inputs: - user_name: - type: string - description: Name of the user. - constraints: - - pattern: '^\w+$' - ''' - - input_params = {'user_name': '1-abc'} - expectedmessage = _('The value "1-abc" of property "user_name" does ' - 'not match pattern "^\\w+$".') - self._translate_input_test(tpl_snippet, input_params, expectedmessage) - - def test_valid_input_storage_size(self): - tpl_snippet = ''' - inputs: - storage_size: - type: scalar-unit.size - description: size of the storage volume. - ''' - - expectedmessage = _('both equal.') - input_params = {'storage_size': '2 GB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 2)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - """ TOSCA 2000 MB => 2 GB HOT conversion""" - input_params = {'storage_size': '2000 MB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 2)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - """ TOSCA 2048 MB => 2 GB HOT conversion""" - input_params = {'storage_size': '2048 MB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 2)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - """ TOSCA 2 MB => 1 GB HOT conversion""" - input_params = {'storage_size': '2 MB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 1)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - """ TOSCA 1024 MB => 1 GB HOT conversion""" - input_params = {'storage_size': '1024 MB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 1)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - """ TOSCA 1024 MiB => 1 GB HOT conversion""" - input_params = {'storage_size': '1024 MiB'} - expected_hot_params = [{'storage_size': - OrderedDict([('type', 'number'), - ('description', - 'size of the storage volume.'), - ('default', 1)])}] - self._translate_input_test(tpl_snippet, input_params, - expectedmessage, expected_hot_params) - - def test_invalid_input_storage_size(self): - tpl_snippet = ''' - inputs: - storage_size: - type: scalar-unit.size - description: size of the storage volume. - ''' - - input_params = {'storage_size': '0 MB'} - expectedmsg = _("Unit value should be > 0.") - self._translate_input_test(tpl_snippet, input_params, expectedmsg) - - input_params = {'storage_size': '-2 MB'} - expectedmsg = _('"-2 MB" is not a valid scalar-unit.') - self._translate_input_test(tpl_snippet, input_params, expectedmsg) - - def test_invalid_input_type_version(self): - tpl_snippet = ''' - inputs: - version: - type: version - ''' - - input_params = {'version': '0.a'} - expectedmessage = _('Value of TOSCA version property ' - '"0.a" is invalid.') - self._translate_input_test(tpl_snippet, input_params, - expectedmessage) - - input_params = {'version': '0.0.0.abc'} - expectedmessage = _('Value of TOSCA version property ' - '"0.0.0.abc" is invalid.') - self._translate_input_test(tpl_snippet, input_params, - expectedmessage) - - def test_valid_input_type_version(self): - tpl_snippet = ''' - inputs: - version: - type: version - default: 12 - ''' - - expectedmessage = _('both equal.') - input_params = {'version': '18'} - expected_hot_params = [{'version': - OrderedDict([('type', 'string'), - ('default', '18.0')])}] - self._translate_input_test(tpl_snippet, input_params, expectedmessage, - expected_hot_params) - - input_params = {'version': '18.0'} - expected_hot_params = [{'version': - OrderedDict([('type', 'string'), - ('default', '18.0')])}] - self._translate_input_test(tpl_snippet, input_params, expectedmessage, - expected_hot_params) - - input_params = {'version': '18.0.1'} - expected_hot_params = [{'version': - OrderedDict([('type', 'string'), - ('default', '18.0.1')])}] - self._translate_input_test(tpl_snippet, input_params, expectedmessage, - expected_hot_params) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_outputs.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_outputs.py deleted file mode 100644 index 955150e..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tests/test_translate_outputs.py +++ /dev/null @@ -1,50 +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. - -import os -from toscaparser.tests.base import TestCase -from toscaparser.tosca_template import ToscaTemplate -import toscaparser.utils.yamlparser -from translator.hot.tosca_translator import TOSCATranslator - - -class ToscaTemplateOutputTest(TestCase): - - def test_translate_output(self): - tosca_tpl = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "../../tests/data/" - "tosca_nodejs_mongodb_two_instances.yaml") - tosca = ToscaTemplate(tosca_tpl) - translate = TOSCATranslator(tosca, []) - hot_translation = translate.translate() - - expected_output = {'nodejs_url': - {'description': 'URL for the nodejs ' - 'server, http://:3000', - 'value': - {'get_attr': - ['app_server', 'networks', 'private', 0]}}, - 'mongodb_url': - {'description': 'URL for the mongodb server.', - 'value': - {'get_attr': - ['mongo_server', 'networks', 'private', 0]}}} - - hot_translation_dict = \ - toscaparser.utils.yamlparser.simple_parse(hot_translation) - - outputs = hot_translation_dict.get('outputs') - for resource_name in outputs: - translated_value = outputs.get(resource_name) - expected_value = expected_output.get(resource_name) - self.assertEqual(translated_value, expected_value) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/__init__.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/__init__.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_blockstorage.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_blockstorage.py deleted file mode 100644 index d4fffe1..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_blockstorage.py +++ /dev/null @@ -1,84 +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 InvalidPropertyValueError -from toscaparser.nodetemplate import NodeTemplate -from toscaparser.tests.base import TestCase -from toscaparser.utils.gettextutils import _ -import toscaparser.utils.yamlparser -from translator.hot.tosca.tosca_block_storage import ToscaBlockStorage - - -class ToscaBlockStoreTest(TestCase): - - def _tosca_blockstore_test(self, tpl_snippet, expectedprops): - nodetemplates = (toscaparser.utils.yamlparser. - simple_parse(tpl_snippet)['node_templates']) - name = list(nodetemplates.keys())[0] - try: - nodetemplate = NodeTemplate(name, nodetemplates) - tosca_block_store = ToscaBlockStorage(nodetemplate) - tosca_block_store.handle_properties() - if not self._compare_properties(tosca_block_store.properties, - expectedprops): - raise Exception(_("Hot Properties are not" - " same as expected properties")) - except Exception: - # for time being rethrowing. Will be handled future based - # on new development - raise - - def _compare_properties(self, hotprops, expectedprops): - return all(item in hotprops.items() for item in expectedprops.items()) - - def test_node_blockstorage_with_properties(self): - tpl_snippet = ''' - node_templates: - my_storage: - type: tosca.nodes.BlockStorage - properties: - size: 1024 MiB - snapshot_id: abc - ''' - expectedprops = {'snapshot_id': 'abc', - 'size': 1} - self._tosca_blockstore_test( - tpl_snippet, - expectedprops) - - tpl_snippet = ''' - node_templates: - my_storage: - type: tosca.nodes.BlockStorage - properties: - size: 124 MB - snapshot_id: abc - ''' - expectedprops = {'snapshot_id': 'abc', - 'size': 1} - self._tosca_blockstore_test( - tpl_snippet, - expectedprops) - - def test_node_blockstorage_with_invalid_size_property(self): - tpl_snippet = ''' - node_templates: - my_storage: - type: tosca.nodes.BlockStorage - properties: - size: 0 MB - snapshot_id: abc - ''' - expectedprops = {} - self.assertRaises(InvalidPropertyValueError, - lambda: self._tosca_blockstore_test(tpl_snippet, - expectedprops)) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_compute.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_compute.py deleted file mode 100644 index f956344..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_compute.py +++ /dev/null @@ -1,253 +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. - -import json -import mock -from mock import patch - -from toscaparser.nodetemplate import NodeTemplate -from toscaparser.tests.base import TestCase -from toscaparser.utils.gettextutils import _ -import toscaparser.utils.yamlparser -from translator.hot.tosca.tosca_compute import ToscaCompute - - -class ToscaComputeTest(TestCase): - - def _tosca_compute_test(self, tpl_snippet, expectedprops): - nodetemplates = (toscaparser.utils.yamlparser. - simple_parse(tpl_snippet)['node_templates']) - name = list(nodetemplates.keys())[0] - try: - nodetemplate = NodeTemplate(name, nodetemplates) - nodetemplate.validate() - toscacompute = ToscaCompute(nodetemplate) - toscacompute.handle_properties() - if not self._compare_properties(toscacompute.properties, - expectedprops): - raise Exception(_("Hot Properties are not" - " same as expected properties")) - except Exception: - # for time being rethrowing. Will be handled future based - # on new development in Glance and Graffiti - raise - - def _compare_properties(self, hotprops, expectedprops): - return all(item in hotprops.items() for item in expectedprops.items()) - - def test_node_compute_with_host_and_os_capabilities(self): - tpl_snippet = ''' - 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 - ''' - expectedprops = {'flavor': 'm1.large', - 'image': 'fedora-amd64-heat-config'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_without_os_capabilities(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - host: - properties: - disk_size: 10 GB - num_cpus: 4 - mem_size: 4 GB - #left intentionally - ''' - expectedprops = {'flavor': 'm1.large', - 'image': None} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_without_host_capabilities(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - os: - properties: - architecture: x86_64 - type: Linux - distribution: Fedora - version: 18.0 - ''' - expectedprops = {'flavor': None, - 'image': 'fedora-amd64-heat-config'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_without_properties_and_os_capabilities(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - properties: - #left intentionally - capabilities: - #left intentionally - ''' - expectedprops = {'flavor': None, - 'image': None} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_with_only_type(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - ''' - expectedprops = {'flavor': None, - 'image': None} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_host_capabilities_without_properties(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - host: - properties: - #left intentionally - ''' - expectedprops = {'flavor': 'm1.nano'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_host_capabilities_without_disk_size(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - host: - properties: - num_cpus: 4 - mem_size: 4 GB - ''' - expectedprops = {'flavor': 'm1.large'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_host_capabilities_without_mem_size(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - host: - properties: - num_cpus: 4 - disk_size: 10 GB - ''' - expectedprops = {'flavor': 'm1.large'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - def test_node_compute_host_capabilities_without_mem_size_disk_size(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.Compute - capabilities: - host: - properties: - num_cpus: 4 - ''' - expectedprops = {'flavor': 'm1.large'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) - - @patch('requests.post') - @patch('requests.get') - @patch('os.getenv') - def test_node_compute_with_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.hot.tosca.tosca_compute.ToscaCompute.' - '_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_response.status_code = 200 - mock_ks_content = { - 'access': { - 'token': { - 'id': 'd1dfa603-3662-47e0-b0b6-3ae7914bdf76' - }, - 'serviceCatalog': [{ - 'type': 'compute', - 'endpoints': [{ - 'publicURL': 'http://abc.com' - }] - }] - } - } - mock_ks_response.content = json.dumps(mock_ks_content) - mock_nova_response = mock.MagicMock() - mock_nova_response.status_code = 200 - mock_flavor_content = { - 'flavors': [{ - 'name': 'm1.mock_flavor', - 'ram': 1024, - 'disk': 1, - 'vcpus': 1 - }] - } - mock_nova_response.content = \ - json.dumps(mock_flavor_content) - mock_post.return_value = mock_ks_response - mock_get.return_value = mock_nova_response - expectedprops = {'flavor': 'm1.mock_flavor'} - self._tosca_compute_test( - tpl_snippet, - expectedprops) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_objectstore.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_objectstore.py deleted file mode 100644 index 4c42794..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tests/test_tosca_objectstore.py +++ /dev/null @@ -1,71 +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.nodetemplate import NodeTemplate -from toscaparser.tests.base import TestCase -from toscaparser.utils.gettextutils import _ -import toscaparser.utils.yamlparser -from translator.hot.tosca.tosca_object_storage import ToscaObjectStorage - - -class ToscaObjectStoreTest(TestCase): - - def _tosca_objectstore_test(self, tpl_snippet, expectedprops): - nodetemplates = (toscaparser.utils.yamlparser. - simple_parse(tpl_snippet)['node_templates']) - name = list(nodetemplates.keys())[0] - try: - nodetemplate = NodeTemplate(name, nodetemplates) - tosca_object_store = ToscaObjectStorage(nodetemplate) - tosca_object_store.handle_properties() - if not self._compare_properties(tosca_object_store.properties, - expectedprops): - raise Exception(_("Hot Properties are not" - " same as expected properties")) - except Exception: - # for time being rethrowing. Will be handled future based - # on new development - raise - - def _compare_properties(self, hotprops, expectedprops): - return all(item in hotprops.items() for item in expectedprops.items()) - - def test_node_objectstorage_with_properties(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.ObjectStorage - properties: - name: test - size: 1024 KB - maxsize: 1 MB - ''' - expectedprops = {'name': 'test', - 'X-Container-Meta': {'Quota-Bytes': 1000000}} - self._tosca_objectstore_test( - tpl_snippet, - expectedprops) - - def test_node_objectstorage_with_few_properties(self): - tpl_snippet = ''' - node_templates: - server: - type: tosca.nodes.ObjectStorage - properties: - name: test - size: 1024 B - ''' - expectedprops = {'name': 'test', - 'X-Container-Meta': {'Quota-Bytes': 1024}} - self._tosca_objectstore_test( - tpl_snippet, - expectedprops) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage.py deleted file mode 100644 index 482db3e..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage.py +++ /dev/null @@ -1,69 +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. - -import logging -from toscaparser.common.exception import InvalidPropertyValueError -from toscaparser.elements.scalarunit import ScalarUnit_Size -from toscaparser.functions import GetInput -from toscaparser.utils.gettextutils import _ -from translator.hot.syntax.hot_resource import HotResource - -log = logging.getLogger("tosca") - -# Name used to dynamically load appropriate map class. -TARGET_CLASS_NAME = 'ToscaBlockStorage' - - -class ToscaBlockStorage(HotResource): - '''Translate TOSCA node type tosca.nodes.BlockStorage.''' - - toscatype = 'tosca.nodes.BlockStorage' - - def __init__(self, nodetemplate): - super(ToscaBlockStorage, self).__init__(nodetemplate, - type='OS::Cinder::Volume') - pass - - def handle_properties(self): - tosca_props = {} - for prop in self.nodetemplate.get_properties_objects(): - if isinstance(prop.value, GetInput): - tosca_props[prop.name] = {'get_param': prop.value.input_name} - else: - if prop.name == "size": - size_value = (ScalarUnit_Size(prop.value). - get_num_from_scalar_unit('GiB')) - if size_value == 0: - # OpenStack Heat expects size in GB - raise InvalidPropertyValueError( - what=_('Cinder Volume Size unit should be in GBs')) - elif int(size_value) < size_value: - size_value = int(size_value) + 1 - log.warning(_("Cinder unit value should be in " - "multiples of GBs. so corrected " - " %(prop_val)s to %(size_value)s GB.") - % {'prop_val': prop.value, - 'size_value': size_value}) - tosca_props[prop.name] = int(size_value) - else: - tosca_props[prop.name] = prop.value - self.properties = tosca_props - - def get_hot_attribute(self, attribute, args): - attr = {} - # Convert from a TOSCA attribute for a nodetemplate to a HOT - # attribute for the matching resource. Unless there is additional - # runtime support, this should be a one to one mapping. - if attribute == 'volume_id': - attr['get_resource'] = args[0] - return attr diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage_attachment.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage_attachment.py deleted file mode 100644 index 715d5b3..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_block_storage_attachment.py +++ /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.functions import GetInput -from translator.hot.syntax.hot_resource import HotResource - -# Name used to dynamically load appropriate map class. -TARGET_CLASS_NAME = 'ToscaBlockStorageAttachment' - - -class ToscaBlockStorageAttachment(HotResource): - '''Translate TOSCA relationship AttachesTo for Compute and BlockStorage.''' - - toscatype = 'tosca.nodes.BlockStorageAttachment' - - def __init__(self, template, nodetemplates, instance_uuid, volume_id): - super(ToscaBlockStorageAttachment, - self).__init__(template, type='OS::Cinder::VolumeAttachment') - self.nodetemplates = nodetemplates - self.instance_uuid = {'get_resource': instance_uuid} - self.volume_id = {'get_resource': volume_id} - - def handle_properties(self): - tosca_props = {} - for prop in self.nodetemplate.get_properties_objects(): - if isinstance(prop.value, GetInput): - tosca_props[prop.name] = {'get_param': prop.value.input_name} - else: - tosca_props[prop.name] = prop.value - self.properties = tosca_props - # instance_uuid and volume_id for Cinder volume attachment - self.properties['instance_uuid'] = self.instance_uuid - self.properties['volume_id'] = self.volume_id - if 'location' in self.properties: - self.properties['mountpoint'] = self.properties.pop('location') - - def handle_life_cycle(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py deleted file mode 100755 index 137418d..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_compute.py +++ /dev/null @@ -1,274 +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. - -import json -import logging -import os -import requests - -from toscaparser.utils.validateutils import TOSCAVersionProperty -import translator.common.utils -from translator.hot.syntax.hot_resource import HotResource -log = logging.getLogger('tosca') - -# 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 -# describe artifacts. We will follow these projects to see if they can be -# leveraged for this TOSCA translation. -# For development purpose at this time, we temporarily hardcode a list of -# flavors and images here -FLAVORS = {'m1.xlarge': {'mem_size': 16384, 'disk_size': 160, 'num_cpus': 8}, - 'm1.large': {'mem_size': 8192, 'disk_size': 80, 'num_cpus': 4}, - 'm1.medium': {'mem_size': 4096, 'disk_size': 40, 'num_cpus': 2}, - 'm1.small': {'mem_size': 2048, 'disk_size': 20, 'num_cpus': 1}, - 'm1.tiny': {'mem_size': 512, 'disk_size': 1, 'num_cpus': 1}, - 'm1.micro': {'mem_size': 128, 'disk_size': 0, 'num_cpus': 1}, - 'm1.nano': {'mem_size': 64, 'disk_size': 0, 'num_cpus': 1}} - -IMAGES = {'ubuntu-software-config-os-init': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'Ubuntu', - 'version': '14.04'}, - 'ubuntu-12.04-software-config-os-init': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'Ubuntu', - 'version': '12.04'}, - 'fedora-amd64-heat-config': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'Fedora', - 'version': '18.0'}, - 'F18-x86_64-cfntools': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'Fedora', - 'version': '19'}, - 'Fedora-x86_64-20-20131211.1-sda': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'Fedora', - 'version': '20'}, - 'cirros-0.3.1-x86_64-uec': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'CirrOS', - 'version': '0.3.1'}, - 'cirros-0.3.2-x86_64-uec': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'CirrOS', - 'version': '0.3.2'}, - 'rhel-6.5-test-image': {'architecture': 'x86_64', - 'type': 'Linux', - 'distribution': 'RHEL', - 'version': '6.5'}} - - -class ToscaCompute(HotResource): - '''Translate TOSCA node type tosca.nodes.Compute.''' - - toscatype = 'tosca.nodes.Compute' - - def __init__(self, nodetemplate): - super(ToscaCompute, self).__init__(nodetemplate, - type='OS::Nova::Server') - # List with associated hot port resources with this server - self.assoc_port_resources = [] - pass - - def handle_properties(self): - self.properties = self.translate_compute_flavor_and_image( - 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' - - # To be reorganized later based on new development in Glance and Graffiti - def translate_compute_flavor_and_image(self, - host_capability, - os_capability): - hot_properties = {} - host_cap_props = {} - os_cap_props = {} - image = None - flavor = None - if host_capability: - for prop in host_capability.get_properties_objects(): - host_cap_props[prop.name] = prop.value - flavor = self._best_flavor(host_cap_props) - if os_capability: - for prop in os_capability.get_properties_objects(): - os_cap_props[prop.name] = prop.value - 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 - } - } - } - 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: - 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): - # Check whether user exported all required environment variables. - flavors = FLAVORS - if self._check_for_env_variables(): - resp = self._create_nova_flavor_dict() - if resp: - flavors = resp - - # start with all flavors - match_all = flavors.keys() - - # 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) - - # flavors that fit the mem size - mem = properties.get('mem_size') - if mem: - mem = translator.common.utils.MemoryUnit.convert_unit_size_to_num( - mem, 'MB') - match_cpu_mem = self._match_flavors(match_cpu, flavors, - 'mem_size', mem) - # flavors that fit the disk size - disk = properties.get('disk_size') - if disk: - disk = translator.common.utils.MemoryUnit.\ - convert_unit_size_to_num(disk, 'GB') - match_cpu_mem_disk = self._match_flavors(match_cpu_mem, flavors, - '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 - if len(match_cpu_mem_disk) > 1: - return self._least_flavor(match_cpu_mem_disk, flavors, 'mem_size') - elif len(match_cpu_mem_disk) == 1: - return match_cpu_mem_disk[0] - else: - return None - - def _best_image(self, properties): - match_all = IMAGES.keys() - architecture = properties.get('architecture') - 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') - match_distribution = self._match_images(match_type, IMAGES, - 'distribution', - distribution) - version = properties.get('version') - version = TOSCAVersionProperty(version).get_version() - match_version = self._match_images(match_distribution, IMAGES, - 'version', version) - - if len(match_version): - return list(match_version)[0] - - def _match_flavors(self, this_list, this_dict, attr, size): - '''Return from this list all flavors matching the attribute size.''' - if not size: - return list(this_list) - matching_flavors = [] - for flavor in this_list: - if isinstance(size, int): - if this_dict[flavor][attr] >= size: - matching_flavors.append(flavor) - return matching_flavors - - def _least_flavor(self, this_list, this_dict, attr): - '''Return from this list the flavor with the smallest attr.''' - least_flavor = this_list[0] - for flavor in this_list: - if this_dict[flavor][attr] < this_dict[least_flavor][attr]: - least_flavor = flavor - return least_flavor - - def _match_images(self, this_list, this_dict, attr, prop): - if not prop: - return this_list - matching_images = [] - for image in this_list: - if this_dict[image][attr].lower() == str(prop).lower(): - matching_images.append(image) - return matching_images - - def get_hot_attribute(self, attribute, args): - attr = {} - # Convert from a TOSCA attribute for a nodetemplate to a HOT - # attribute for the matching resource. Unless there is additional - # runtime support, this should be a one to one mapping. - - # 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. - if attribute == 'private_address' or \ - attribute == 'public_address': - attr['get_attr'] = [self.name, 'networks', 'private', 0] - - return attr diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_database.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_database.py deleted file mode 100755 index 26c9d4d..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_database.py +++ /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 = 'ToscaDatabase' - - -class ToscaDatabase(HotResource): - '''Translate TOSCA node type tosca.nodes.Database.''' - - toscatype = 'tosca.nodes.Database' - - def __init__(self, nodetemplate): - super(ToscaDatabase, self).__init__(nodetemplate) - pass - - def handle_properties(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_dbms.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_dbms.py deleted file mode 100755 index 38c31bd..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_dbms.py +++ /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 = 'ToscaDbms' - - -class ToscaDbms(HotResource): - '''Translate TOSCA node type tosca.nodes.DBMS.''' - - toscatype = 'tosca.nodes.DBMS' - - def __init__(self, nodetemplate): - super(ToscaDbms, self).__init__(nodetemplate) - pass - - def handle_properties(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_network.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_network.py deleted file mode 100644 index 909c1b7..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_network.py +++ /dev/null @@ -1,120 +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 InvalidPropertyValueError -from translator.hot.syntax.hot_resource import HotResource - -# Name used to dynamically load appropriate map class. -TARGET_CLASS_NAME = 'ToscaNetwork' - - -class ToscaNetwork(HotResource): - '''Translate TOSCA node type tosca.nodes.network.Network.''' - - toscatype = 'tosca.nodes.network.Network' - SUBNET_SUFFIX = '_subnet' - NETWORK_PROPS = ['network_name', 'network_id', 'segmentation_id'] - SUBNET_PROPS = ['ip_version', 'cidr', 'start_ip', 'end_ip', 'gateway_ip'] - - existing_resource_id = None - - def __init__(self, nodetemplate): - super(ToscaNetwork, self).__init__(nodetemplate, - type='OS::Neutron::Net') - pass - - def handle_properties(self): - tosca_props = self._get_tosca_props( - self.nodetemplate.get_properties_objects()) - - net_props = {} - for key, value in tosca_props.items(): - if key in self.NETWORK_PROPS: - if key == 'network_name': - # If CIDR is specified network_name should - # be used as the name for the new network. - if 'cidr' in tosca_props.keys(): - net_props['name'] = value - # If CIDR is not specified network_name will be used - # to lookup existing network. If network_id is specified - # together with network_name then network_id should be - # used to lookup the network instead - elif 'network_id' not in tosca_props.keys(): - self.hide_resource = True - self.existing_resource_id = value - break - elif key == 'network_id': - self.hide_resource = True - self.existing_resource_id = value - break - elif key == 'segmentation_id': - net_props['segmentation_id'] = \ - tosca_props['segmentation_id'] - # Hardcode to vxlan for now until we add the network type - # and physical network to the spec. - net_props['value_specs'] = {'provider:segmentation_id': - value, 'provider:network_type': - 'vxlan'} - self.properties = net_props - - def handle_expansion(self): - # If the network resource should not be output (they are hidden), - # there is no need to generate subnet resource - if self.hide_resource: - return - - tosca_props = self._get_tosca_props( - self.nodetemplate.get_properties_objects()) - - subnet_props = {} - - ip_pool_start = None - ip_pool_end = None - - for key, value in tosca_props.items(): - if key in self.SUBNET_PROPS: - if key == 'start_ip': - ip_pool_start = value - elif key == 'end_ip': - ip_pool_end = value - elif key == 'dhcp_enabled': - subnet_props['enable_dhcp'] = value - else: - subnet_props[key] = value - - if 'network_id' in tosca_props: - subnet_props['network'] = tosca_props['network_id'] - else: - subnet_props['network'] = '{ get_resource: %s }' % (self.name) - - # Handle allocation pools - # Do this only if both start_ip and end_ip are provided - # If one of them is missing throw an exception. - if ip_pool_start and ip_pool_end: - allocation_pool = {} - allocation_pool['start'] = ip_pool_start - allocation_pool['end'] = ip_pool_end - allocation_pools = [allocation_pool] - subnet_props['allocation_pools'] = allocation_pools - elif ip_pool_start: - raise InvalidPropertyValueError(what=_('start_ip')) - elif ip_pool_end: - raise InvalidPropertyValueError(what=_('end_ip')) - - subnet_resource_name = self.name + self.SUBNET_SUFFIX - - hot_resources = [HotResource(self.nodetemplate, - type='OS::Neutron::Subnet', - name=subnet_resource_name, - properties=subnet_props)] - return hot_resources diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_port.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_port.py deleted file mode 100644 index f5f0b25..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_network_port.py +++ /dev/null @@ -1,117 +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 = 'ToscaNetworkPort' - - -class ToscaNetworkPort(HotResource): - '''Translate TOSCA node type tosca.nodes.network.Port.''' - - toscatype = 'tosca.nodes.network.Port' - - def __init__(self, nodetemplate): - super(ToscaNetworkPort, self).__init__(nodetemplate, - type='OS::Neutron::Port') - # Default order - self.order = 0 - pass - - def _generate_networks_for_compute(self, port_resources): - '''Generate compute networks property list from the port resources.''' - networks = [] - for resource in port_resources: - networks.append({'port': '{ get_resource: %s }' % (resource.name)}) - return networks - - def _insert_sorted_resource(self, resources, resource): - '''Insert a resource in the list of resources and keep the order.''' - lo = 0 - hi = len(resources) - while lo < hi: - mid = (lo + hi) // 2 - if resource.order < resources[mid].order: - hi = mid - else: - lo = mid + 1 - resources.insert(lo, resource) - - def handle_properties(self): - tosca_props = self._get_tosca_props( - self.nodetemplate.get_properties_objects()) - port_props = {} - for key, value in tosca_props.items(): - if key == 'ip_address': - fixed_ip = [] - fixed_ip['ip_address'] = value - fixed_ip['subnet'] = '' - port_props['fixed_ips'] = [fixed_ip] - elif key == 'order': - self.order = value - # TODO(sdmonov): Need to implement the properties below - elif key == 'is_default': - pass - elif key == 'ip_range_start': - pass - elif key == 'ip_range_end': - pass - 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'] - - 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) - - # 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 - - self.properties = port_props diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_object_storage.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_object_storage.py deleted file mode 100644 index ed283b2..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_object_storage.py +++ /dev/null @@ -1,58 +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.scalarunit import ScalarUnit_Size -from translator.hot.syntax.hot_resource import HotResource - -# Name used to dynamically load appropriate map class. -TARGET_CLASS_NAME = 'ToscaObjectStorage' - - -class ToscaObjectStorage(HotResource): - '''Translate TOSCA node type tosca.nodes.ObjectStorage.''' - - toscatype = 'tosca.nodes.ObjectStorage' - - def __init__(self, nodetemplate): - super(ToscaObjectStorage, self).__init__(nodetemplate, - type='OS::Swift::Container') - pass - - def handle_properties(self): - tosca_props = self._get_tosca_props( - self.nodetemplate.get_properties_objects()) - objectstore_props = {} - container_quota = {} - skip_check = False - - for key, value in tosca_props.items(): - if key == "name": - objectstore_props["name"] = value - elif key == "size" or key == "maxsize": - # currently heat is not supporting dynamically increase - # the container quota-size. - # if both defined in tosca template, consider store_maxsize. - if skip_check: - continue - quota_size = None - if "maxsize" in tosca_props.keys(): - quota_size = tosca_props["maxsize"] - else: - quota_size = tosca_props["size"] - container_quota["Quota-Bytes"] = \ - ScalarUnit_Size(quota_size).get_num_from_scalar_unit() - objectstore_props["X-Container-Meta"] = container_quota - skip_check = True - - objectstore_props["X-Container-Read"] = '".r:*"' - self.properties = objectstore_props diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_software_component.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_software_component.py deleted file mode 100755 index 044de43..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_software_component.py +++ /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 = 'ToscaSoftwareComponent' - - -class ToscaSoftwareComponent(HotResource): - '''Translate TOSCA node type tosca.nodes.SoftwareComponent.''' - - toscatype = 'tosca.nodes.SoftwareComponent' - - def __init__(self, nodetemplate): - super(ToscaSoftwareComponent, self).__init__(nodetemplate) - pass - - def handle_properties(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_web_application.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_web_application.py deleted file mode 100755 index d0a9c5d..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_web_application.py +++ /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 = 'ToscaWebApplication' - - -class ToscaWebApplication(HotResource): - '''Translate TOSCA node type tosca.nodes.WebApplication.''' - - toscatype = 'tosca.nodes.WebApplication' - - def __init__(self, nodetemplate): - super(ToscaWebApplication, self).__init__(nodetemplate) - pass - - def handle_properties(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_webserver.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_webserver.py deleted file mode 100755 index 83bda80..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca/tosca_webserver.py +++ /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 = 'ToscaWebserver' - - -class ToscaWebserver(HotResource): - '''Translate TOSCA node type tosca.nodes.WebServer.''' - - toscatype = 'tosca.nodes.WebServer' - - def __init__(self, nodetemplate): - super(ToscaWebserver, self).__init__(nodetemplate) - pass - - def handle_properties(self): - pass diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca_translator.py b/tosca2heat/heat-translator-0.3.0/translator/hot/tosca_translator.py deleted file mode 100644 index 74da6ce..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/tosca_translator.py +++ /dev/null @@ -1,64 +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. - -import logging -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 - - -class TOSCATranslator(object): - '''Invokes translation methods.''' - - log = logging.getLogger('heat-translator') - - def __init__(self, tosca, parsed_params): - super(TOSCATranslator, self).__init__() - self.tosca = tosca - self.hot_template = HotTemplate() - self.parsed_params = parsed_params - self.node_translator = None - - def translate(self): - self._resolve_input() - self.hot_template.description = self.tosca.description - self.hot_template.parameters = self._translate_inputs() - self.node_translator = TranslateNodeTemplates(self.tosca, - self.hot_template) - self.hot_template.resources = self.node_translator.translate() - self.hot_template.outputs = self._translate_outputs() - return self.hot_template.output_to_yaml() - - def _translate_inputs(self): - translator = TranslateInputs(self.tosca.inputs, self.parsed_params) - return translator.translate() - - def _translate_outputs(self): - translator = TranslateOutputs(self.tosca.outputs, self.node_translator) - return translator.translate() - - # check all properties for all node and ensure they are resolved - # to actual value - def _resolve_input(self): - for n in self.tosca.nodetemplates: - for node_prop in n.get_properties_objects(): - if isinstance(node_prop.value, dict): - try: - self.parsed_params[node_prop.value['get_input']] - except Exception: - msg = (_('Must specify all input values in \ - TOSCA template, missing %s') % - node_prop.value['get_input']) - self.log.warning(msg) - raise ValueError(msg) diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py b/tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py deleted file mode 100644 index ea9f990..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py +++ /dev/null @@ -1,153 +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. - -import logging -from toscaparser.dataentity import DataEntity -from toscaparser.elements.scalarunit import ScalarUnit_Size -from toscaparser.utils.gettextutils import _ -from toscaparser.utils.validateutils import TOSCAVersionProperty -from translator.hot.syntax.hot_parameter import HotParameter - - -INPUT_CONSTRAINTS = (CONSTRAINTS, DESCRIPTION, LENGTH, RANGE, - MIN, MAX, ALLOWED_VALUES, ALLOWED_PATTERN) = \ - ('constraints', 'description', 'length', 'range', - 'min', 'max', 'allowed_values', 'allowed_pattern') - -TOSCA_CONSTRAINT_OPERATORS = (EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN, - LESS_OR_EQUAL, IN_RANGE, VALID_VALUES, LENGTH, - MIN_LENGTH, MAX_LENGTH, PATTERN) = \ - ('equal', 'greater_than', 'greater_or_equal', - 'less_than', 'less_or_equal', 'in_range', - 'valid_values', 'length', 'min_length', - 'max_length', 'pattern') - -TOSCA_TO_HOT_CONSTRAINTS_ATTRS = {'equal': 'allowed_values', - 'greater_than': 'range', - 'greater_or_equal': 'range', - 'less_than': 'range', - 'less_or_equal': 'range', - 'in_range': 'range', - 'valid_values': 'allowed_values', - 'length': 'length', - 'min_length': 'length', - 'max_length': 'length', - 'pattern': 'allowed_pattern'} - -TOSCA_TO_HOT_INPUT_TYPES = {'string': 'string', - 'integer': 'number', - 'float': 'number', - 'boolean': 'boolean', - 'timestamp': 'string', - 'scalar-unit.size': 'number', - 'version': 'string', - 'null': 'string', - 'PortDef': 'number'} - -log = logging.getLogger('heat-translator') - - -class TranslateInputs(object): - '''Translate TOSCA Inputs to Heat Parameters.''' - - def __init__(self, inputs, parsed_params): - self.inputs = inputs - self.parsed_params = parsed_params - - def translate(self): - return self._translate_inputs() - - def _translate_inputs(self): - hot_inputs = [] - hot_default = None - for input in self.inputs: - hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type] - - if input.name in self.parsed_params: - hot_default = DataEntity.validate_datatype( - input.type, self.parsed_params[input.name]) - elif input.default is not None: - 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 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. - # should add logic to support other types if needed. - input_value = hot_default - 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.')) - elif int(hot_default) < hot_default: - hot_default = int(hot_default) + 1 - log.warning(_("Cinder unit value should be in multiples" - " of GBs. So corrected %(input_value)s " - "to %(hot_default)s GB.") - % {'input_value': input_value, - 'hot_default': hot_default}) - if input.type == 'version': - hot_default = TOSCAVersionProperty(hot_default).get_version() - - hot_constraints = [] - if input.constraints: - for constraint in input.constraints: - constraint.validate(hot_default) - hc, hvalue = self._translate_constraints( - constraint.constraint_key, constraint.constraint_value) - hot_constraints.append({hc: hvalue}) - - hot_inputs.append(HotParameter(name=input.name, - type=hot_input_type, - description=input.description, - default=hot_default, - constraints=hot_constraints)) - return hot_inputs - - def _translate_constraints(self, name, value): - hot_constraint = TOSCA_TO_HOT_CONSTRAINTS_ATTRS[name] - - # Offset used to support less_than and greater_than. - # TODO(anyone): when parser supports float, verify this works - offset = 1 - - if name == EQUAL: - hot_value = [value] - elif name == GREATER_THAN: - hot_value = {"min": value + offset} - elif name == GREATER_OR_EQUAL: - hot_value = {"min": value} - elif name == LESS_THAN: - hot_value = {"max": value - offset} - elif name == LESS_OR_EQUAL: - hot_value = {"max": value} - elif name == IN_RANGE: - # value is list type here - min_value = min(value) - max_value = max(value) - hot_value = {"min": min_value, "max": max_value} - elif name == LENGTH: - hot_value = {"min": value, "max": value} - elif name == MIN_LENGTH: - hot_value = {"min": value} - elif name == MAX_LENGTH: - hot_value = {"max": value} - else: - hot_value = value - return hot_constraint, hot_value diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_node_templates.py b/tosca2heat/heat-translator-0.3.0/translator/hot/translate_node_templates.py deleted file mode 100644 index 152603d..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_node_templates.py +++ /dev/null @@ -1,408 +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. - -import importlib -import logging -import os -import six - -from toscaparser.functions import GetAttribute -from toscaparser.functions import GetInput -from toscaparser.functions import GetProperty -from toscaparser.relationship_template import RelationshipTemplate -from translator.common.exception import ToscaClassAttributeError -from translator.common.exception import ToscaClassImportError -from translator.common.exception import ToscaModImportError -from translator.conf.config import ConfigProvider as translatorConfig -from translator.hot.syntax.hot_resource import HotResource -from translator.hot.tosca.tosca_block_storage_attachment import ( - ToscaBlockStorageAttachment - ) - -########################### -# Module utility Functions -# for dynamic class loading -########################### - - -def _generate_type_map(): - '''Generate TOSCA translation types map. - - Load user defined classes from location path specified in conf file. - Base classes are located within the tosca directory. - - ''' - - # Base types directory - BASE_PATH = 'translator/hot/tosca' - - # Custom types directory defined in conf file - custom_path = translatorConfig.get_value('DEFAULT', - 'custom_types_location') - - # First need to load the parent module, for example 'contrib.hot', - # for all of the dynamically loaded classes. - classes = [] - _load_classes((BASE_PATH, custom_path), classes) - try: - types_map = {clazz.toscatype: clazz for clazz in classes} - except AttributeError as e: - raise ToscaClassAttributeError(message=e.message) - - return types_map - - -def _load_classes(locations, classes): - '''Dynamically load all the classes from the given locations.''' - - for cls_path in locations: - # Use the absolute path of the class path - abs_path = os.path.dirname(os.path.abspath(__file__)) - abs_path = abs_path.replace('translator/hot', cls_path) - - # Grab all the tosca type module files in the given path - mod_files = [f for f in os.listdir(abs_path) if f.endswith('.py') - and not f.startswith('__init__') - and f.startswith('tosca_')] - - # For each module, pick out the target translation class - for f in mod_files: - # NOTE: For some reason the existing code does not use the map to - # instantiate ToscaBlockStorageAttachment. Don't add it to the map - # here until the dependent code is fixed to use the map. - if f == 'tosca_block_storage_attachment.py': - continue - - mod_name = cls_path + '/' + f.strip('.py') - mod_name = mod_name.replace('/', '.') - try: - mod = importlib.import_module(mod_name) - target_name = getattr(mod, 'TARGET_CLASS_NAME') - clazz = getattr(mod, target_name) - classes.append(clazz) - except ImportError: - raise ToscaModImportError(mod_name=mod_name) - except AttributeError: - if target_name: - raise ToscaClassImportError(name=target_name, - mod_name=mod_name) - else: - # TARGET_CLASS_NAME is not defined in module. - # Re-raise the exception - raise - -################## -# Module constants -################## - -SECTIONS = (TYPE, PROPERTIES, REQUIREMENTS, INTERFACES, LIFECYCLE, INPUT) = \ - ('type', 'properties', 'requirements', - 'interfaces', 'lifecycle', 'input') - -# TODO(anyone): the following requirement names should not be hard-coded -# in the translator. Since they are basically arbitrary names, we have to get -# them from TOSCA type definitions. -# To be fixed with the blueprint: -# https://blueprints.launchpad.net/heat-translator/+spec/tosca-custom-types -REQUIRES = (CONTAINER, DEPENDENCY, DATABASE_ENDPOINT, CONNECTION, HOST) = \ - ('container', 'dependency', 'database_endpoint', - 'connection', 'host') - -INTERFACES_STATE = (CREATE, START, CONFIGURE, START, DELETE) = \ - ('create', 'stop', 'configure', 'start', 'delete') - - -TOSCA_TO_HOT_REQUIRES = {'container': 'server', 'host': 'server', - 'dependency': 'depends_on', "connects": 'depends_on'} - -TOSCA_TO_HOT_PROPERTIES = {'properties': 'input'} -log = logging.getLogger('heat-translator') - -TOSCA_TO_HOT_TYPE = _generate_type_map() - - -class TranslateNodeTemplates(object): - '''Translate TOSCA NodeTemplates to Heat Resources.''' - - def __init__(self, tosca, hot_template): - self.tosca = tosca - self.nodetemplates = self.tosca.nodetemplates - self.hot_template = hot_template - # list of all HOT resources generated - self.hot_resources = [] - # mapping between TOSCA nodetemplate and HOT resource - self.hot_lookup = {} - - def translate(self): - return self._translate_nodetemplates() - - def _recursive_handle_properties(self, resource): - '''Recursively handle the properties of the depends_on_nodes nodes.''' - # Use of hashtable (dict) here should be faster? - if resource in self.processed_resources: - return - self.processed_resources.append(resource) - for depend_on in resource.depends_on_nodes: - self._recursive_handle_properties(depend_on) - - resource.handle_properties() - - def _translate_nodetemplates(self): - - suffix = 0 - # Copy the TOSCA graph: nodetemplate - for node in self.nodetemplates: - hot_node = TOSCA_TO_HOT_TYPE[node.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": - volume_name = None - requirements = node.requirements - if requirements: - # Find the name of associated BlockStorage node - for requires in requirements: - for value in requires.values(): - if isinstance(value, dict): - for node_name in value.values(): - for n in self.nodetemplates: - if n.name == node_name: - volume_name = node_name - break - else: # unreachable code ! - for n in self.nodetemplates: - if n.name == node_name: - volume_name = node_name - break - - suffix = suffix + 1 - attachment_node = self._get_attachment_node(node, - suffix, - volume_name) - if attachment_node: - self.hot_resources.append(attachment_node) - - # Handle life cycle operations: this may expand each node - # into multiple HOT resources and may change their name - lifecycle_resources = [] - for resource in self.hot_resources: - expanded = resource.handle_life_cycle() - if expanded: - lifecycle_resources += expanded - self.hot_resources += lifecycle_resources - - # Handle configuration from ConnectsTo relationship in the TOSCA node: - # this will generate multiple HOT resources, set of 2 for each - # configuration - connectsto_resources = [] - for node in self.nodetemplates: - for requirement in node.requirements: - for endpoint, details in six.iteritems(requirement): - relation = None - if isinstance(details, dict): - target = details.get('node') - relation = details.get('relationship') - else: - target = details - if (target and relation and - not isinstance(relation, six.string_types)): - interfaces = relation.get('interfaces') - connectsto_resources += \ - self._create_connect_configs(node, - target, - interfaces) - self.hot_resources += connectsto_resources - - # Copy the initial dependencies based on the relationship in - # the TOSCA template - for node in self.nodetemplates: - for node_depend in node.related_nodes: - # if the source of dependency is a server and the - # relationship type is 'tosca.relationships.HostedOn', - # add dependency as properties.server - if node_depend.type == 'tosca.nodes.Compute' and \ - node.related[node_depend].type == \ - node.type_definition.HOSTEDON: - self.hot_lookup[node].properties['server'] = \ - {'get_resource': self.hot_lookup[node_depend].name} - # for all others, add dependency as depends_on - else: - self.hot_lookup[node].depends_on.append( - self.hot_lookup[node_depend].top_of_chain()) - - self.hot_lookup[node].depends_on_nodes.append( - self.hot_lookup[node_depend].top_of_chain()) - - # handle hosting relationship - for resource in self.hot_resources: - resource.handle_hosting() - - # handle built-in properties of HOT resources - # if a resource depends on other resources, - # their properties need to be handled first. - # Use recursion to handle the properties of the - # dependent nodes in correct order - self.processed_resources = [] - for resource in self.hot_resources: - self._recursive_handle_properties(resource) - - # handle resources that need to expand to more than one HOT resource - expansion_resources = [] - for resource in self.hot_resources: - expanded = resource.handle_expansion() - if expanded: - expansion_resources += expanded - self.hot_resources += expansion_resources - - # Resolve function calls: GetProperty, GetAttribute, GetInput - # at this point, all the HOT resources should have been created - # in the graph. - for resource in self.hot_resources: - # traverse the reference chain to get the actual value - 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() - - return self.hot_resources - - def _get_attachment_node(self, node, suffix, volume_name): - attach = False - ntpl = self.nodetemplates - for key, value in node.relationships.items(): - if key.is_derived_from('tosca.relationships.AttachesTo'): - if value.is_derived_from('tosca.nodes.BlockStorage'): - attach = True - if attach: - relationship_tpl = None - for req in node.requirements: - for key, val in req.items(): - attach = val - relship = val.get('relationship') - for rkey, rval in val.items(): - if relship and isinstance(relship, dict): - for rkey, rval in relship.items(): - if rkey == 'type': - relationship_tpl = val - attach = rval - elif rkey == 'template': - rel_tpl_list = \ - (self.tosca.topology_template. - _tpl_relationship_templates()) - relationship_tpl = rel_tpl_list[rval] - attach = rval - else: - continue - elif isinstance(relship, str): - attach = relship - relationship_tpl = val - relationship_templates = \ - self.tosca._tpl_relationship_templates() - if 'relationship' in relationship_tpl and \ - attach not in \ - self.tosca._tpl_relationship_types() and \ - attach in relationship_templates: - relationship_tpl['relationship'] = \ - relationship_templates[attach] - break - if relationship_tpl: - rval_new = attach + "_" + str(suffix) - att = RelationshipTemplate( - relationship_tpl, rval_new, - self.tosca._tpl_relationship_types()) - hot_node = ToscaBlockStorageAttachment(att, ntpl, - node.name, - volume_name - ) - return hot_node - - def find_hot_resource(self, name): - for resource in self.hot_resources: - if resource.name == name: - return resource - - def _find_tosca_node(self, tosca_name): - for node in self.nodetemplates: - if node.name == tosca_name: - return node - - def _find_hot_resource_for_tosca(self, tosca_name): - for node in self.nodetemplates: - if node.name == tosca_name: - return self.hot_lookup[node] - - def _create_connect_configs(self, source_node, target_name, - connect_interfaces): - connectsto_resources = [] - if connect_interfaces: - for iname, interface in six.iteritems(connect_interfaces): - connectsto_resources += \ - self._create_connect_config(source_node, target_name, - interface) - return connectsto_resources - - def _create_connect_config(self, source_node, target_name, - connect_interface): - connectsto_resources = [] - target_node = self._find_tosca_node(target_name) - # the configuration can occur on the source or the target - connect_config = connect_interface.get('pre_configure_target') - if connect_config is not None: - config_location = 'target' - else: - connect_config = connect_interface.get('pre_configure_source') - if connect_config is not None: - config_location = 'source' - else: - msg = _("Template error: " - "no configuration found for ConnectsTo " - "in {1}").format(self.nodetemplate.name) - log.warning(msg) - raise Exception(msg) - config_name = source_node.name + '_' + target_name + '_connect_config' - implement = connect_config.get('implementation') - if config_location == 'target': - hot_config = HotResource(target_node, - config_name, - 'OS::Heat::SoftwareConfig', - {'config': {'get_file': implement}}) - elif config_location == 'source': - hot_config = HotResource(source_node, - config_name, - 'OS::Heat::SoftwareConfig', - {'config': {'get_file': implement}}) - connectsto_resources.append(hot_config) - hot_target = self._find_hot_resource_for_tosca(target_name) - hot_source = self._find_hot_resource_for_tosca(source_node.name) - connectsto_resources.append(hot_config. - handle_connectsto(source_node, - target_node, - hot_source, - hot_target, - config_location, - connect_interface)) - return connectsto_resources diff --git a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_outputs.py b/tosca2heat/heat-translator-0.3.0/translator/hot/translate_outputs.py deleted file mode 100644 index d707722..0000000 --- a/tosca2heat/heat-translator-0.3.0/translator/hot/translate_outputs.py +++ /dev/null @@ -1,42 +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_output import HotOutput - - -class TranslateOutputs(object): - '''Translate TOSCA Outputs to Heat Outputs.''' - - def __init__(self, outputs, node_translator): - self.outputs = outputs - self.nodes = node_translator - - def translate(self): - return self._translate_outputs() - - def _translate_outputs(self): - hot_outputs = [] - for output in self.outputs: - if output.value.name == 'get_attribute': - get_parameters = output.value.args - hot_target = self.nodes.find_hot_resource(get_parameters[0]) - hot_value = hot_target.get_hot_attribute(get_parameters[1], - get_parameters) - hot_outputs.append(HotOutput(output.name, - hot_value, - output.description)) - else: - hot_outputs.append(HotOutput(output.name, - output.value, - output.description)) - return hot_outputs -- cgit 1.2.3-korg