def take_action(self, parsed_args): log.debug(_('Translating the template with input parameters' '(%s).'), parsed_args) output = None if parsed_args.parameter: parsed_params = parsed_args.parameter else: parsed_params = {} if parsed_args.template_type == "tosca": path = parsed_args.template_file a_file = os.path.isfile(path) a_url = UrlUtils.validate_url(path) if not a_file else False if a_file or a_url: validate = parsed_args.validate_only if validate and validate.lower() == "true": ToscaTemplate(path, parsed_params, a_file) else: tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() else: msg = _('Could not find template file.') log.error(msg) sys.stdout.write(msg) raise SystemExit if output: if parsed_args.output_file: with open(parsed_args.output_file, 'w+') as f: f.write(output) else: print(output)
def test_translate_single_storage(self): '''TOSCA template with single BlockStorage and Attachment.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/storage/" "tosca_blockstorage_with_attachment.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resouce = {'attachesto_1': {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_server', 'location': {'get_param': 'storage_location'}, 'volume_id': 'my_storage'}}} output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') translated_value = resources.get('attachesto_1') expected_value = expected_resouce.get('attachesto_1') self.assertEqual(translated_value, expected_value) outputs = output_dict['outputs'] self.assertIn('private_ip', outputs) self.assertEqual( 'Private IP address of the newly created compute instance.', outputs['private_ip']['description']) self.assertEqual({'get_attr': ['my_server', 'networks', 'private', 0]}, outputs['private_ip']['value']) self.assertIn('volume_id', outputs) self.assertEqual('The volume id of the block storage instance.', outputs['volume_id']['description']) self.assertEqual({'get_resource': 'my_storage'}, outputs['volume_id']['value'])
def test_translate_storage_notation1(self): '''TOSCA template with single BlockStorage and Attachment.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/storage/" "tosca_blockstorage_with_attachment_notation1.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_web_app_tier_1', 'location': '/default_location', 'volume_id': 'my_storage'}} expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_web_app_tier_2', 'location': '/some_other_data_location', 'volume_id': 'my_storage'}} output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') self.assertIn('myattachto_1', resources.keys()) self.assertIn('myattachto_2', resources.keys()) self.assertIn(expected_resource_1, resources.values()) self.assertIn(expected_resource_2, resources.values())
def compare_tosca_translation_with_hot(tosca_file, hot_file, params): """Verify tosca translation against the given hot specification. inputs: tosca_file: relative local path or URL to the tosca input file hot_file: relative path to expected hot output params: dictionary of parameter name value pairs Returns as a dictionary the difference between the HOT translation of the given tosca_file and the given hot_file. """ from toscaparser.tosca_template import ToscaTemplate from translator.hot.tosca_translator import TOSCATranslator tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), tosca_file) a_file = os.path.isfile(tosca_tpl) if not a_file: tosca_tpl = tosca_file expected_hot_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), hot_file) tosca = ToscaTemplate(tosca_tpl, params, a_file) translate = TOSCATranslator(tosca, params) output = translate.translate() output_dict = toscaparser.utils.yamlparser.simple_parse(output) expected_output_dict = YamlUtils.get_dict(expected_hot_tpl) return CompareUtils.diff_dicts(output_dict, expected_output_dict)
def compare_tosca_translation_with_hot(tosca_file, hot_file, params): '''Verify tosca translation against the given hot specification. inputs: tosca_file: relative local path or URL to the tosca input file hot_file: relative path to expected hot output params: dictionary of parameter name value pairs Returns as a dictionary the difference between the HOT translation of the given tosca_file and the given hot_file. ''' from toscaparser.tosca_template import ToscaTemplate from translator.hot.tosca_translator import TOSCATranslator tosca_tpl = os.path.normpath( os.path.join(os.path.dirname(os.path.abspath(__file__)), tosca_file)) a_file = os.path.isfile(tosca_tpl) if not a_file: tosca_tpl = tosca_file expected_hot_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), hot_file) tosca = ToscaTemplate(tosca_tpl, params, a_file) translate = TOSCATranslator(tosca, params) output = translate.translate() output_dict = toscaparser.utils.yamlparser.simple_parse(output) expected_output_dict = YamlUtils.get_dict(expected_hot_tpl) return CompareUtils.diff_dicts(output_dict, expected_output_dict)
def get_generatehotemplate(self, request, descriptor_id, descriptor_type): """ Generate hot template for a TOSCA descriptor It is based on the reverse engineering of translator/shell.py """ result = '' print "get_generatehotemplate" print "descriptor_id: " + descriptor_id print "descriptor_type: " + descriptor_type project = self.get_dataproject() print project['toscayaml'][descriptor_id] tosca = ToscaTemplate( None, {}, False, yaml_dict_tpl=project['toscayaml'][descriptor_id]) translator = TOSCATranslator(tosca, {}, False, csar_dir=None) #log.debug(_('Translating the tosca template.')) print 'Translating the tosca template.' print translator.translate() result = translator.translate() return result
def _translate(self, sourcetype, path, parsed_params, a_file): output = None if sourcetype == "tosca": tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() return output
def test_translate_output(self): tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../../toscalib/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://<IP>: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 = \ translator.toscalib.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)
def generate_hot_from_tosca(vnfd_dict): parsed_params = dev_attrs.pop('param_values', {}) toscautils.updateimports(vnfd_dict) try: tosca = ToscaTemplate(parsed_params=parsed_params, a_file=False, yaml_dict_tpl=vnfd_dict) except Exception as e: LOG.debug("tosca-parser error: %s", str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e)) monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) res_tpl = toscautils.get_resources_dict(tosca, STACK_FLAVOR_EXTRA) toscautils.post_process_template(tosca) try: translator = TOSCATranslator(tosca, parsed_params) heat_template_yaml = translator.translate() except Exception as e: LOG.debug("heat-translator error: %s", str(e)) raise vnfm.HeatTranslatorFailed(error_msg_details=str(e)) heat_template_yaml = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, res_tpl, unsupported_res_prop) return heat_template_yaml, monitoring_dict
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) if parsed_args.parameter: parsed_params = parsed_args.parameter else: parsed_params = {} if parsed_args.template_type == "tosca": path = parsed_args.template_file a_file = os.path.isfile(path) a_url = UrlUtils.validate_url(path) if not a_file else False if a_file or a_url: tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() else: sys.stdout.write('Could not find template file.') raise SystemExit if parsed_args.output_file: with open(parsed_args.output_file, 'w+') as f: f.write(output) else: print(output)
def test_translate_multi_storage(self): '''TOSCA template with multiple BlockStorage and Attachment.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/storage/" "tosca_multiple_blockstorage_with_attachment.yaml") tosca = ToscaTemplate(tosca_tpl) translated_volume_attachment = [] translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_server', 'location': {'get_param': 'storage_location'}, 'volume_id': 'my_storage'}} expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_server2', 'location': {'get_param': 'storage_location'}, 'volume_id': 'my_storage2'}} output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') translated_volume_attachment.append(resources.get('attachesto_1')) translated_volume_attachment.append(resources.get('attachesto_2')) self.assertIn(expected_resource_1, translated_volume_attachment) self.assertIn(expected_resource_2, translated_volume_attachment)
def test_translate_server_existing_network(self): '''TOSCA template with 1 server attached to existing network.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/network/" "tosca_server_on_existing_network.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resource_1 = {'type': 'OS::Neutron::Port', 'properties': {'network': {'get_param': 'network_name'} }} expected_resource_2 = [{'port': {'get_resource': 'my_port'}}] output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') self.assertItemsEqual(resources.keys(), ['my_server', 'my_port']) self.assertEqual(resources.get('my_port'), expected_resource_1) self.assertIn('properties', resources.get('my_server')) self.assertIn('networks', resources.get('my_server').get('properties')) translated_resource = resources.get('my_server').\ get('properties').get('networks') self.assertEqual(translated_resource, expected_resource_2)
def _translate(self, sourcetype, path, parsed_params, a_file): output = None if sourcetype == "tosca": log.debug(_('Loading the tosca template.')) tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params, self.deploy) log.debug(_('Translating the tosca template.')) output = translator.translate() return output
def test_translate_three_networks_single_server(self): '''TOSCA template with three Networks and single Compute.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/network/" "tosca_one_server_three_networks.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') for net_num in range(1, 4): net_name = 'my_network%d' % (net_num) subnet_name = '%s_subnet' % (net_name) port_name = 'my_port%d' % (net_num) expected_resource_net = {'type': 'OS::Neutron::Net', 'properties': {'name': 'net%d' % (net_num) }} expected_resource_subnet = {'type': 'OS::Neutron::Subnet', 'properties': {'cidr': '192.168.%d.0/24' % (net_num), 'ip_version': 4, 'network': {'get_resource': net_name} }} expected_resource_port = {'type': 'OS::Neutron::Port', 'depends_on': [net_name], 'properties': {'network': {'get_resource': net_name} }} self.assertIn(net_name, resources.keys()) self.assertIn(subnet_name, resources.keys()) self.assertIn(port_name, resources.keys()) self.assertEqual(resources.get(net_name), expected_resource_net) self.assertEqual(resources.get(subnet_name), expected_resource_subnet) self.assertEqual(resources.get(port_name), expected_resource_port) self.assertIn('properties', resources.get('my_server')) self.assertIn('networks', resources.get('my_server').get('properties')) translated_resource = resources.get('my_server').\ get('properties').get('networks') expected_srv_networks = [{'port': {'get_resource': 'my_port1'}}, {'port': {'get_resource': 'my_port2'}}, {'port': {'get_resource': 'my_port3'}}] self.assertEqual(translated_resource, expected_srv_networks)
def generate_heat_template(self, tosca_template_str): if tosca_template_str is None: raise ValueError('Must provide tosca_template_str parameter') tosca = self.tosca_parser_service.parse_tosca_str(tosca_template_str) heat_translator = TOSCATranslator(tosca, {}) # heat translator returns translated heat in a dict translation_dict_key = 'main_hot' heat_translations = heat_translator.translate_to_yaml_files_dict( translation_dict_key) heat_result = heat_translations[translation_dict_key] return heat_result
def test_post_process_heat_template(self): tosca1 = ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=self.vnfd_dict) toscautils.post_process_template(tosca1) translator = TOSCATranslator(tosca1, {}) heat_template_yaml = translator.translate() expected_heat_tpl = _get_template("hot_tosca_openwrt.yaml") mgmt_ports = toscautils.get_mgmt_ports(self.tosca) heat_tpl = toscautils.post_process_heat_template(heat_template_yaml, mgmt_ports, {}, {}) heatdict = yaml.load(heat_tpl) expecteddict = yaml.load(expected_heat_tpl) self.assertEqual(heatdict, expecteddict)
def test_translate_single_network_single_server(self): '''TOSCA template with single Network and single Compute.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/network/" "tosca_one_server_one_network.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resource_1 = {'type': 'OS::Neutron::Net', 'properties': {'name': {'get_param': 'network_name'} }} expected_resource_2 = {'type': 'OS::Neutron::Subnet', 'properties': {'cidr': '192.168.0.0/24', 'ip_version': 4, 'allocation_pools': [{'start': '192.168.0.50', 'end': '192.168.0.200'}], 'gateway_ip': '192.168.0.1', 'network': {'get_resource': 'my_network'} }} expected_resource_3 = {'type': 'OS::Neutron::Port', 'depends_on': ['my_network'], 'properties': {'network': {'get_resource': 'my_network'} }} expected_resource_4 = [{'port': {'get_resource': 'my_port'}}] output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') self.assertIn('my_network', resources.keys()) self.assertIn('my_network_subnet', resources.keys()) self.assertIn('my_port', resources.keys()) self.assertIn('my_server', resources.keys()) self.assertEqual(resources.get('my_network'), expected_resource_1) self.assertEqual(resources.get('my_network_subnet'), expected_resource_2) self.assertEqual(resources.get('my_port'), expected_resource_3) self.assertIn('properties', resources.get('my_server')) self.assertIn('networks', resources.get('my_server').get('properties')) translated_resource = resources.get('my_server').\ get('properties').get('networks') self.assertEqual(translated_resource, expected_resource_4)
def generate_heat_template(self, tosca_template_str, template_path=None): if tosca_template_str is None: raise ValueError('Must provide tosca_template_str parameter') tosca = self.tosca_parser_service.parse_tosca_str( tosca_template_str, template_path=template_path) heat_translator = TOSCATranslator(tosca, {}) # heat translator returns translated heat in a dict translation_dict_key = 'main_hot' heat_translations = heat_translator.translate_to_yaml_files_dict( translation_dict_key) heat_result = heat_translations[translation_dict_key] logger.debug('Translated Heat: {0}'.format(heat_result)) return heat_result
def compare_tosca_translation_with_hot(tosca_file, hot_files, params, nested_resources=False): '''Verify tosca translation against the given hot specification. inputs: tosca_file: relative local path or URL to the tosca input file hot_file: relative path to expected hot output params: dictionary of parameter name value pairs Returns as a dictionary the difference between the HOT translation of the given tosca_file and the given hot_file. ''' from toscaparser.tosca_template import ToscaTemplate from translator.hot.tosca_translator import TOSCATranslator tosca_tpl = os.path.normpath(os.path.join( os.path.dirname(os.path.abspath(__file__)), tosca_file)) a_file = os.path.isfile(tosca_tpl) if not a_file: tosca_tpl = tosca_file expected_hot_templates = [] for hot_file in hot_files: expected_hot_templates.append(os.path.join( os.path.dirname(os.path.abspath(__file__)), hot_file)) tosca = ToscaTemplate(tosca_tpl, params, a_file) translate = TOSCATranslator(tosca, params) basename = os.path.basename(hot_files[0]) output_hot_templates = translate.translate_to_yaml_files_dict(basename) if nested_resources: basename = os.path.basename(hot_files[0]) output_hot_templates =\ translate.translate_to_yaml_files_dict(basename, True) output_dict = {} for output_hot_template_name in output_hot_templates: output_dict[output_hot_template_name] = \ toscaparser.utils.yamlparser.simple_parse( output_hot_templates[output_hot_template_name]) expected_output_dict = {} for expected_hot_template in expected_hot_templates: expected_output_dict[os.path.basename(expected_hot_template)] = \ YamlUtils.get_dict(expected_hot_template) return CompareUtils.diff_dicts(expected_output_dict, output_dict)
def test_post_process_heat_template(self): tosca1 = ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=self.vnfd_dict) toscautils.post_process_template(tosca1) translator = TOSCATranslator(tosca1, {}) heat_template_yaml = translator.translate() expected_heat_tpl = _get_template('hot_tosca_openwrt.yaml') mgmt_ports = toscautils.get_mgmt_ports(self.tosca) heat_tpl = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, {}, {}) heatdict = yaml.load(heat_tpl) expecteddict = yaml.load(expected_heat_tpl) self.assertEqual(expecteddict, heatdict)
def _translate(self, sourcetype, path, parsed_params, a_file, deploy): output = None if sourcetype == "tosca": log.debug(_('Loading the tosca template.')) tosca = ToscaTemplate(path, parsed_params, a_file) csar_dir = None if deploy and zipfile.is_zipfile(path): # set CSAR directory to the root of TOSCA-Metadata csar_decompress = utils.decompress(path) csar_dir = os.path.join(csar_decompress, self.TOSCA_CSAR_META_DIR) msg = _("'%(csar)s' is the location of decompressed " "CSAR file.") % {'csar': csar_dir} log.info(msg) translator = TOSCATranslator(tosca, parsed_params, deploy, csar_dir=csar_dir) log.debug(_('Translating the tosca template.')) output = translator.translate() return output
def take_action(self, parsed_args): log.debug(_('Translating the template with input parameters' '(%s).'), parsed_args) output = None session = self.app.cloud.get_session() flavors.SESSION = session images.SESSION = session if parsed_args.parameter: parsed_params = parsed_args.parameter else: parsed_params = {} if parsed_args.template_type == "tosca": path = parsed_args.template_file a_file = os.path.isfile(path) a_url = UrlUtils.validate_url(path) if not a_file else False if a_file or a_url: validate = parsed_args.validate_only if validate and validate.lower() == "true": ToscaTemplate(path, parsed_params, a_file) msg = (_('The input "%(path)s" successfully passed ' 'validation.') % { 'path': path }) print(msg) else: tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() else: msg = _('Could not find template file.\n') log.error(msg) sys.stdout.write(msg) raise SystemExit if output: if parsed_args.output_file: with open(parsed_args.output_file, 'w+') as f: f.write(output) else: print(output)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) if not os.path.isfile(parsed_args.template_file): sys.stdout.write('Could not find template file.') raise SystemExit # TODO(stevemar): parsed_params doesn't default nicely parsed_params = {} if parsed_args.template_type == "tosca": tosca = ToscaTemplate(parsed_args.template_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() if parsed_args.output_file: with open(parsed_args.output_file, 'w+') as f: f.write(output) else: print(output)
def test_translate_output_order(self): tosca_yaml_file = "data/tosca_single_server.yaml" tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), tosca_yaml_file) parsed_params = {'cpus': 2} tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, parsed_params) hot_translated_output = translate.translate() #load expected hot yaml file hot_yaml_file = "data/hot_output/hot_single_server.yaml" hot_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), hot_yaml_file) with open(hot_tpl) as f: hot_expected_output = f.read() #compare generated and expected hot templates status = CompareUtils.compare_hot_yamls(hot_translated_output, hot_expected_output) self.assertEqual(status, True)
def take_action(self, parsed_args): LOG.debug(_('Translating the template with input parameters' '(%s).'), parsed_args) output = None session = self.app.cloud.get_session() flavors.SESSION = session images.SESSION = session if parsed_args.parameter: parsed_params = parsed_args.parameter else: parsed_params = {} if parsed_args.template_type == "tosca": path = parsed_args.template_file a_file = os.path.isfile(path) a_url = UrlUtils.validate_url(path) if not a_file else False if a_file or a_url: validate = parsed_args.validate_only if validate and validate.lower() == "true": ToscaTemplate(path, parsed_params, a_file) msg = (_('The input "%(path)s" successfully passed ' 'validation.') % {'path': path}) print(msg) else: tosca = ToscaTemplate(path, parsed_params, a_file) translator = TOSCATranslator(tosca, parsed_params) output = translator.translate() else: msg = _('Could not find template file.\n') LOG.error(msg) sys.stdout.write(msg) raise SystemExit if output: if parsed_args.output_file: with open(parsed_args.output_file, 'w+') as f: f.write(output) else: print(output)
def test_translate_unsupported_tosca_type(self): tosca_file = '../tests/data/test_tosca_unsupported_type.yaml' tosca_tpl = os.path.normpath(os.path.join( os.path.dirname(os.path.abspath(__file__)), tosca_file)) params = {} expected_msg = _('Type "tosca.nodes.LoadBalancer" is valid TOSCA ' 'type but translation support is not yet available.') tosca = ToscaTemplate(tosca_tpl, params, True) err = self.assertRaises(UnsupportedTypeError, TOSCATranslator(tosca, params) .translate) self.assertEqual(expected_msg, err.__str__())
def test_translate_output_order(self): tosca_yaml_file = "data/tosca_single_server.yaml" tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), tosca_yaml_file) parsed_params = {'cpus': 2} tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, parsed_params) hot_translated_output = translate.translate() #load expected hot yaml file hot_yaml_file = "data/hot_output/hot_single_server.yaml" hot_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), hot_yaml_file) with open(hot_tpl) as f: hot_expected_output = f.read() #compare generated and expected hot templates status = CompareUtils.compare_hot_yamls(hot_translated_output, hot_expected_output) self.assertEqual(status, True)
def test_single_template_objectstore(self): tosca_yaml_file = "../toscalib/tests/data/storage/" + \ "tosca_single_object_store.yaml" tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), tosca_yaml_file) parsed_params = {'objectstore_name': 'test_obj_store'} tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, parsed_params) hot_translated_output = translate.translate() #load expected hot yaml file hot_yaml_file = "../toscalib/tests/data/hot_output/" + \ "hot_single_object_store.yaml" hot_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)), hot_yaml_file) with open(hot_tpl) as f: hot_expected_output = f.read() #compare generated and expected hot templates status = CompareUtils.compare_hot_yamls(hot_translated_output, hot_expected_output) self.assertEqual(status, True)
def generate_hot_from_tosca(vnfd_dict): parsed_params = {} if ('param_values' in dev_attrs and dev_attrs['param_values'] != ""): try: parsed_params = yaml.load(dev_attrs['param_values']) except Exception as e: LOG.debug("Params not Well Formed: %s", str(e)) raise vnfm.ParamYAMLNotWellFormed( error_msg_details=str(e)) toscautils.updateimports(vnfd_dict) try: tosca = ToscaTemplate(parsed_params=parsed_params, a_file=False, yaml_dict_tpl=vnfd_dict) except Exception as e: LOG.debug("tosca-parser error: %s", str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e)) monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) res_tpl = toscautils.get_resources_dict(tosca, STACK_FLAVOR_EXTRA) toscautils.post_process_template(tosca) try: translator = TOSCATranslator(tosca, parsed_params) heat_template_yaml = translator.translate() except Exception as e: LOG.debug("heat-translator error: %s", str(e)) raise vnfm.HeatTranslatorFailed(error_msg_details=str(e)) heat_template_yaml = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, res_tpl, unsupported_res_prop) return heat_template_yaml, monitoring_dict
def test_single_template_objectstore(self): tosca_yaml_file = "../toscalib/tests/data/storage/" + \ "tosca_single_object_store.yaml" tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), tosca_yaml_file) parsed_params = {'objectstore_name': 'test_obj_store'} tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, parsed_params) hot_translated_output = translate.translate() #load expected hot yaml file hot_yaml_file = "../toscalib/tests/data/hot_output/" + \ "hot_single_object_store.yaml" hot_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), hot_yaml_file) with open(hot_tpl) as f: hot_expected_output = f.read() #compare generated and expected hot templates status = CompareUtils.compare_hot_yamls(hot_translated_output, hot_expected_output) self.assertEqual(status, True)
def test_translate_storage_notation2(self): '''TOSCA template with single BlockStorage and Attachment.''' tosca_tpl = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../toscalib/tests/data/storage/" "tosca_blockstorage_with_attachment_notation2.yaml") tosca = ToscaTemplate(tosca_tpl) translate = TOSCATranslator(tosca, self.parsed_params) output = translate.translate() expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_web_app_tier_1', 'location': '/my_data_location', 'volume_id': 'my_storage'}} expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment', 'properties': {'instance_uuid': 'my_web_app_tier_2', 'location': '/some_other_data_location', 'volume_id': 'my_storage'}} output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') # Resource name suffix depends on nodetemplates order in dict, which is # not certain. So we have two possibilities of resources name. if resources.get('storage_attachesto_1_1'): self.assertIn('storage_attachesto_1_1', resources.keys()) self.assertIn('storage_attachesto_2_2', resources.keys()) else: self.assertIn('storage_attachesto_1_2', resources.keys()) self.assertIn('storage_attachesto_2_1', resources.keys()) self.assertIn(expected_resource_1, resources.values()) self.assertIn(expected_resource_2, resources.values())
def create(self, plugin, context, device, auth_attr): LOG.debug(_('device %s'), device) attributes = device['device_template']['attributes'].copy() vnfd_yaml = attributes.pop('vnfd', None) fields = dict((key, attributes.pop(key)) for key in ('stack_name', 'template_url', 'template') if key in attributes) for key in ('files', 'parameters'): if key in attributes: fields[key] = jsonutils.loads(attributes.pop(key)) # overwrite parameters with given dev_attrs for device creation dev_attrs = device['attributes'].copy() fields.update(dict((key, dev_attrs.pop(key)) for key in ('stack_name', 'template_url', 'template') if key in dev_attrs)) for key in ('files', 'parameters'): if key in dev_attrs: fields.setdefault(key, {}).update( jsonutils.loads(dev_attrs.pop(key))) region_name = device.get('placement_attr', {}).get('region_name', None) heatclient_ = HeatClient(auth_attr, region_name) unsupported_res_prop = self.fetch_unsupported_resource_prop( heatclient_) LOG.debug('vnfd_yaml %s', vnfd_yaml) if vnfd_yaml is not None: vnfd_dict = yamlparser.simple_ordered_parse(vnfd_yaml) LOG.debug('vnfd_dict %s', vnfd_dict) monitoring_dict = {'vdus': {}} if 'tosca_definitions_version' in vnfd_dict: parsed_params = dev_attrs.pop('param_values', {}) toscautils.updateimports(vnfd_dict) try: tosca = ToscaTemplate(parsed_params=parsed_params, a_file=False, yaml_dict_tpl=vnfd_dict) except Exception as e: LOG.debug("tosca-parser error: %s", str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e)) monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) res_tpl = toscautils.get_resources_dict(tosca, STACK_FLAVOR_EXTRA) toscautils.post_process_template(tosca) try: translator = TOSCATranslator(tosca, parsed_params) heat_template_yaml = translator.translate() except Exception as e: LOG.debug("heat-translator error: %s", str(e)) raise vnfm.HeatTranslatorFailed(error_msg_details=str(e)) heat_template_yaml = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, res_tpl, unsupported_res_prop) else: assert 'template' not in fields assert 'template_url' not in fields template_dict = yaml.load(HEAT_TEMPLATE_BASE) outputs_dict = {} template_dict['outputs'] = outputs_dict if 'get_input' in vnfd_yaml: self._process_parameterized_input(dev_attrs, vnfd_dict) KEY_LIST = (('description', 'description'), ) for (key, vnfd_key) in KEY_LIST: if vnfd_key in vnfd_dict: template_dict[key] = vnfd_dict[vnfd_key] for vdu_id, vdu_dict in vnfd_dict.get('vdus', {}).items(): template_dict.setdefault('resources', {})[vdu_id] = { "type": "OS::Nova::Server" } resource_dict = template_dict['resources'][vdu_id] KEY_LIST = (('image', 'vm_image'), ('flavor', 'instance_type')) resource_dict['properties'] = {} properties = resource_dict['properties'] for (key, vdu_key) in KEY_LIST: properties[key] = vdu_dict[vdu_key] if 'network_interfaces' in vdu_dict: self._process_vdu_network_interfaces(vdu_id, vdu_dict, properties, template_dict, unsupported_res_prop) if ('user_data' in vdu_dict and 'user_data_format' in vdu_dict): properties['user_data_format'] = vdu_dict[ 'user_data_format'] properties['user_data'] = vdu_dict['user_data'] elif ('user_data' in vdu_dict or 'user_data_format' in vdu_dict): raise vnfm.UserDataFormatNotFound() if 'placement_policy' in vdu_dict: if 'availability_zone' in vdu_dict['placement_policy']: properties['availability_zone'] = vdu_dict[ 'placement_policy']['availability_zone'] if 'config' in vdu_dict: properties['config_drive'] = True metadata = properties.setdefault('metadata', {}) metadata.update(vdu_dict['config']) for key, value in metadata.items(): metadata[key] = value[:255] monitoring_policy = vdu_dict.get('monitoring_policy', 'noop') failure_policy = vdu_dict.get('failure_policy', 'noop') # Convert the old monitoring specification to the new # network. This should be removed after Mitaka if (monitoring_policy == 'ping' and failure_policy == 'respawn'): vdu_dict['monitoring_policy'] = { 'ping': {'actions': {'failure': 'respawn'}}} vdu_dict.pop('failure_policy') if monitoring_policy != 'noop': monitoring_dict['vdus'][vdu_id] = \ vdu_dict['monitoring_policy'] # to pass necessary parameters to plugin upwards. for key in ('service_type',): if key in vdu_dict: device.setdefault( 'attributes', {})[vdu_id] = jsonutils.dumps( {key: vdu_dict[key]}) heat_template_yaml = yaml.dump(template_dict) fields['template'] = heat_template_yaml if not device['attributes'].get('heat_template'): device['attributes']['heat_template'] = \ heat_template_yaml if monitoring_dict.keys(): device['attributes']['monitoring_policy'] = \ jsonutils.dumps(monitoring_dict) if 'stack_name' not in fields: name = (__name__ + '_' + self.__class__.__name__ + '-' + device['id']) if device['attributes'].get('failure_count'): name += ('-%s') % str(device['attributes']['failure_count']) fields['stack_name'] = name # service context is ignored LOG.debug(_('service_context: %s'), device.get('service_context', [])) LOG.debug(_('fields: %s'), fields) LOG.debug(_('template: %s'), fields['template']) stack = heatclient_.create(fields) return stack['stack']['id']
def translate(): try: status_msg = None hot_output_string = None temp_dir = None full_filename = None params = '' # TODO: look at moving to a decorator trace(REQUEST_SEPARATOR) trace("request.method: " + request.method) trace("request.headers['Content-Type']:" + request.headers[HTTP_REQUEST_KEY_CONTENT_TYPE]) # debug the request object # debug.dump(request.__dict__, 1, "Request") if request.method == 'POST': # Retrieve reference to the file to transcode fileinfo = request.files[FLASK_KEY_REQUEST_FILE] # debug.dump(fileinfo.__dict__, 1, "File Info") # create request-unique subdirectory to store YAML template / CSAR temp_dir = create_dir(app.config[FLASK_KEY_UPLOAD_FOLDER]) full_filename = save_tosca_file(fileinfo, temp_dir) if full_filename and is_tosca_filetype(full_filename): # TODO: See if we can return a ZIP with HOT and artifacts # IF CSAR package unzip it for processing # if(is_csar(full_filename)): # trace("Unzipping TOSCA CSAR archive file...") # csar.unzip_csar(request, full_filename, temp_dir) # else: # trace("Standalone TOSCA template file detected...") # TODO: "sniff" for TOSCA header in template file (for # standalone YAML) or the "entry-defintion" template # identified in tbe manifest of the CSAR # retrieve and validate form data form = request.form # debug.dump_form(request, 1): # Get --parameters from FORM data trace("retrieving parameters...") if 'parameters' in form: params = form['parameters'] # trace("request.form['parameters']: [" + params + "]") params = parse_parameters(params) try: # Parse the TOSCA template trace("Parsing TOSCA template... [" + full_filename + "]") tosca_template = ToscaTemplate(full_filename, params) # Translate the TOSCA template/package to HOT trace("Translating to Heat template...") translator = TOSCATranslator(tosca_template, params) hot_output_string = translator.translate() except Exception, e: raise e else: # TODO: Show error message to indicate valid file types status_msg = "Invalid file ot filetype: file type not saved" # Optionally, save translated output if not PRODUCTION and OUTPUT_TO_FILE: trace("Saving translated output...") save_translated_file(fileinfo, "hot", "outputs", hot_output_string) # Add HOT output to the response and set its content type # to text/plain to avoid it being intpreted as HTML trace("Returning Heat template...") debug.dumpif(DEBUG, hot_output_string, 0, "HOT") response = app.make_response(hot_output_string) response.headers[HTTP_REQUEST_KEY_CONTENT_TYPE] = \ RESPONSE_CONTENT_TYPE return response else:
def test_translate_nodejs_mongodb(self): translate = TOSCATranslator(self.tosca, self.parsed_params) output = translate.translate() expected_resource = {'mongo_dbms_create_config': {'properties': {'config': {'get_file': 'mongodb/create.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'mongo_dbms_configure_config': {'properties': {'config': {'get_file': 'mongodb/config.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'mongo_dbms_start_config': {'properties': {'config': {'get_file': 'mongodb/start.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'nodejs_create_config': {'properties': {'config': {'get_file': 'nodejs/create.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'nodejs_configure_config': {'properties': {'config': {'get_file': 'nodejs/config.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'nodejs_start_config': {'properties': {'config': {'get_file': 'nodejs/start.sh'}, 'group': 'script'}, 'type': 'OS::Heat::SoftwareConfig'}, 'mongo_dbms_create_deploy': {'properties': {'config': {'get_resource': 'mongo_dbms_create_config'}, 'server': {'get_resource': 'mongo_server'}}, 'type': 'OS::Heat::SoftwareDeployment'}, 'mongo_dbms_configure_deploy': {'type': 'OS::Heat::SoftwareDeployment', 'depends_on': ['mongo_dbms_create_deploy'], 'properties': {'config': {'get_resource': 'mongo_dbms_configure_config'}, 'input_values': {'mongodb_ip': {'get_attr': ['mongo_server', 'networks', 'private', 0]}}, 'server': {'get_resource': 'mongo_server'}}}, 'mongo_dbms_start_deploy': {'type': 'OS::Heat::SoftwareDeployment', 'depends_on': ['mongo_dbms_configure_deploy'], 'properties': {'config': {'get_resource': 'mongo_dbms_start_config'}, 'server': {'get_resource': 'mongo_server'}}}, 'nodejs_create_deploy': {'properties': {'config': {'get_resource': 'nodejs_create_config'}, 'server': {'get_resource': 'app_server'}}, 'type': 'OS::Heat::SoftwareDeployment'}, 'nodejs_configure_deploy': {'depends_on': ['nodejs_create_deploy'], 'properties': {'config': {'get_resource': 'nodejs_configure_config'}, 'input_values': {'github_url': 'https://github.com/sample.git', 'mongodb_ip': {'get_attr': ['mongo_server', 'networks', 'private', 0]}}, 'server': {'get_resource': 'app_server'}}, 'type': 'OS::Heat::SoftwareDeployment'}, 'nodejs_start_deploy': {'depends_on': ['nodejs_configure_deploy'], 'properties': {'config': {'get_resource': 'nodejs_start_config'}, 'server': {'get_resource': 'app_server'}}, 'type': 'OS::Heat::SoftwareDeployment'}, 'app_server': {'properties': {'flavor': 'm1.medium', 'image': 'ubuntu-software-config-os-init', 'key_name': 'userkey', 'user_data_format': 'SOFTWARE_CONFIG'}, 'type': 'OS::Nova::Server'}, 'mongo_server': {'properties': {'flavor': 'm1.medium', 'image': 'ubuntu-software-config-os-init', 'key_name': 'userkey', 'user_data_format': 'SOFTWARE_CONFIG'}, 'type': 'OS::Nova::Server'}} output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') for resource_name in resources: translated_value = resources.get(resource_name) expected_value = expected_resource.get(resource_name) self.assertEqual(translated_value, expected_value)
def create(self, plugin, context, device, auth_attr): LOG.debug(_('device %s'), device) attributes = device['device_template']['attributes'].copy() vnfd_yaml = attributes.pop('vnfd', None) fields = dict((key, attributes.pop(key)) for key in ('stack_name', 'template_url', 'template') if key in attributes) for key in ('files', 'parameters'): if key in attributes: fields[key] = jsonutils.loads(attributes.pop(key)) # overwrite parameters with given dev_attrs for device creation dev_attrs = device['attributes'].copy() fields.update( dict((key, dev_attrs.pop(key)) for key in ('stack_name', 'template_url', 'template') if key in dev_attrs)) for key in ('files', 'parameters'): if key in dev_attrs: fields.setdefault(key, {}).update( jsonutils.loads(dev_attrs.pop(key))) region_name = device.get('placement_attr', {}).get('region_name', None) heatclient_ = HeatClient(auth_attr, region_name) unsupported_res_prop = self.fetch_unsupported_resource_prop( heatclient_) LOG.debug('vnfd_yaml %s', vnfd_yaml) if vnfd_yaml is not None: vnfd_dict = yamlparser.simple_ordered_parse(vnfd_yaml) LOG.debug('vnfd_dict %s', vnfd_dict) monitoring_dict = {'vdus': {}} if 'tosca_definitions_version' in vnfd_dict: parsed_params = dev_attrs.pop('param_values', {}) toscautils.updateimports(vnfd_dict) try: tosca = ToscaTemplate(parsed_params=parsed_params, a_file=False, yaml_dict_tpl=vnfd_dict) except Exception as e: LOG.debug("tosca-parser error: %s", str(e)) raise vnfm.ToscaParserFailed(error_msg_details=str(e)) monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) res_tpl = toscautils.get_resources_dict( tosca, STACK_FLAVOR_EXTRA) toscautils.post_process_template(tosca) try: translator = TOSCATranslator(tosca, parsed_params) heat_template_yaml = translator.translate() except Exception as e: LOG.debug("heat-translator error: %s", str(e)) raise vnfm.HeatTranslatorFailed(error_msg_details=str(e)) heat_template_yaml = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, res_tpl, unsupported_res_prop) else: assert 'template' not in fields assert 'template_url' not in fields template_dict = yaml.load(HEAT_TEMPLATE_BASE) outputs_dict = {} template_dict['outputs'] = outputs_dict if 'get_input' in vnfd_yaml: self._process_parameterized_input(dev_attrs, vnfd_dict) KEY_LIST = (('description', 'description'), ) for (key, vnfd_key) in KEY_LIST: if vnfd_key in vnfd_dict: template_dict[key] = vnfd_dict[vnfd_key] for vdu_id, vdu_dict in vnfd_dict.get('vdus', {}).items(): template_dict.setdefault('resources', {})[vdu_id] = { "type": "OS::Nova::Server" } resource_dict = template_dict['resources'][vdu_id] KEY_LIST = (('image', 'vm_image'), ('flavor', 'instance_type')) resource_dict['properties'] = {} properties = resource_dict['properties'] for (key, vdu_key) in KEY_LIST: properties[key] = vdu_dict[vdu_key] if 'network_interfaces' in vdu_dict: self._process_vdu_network_interfaces( vdu_id, vdu_dict, properties, template_dict, unsupported_res_prop) if ('user_data' in vdu_dict and 'user_data_format' in vdu_dict): properties['user_data_format'] = vdu_dict[ 'user_data_format'] properties['user_data'] = vdu_dict['user_data'] elif ('user_data' in vdu_dict or 'user_data_format' in vdu_dict): raise vnfm.UserDataFormatNotFound() if 'placement_policy' in vdu_dict: if 'availability_zone' in vdu_dict['placement_policy']: properties['availability_zone'] = vdu_dict[ 'placement_policy']['availability_zone'] if 'config' in vdu_dict: properties['config_drive'] = True metadata = properties.setdefault('metadata', {}) metadata.update(vdu_dict['config']) for key, value in metadata.items(): metadata[key] = value[:255] if 'key_name' in vdu_dict: properties['key_name'] = vdu_dict['key_name'] monitoring_policy = vdu_dict.get('monitoring_policy', 'noop') failure_policy = vdu_dict.get('failure_policy', 'noop') # Convert the old monitoring specification to the new # network. This should be removed after Mitaka if (monitoring_policy == 'ping' and failure_policy == 'respawn'): vdu_dict['monitoring_policy'] = { 'ping': { 'actions': { 'failure': 'respawn' } } } vdu_dict.pop('failure_policy') if monitoring_policy != 'noop': monitoring_dict['vdus'][vdu_id] = \ vdu_dict['monitoring_policy'] # to pass necessary parameters to plugin upwards. for key in ('service_type', ): if key in vdu_dict: device.setdefault('attributes', {})[vdu_id] = jsonutils.dumps( {key: vdu_dict[key]}) heat_template_yaml = yaml.dump(template_dict) fields['template'] = heat_template_yaml if not device['attributes'].get('heat_template'): device['attributes']['heat_template'] = \ heat_template_yaml if monitoring_dict.keys(): device['attributes']['monitoring_policy'] = \ jsonutils.dumps(monitoring_dict) if 'stack_name' not in fields: name = (__name__ + '_' + self.__class__.__name__ + '-' + device['id']) if device['attributes'].get('failure_count'): name += ('-RESPAWN-%s') % str( device['attributes']['failure_count']) fields['stack_name'] = name # service context is ignored LOG.debug(_('service_context: %s'), device.get('service_context', [])) LOG.debug(_('fields: %s'), fields) LOG.debug(_('template: %s'), fields['template']) stack = heatclient_.create(fields) return stack['stack']['id']
def test_translate_nodejs_mongodb(self): translate = TOSCATranslator(self.tosca, self.parsed_params) output = translate.translate() expected_resource = { 'mongo_dbms_create_config': { 'properties': { 'config': { 'get_file': 'mongodb/create.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'mongo_dbms_configure_config': { 'properties': { 'config': { 'get_file': 'mongodb/config.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'mongo_dbms_start_config': { 'properties': { 'config': { 'get_file': 'mongodb/start.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'nodejs_create_config': { 'properties': { 'config': { 'get_file': 'nodejs/create.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'nodejs_configure_config': { 'properties': { 'config': { 'get_file': 'nodejs/config.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'nodejs_start_config': { 'properties': { 'config': { 'get_file': 'nodejs/start.sh' }, 'group': 'script' }, 'type': 'OS::Heat::SoftwareConfig' }, 'mongo_dbms_create_deploy': { 'properties': { 'config': { 'get_resource': 'mongo_dbms_create_config' }, 'server': { 'get_resource': 'mongo_server' } }, 'type': 'OS::Heat::SoftwareDeployment' }, 'mongo_dbms_configure_deploy': { 'type': 'OS::Heat::SoftwareDeployment', 'depends_on': ['mongo_dbms_create_deploy'], 'properties': { 'config': { 'get_resource': 'mongo_dbms_configure_config' }, 'input_values': { 'mongodb_ip': { 'get_attr': ['mongo_server', 'networks', 'private', 0] } }, 'server': { 'get_resource': 'mongo_server' } } }, 'mongo_dbms_start_deploy': { 'type': 'OS::Heat::SoftwareDeployment', 'depends_on': ['mongo_dbms_configure_deploy'], 'properties': { 'config': { 'get_resource': 'mongo_dbms_start_config' }, 'server': { 'get_resource': 'mongo_server' } } }, 'nodejs_create_deploy': { 'properties': { 'config': { 'get_resource': 'nodejs_create_config' }, 'server': { 'get_resource': 'app_server' } }, 'type': 'OS::Heat::SoftwareDeployment' }, 'nodejs_configure_deploy': { 'depends_on': ['nodejs_create_deploy'], 'properties': { 'config': { 'get_resource': 'nodejs_configure_config' }, 'input_values': { 'github_url': 'https://github.com/sample.git', 'mongodb_ip': { 'get_attr': ['mongo_server', 'networks', 'private', 0] } }, 'server': { 'get_resource': 'app_server' } }, 'type': 'OS::Heat::SoftwareDeployment' }, 'nodejs_start_deploy': { 'depends_on': ['nodejs_configure_deploy'], 'properties': { 'config': { 'get_resource': 'nodejs_start_config' }, 'server': { 'get_resource': 'app_server' } }, 'type': 'OS::Heat::SoftwareDeployment' }, 'app_server': { 'properties': { 'flavor': 'm1.medium', 'image': 'ubuntu-software-config-os-init', 'key_name': 'userkey', 'user_data_format': 'SOFTWARE_CONFIG' }, 'type': 'OS::Nova::Server' }, 'mongo_server': { 'properties': { 'flavor': 'm1.medium', 'image': 'ubuntu-software-config-os-init', 'key_name': 'userkey', 'user_data_format': 'SOFTWARE_CONFIG' }, 'type': 'OS::Nova::Server' } } output_dict = translator.toscalib.utils.yamlparser.simple_parse(output) resources = output_dict.get('resources') for resource_name in resources: translated_value = resources.get(resource_name) expected_value = expected_resource.get(resource_name) self.assertEqual(translated_value, expected_value)