def _test_samples(self, files): if files: for f in self._get_list_of_sample(files): with open(f, 'r') as _f: yaml_dict = None try: yaml_dict = yamlparser.simple_ordered_parse(_f.read()) except: # noqa pass self.assertIsNotNone(yaml_dict, "Yaml parser failed to parse %s" % f) utils.updateimports(yaml_dict) tosca = None try: tosca = tosca_template.ToscaTemplate( a_file=False, yaml_dict_tpl=yaml_dict) except: # noqa pass self.assertIsNotNone(tosca, "Tosca parser failed to parse %s" % f) utils.post_process_template(tosca) hot = None try: hot = tosca_translator.TOSCATranslator(tosca, {}).translate() except: # noqa pass self.assertIsNotNone( hot, "Heat-translator failed to translate %s" % f)
def _parse_template_input(self, mead): mead_dict = mead['mead'] mead_yaml = mead_dict['attributes'].get('mead') if mead_yaml is None: return inner_mead_dict = yaml.safe_load(mead_yaml) LOG.debug('mead_dict: %s', inner_mead_dict) # Prepend the apmec_defs.yaml import file with the full # path to the file toscautils.updateimports(inner_mead_dict) try: tosca = ToscaTemplate(a_file=False, yaml_dict_tpl=inner_mead_dict) except Exception as e: LOG.exception("tosca-parser error: %s", str(e)) raise mem.ToscaParserFailed(error_msg_details=str(e)) if ('description' not in mead_dict or mead_dict['description'] == ''): mead_dict['description'] = inner_mead_dict.get('description', '') if (('name' not in mead_dict or not len(mead_dict['name'])) and 'metadata' in inner_mead_dict): mead_dict['name'] = inner_mead_dict['metadata'].get( 'template_name', '') mead_dict['mgmt_driver'] = toscautils.get_mgmt_driver(tosca) LOG.debug('mead %s', mead)
def test_apmec_conf_heat_extra_specs_all_numa_count(self): tosca_fes_all_numa_count = _get_template( 'tosca_flavor_all_numa_count.yaml') mead_dict = yaml.safe_load(tosca_fes_all_numa_count) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=mead_dict) expected_flavor_dict = { "VDU1": { "vcpus": 8, "disk": 10, "ram": 4096, "extra_specs": { 'hw:cpu_policy': 'dedicated', 'hw:mem_page_size': 'any', 'hw:cpu_sockets': 2, 'hw:cpu_threads': 2, 'hw:numa_nodes': 2, 'hw:cpu_cores': 2, 'hw:cpu_threads_policy': 'avoid', 'aggregate_instance_extra_specs:mec': 'true' } } } actual_flavor_dict = toscautils.get_flavor_dict( tosca, {"aggregate_instance_extra_specs:mec": "true"}) self.assertEqual(expected_flavor_dict, actual_flavor_dict)
def test_check_for_substitution_mappings(self): tosca_sb_map = _get_template('../../../../../etc/samples/test-nsd-' 'mead1.yaml') param = { 'substitution_mappings': { 'VL2': { 'type': 'tosca.nodes.mec.VL', 'properties': { 'network_name': 'net0', 'vendor': 'apmec' } }, 'VL1': { 'type': 'tosca.nodes.mec.VL', 'properties': { 'network_name': 'net_mgmt', 'vendor': 'apmec' } }, 'requirements': { 'virtualLink2': 'VL2', 'virtualLink1': 'VL1' } } } template = yaml.safe_load(tosca_sb_map) toscautils.updateimports(template) toscautils.check_for_substitution_mappings(template, param) self.assertNotIn('substitution_mappings', param)
def test_get_flavor_dict(self): mead_dict = yaml.safe_load(self.tosca_flavor) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=mead_dict) expected_flavor_dict = {"VDU1": {"vcpus": 2, "disk": 10, "ram": 512}} actual_flavor_dict = toscautils.get_flavor_dict(tosca) self.assertEqual(expected_flavor_dict, actual_flavor_dict)
def _parse_template_input(self, context, mesd): mesd_dict = mesd['mesd'] mesd_yaml = mesd_dict['attributes'].get('mesd') inner_mesd_dict = yaml.safe_load(mesd_yaml) mesd['meads'] = dict() LOG.debug('mesd_dict: %s', inner_mesd_dict) # From import we can deploy both NS and MEC Application nsd_imports = inner_mesd_dict['imports'].get('nsds') vnffg_imports = inner_mesd_dict['imports'].get('vnffgds') if nsd_imports: mesd_dict['attributes']['nsds'] = nsd_imports if vnffg_imports: mesd_dict['attributes']['vnffgds'] = vnffg_imports # Deploy MEC applications mem_plugin = manager.ApmecManager.get_service_plugins()['MEM'] mead_imports = inner_mesd_dict['imports']['meads'] inner_mesd_dict['imports'] = [] new_files = [] for mead_name in mead_imports: mead = mem_plugin.get_mead(context, mead_name) # Copy MEA types and MEA names sm_dict = yaml.safe_load( mead['attributes'] ['mead'])['topology_template']['substitution_mappings'] mesd['meads'][sm_dict['node_type']] = mead['name'] # Ugly Hack to validate the child templates # TODO(tbh): add support in tosca-parser to pass child # templates as dict fd, temp_path = mkstemp() with open(temp_path, 'w') as fp: fp.write(mead['attributes']['mead']) os.close(fd) new_files.append(temp_path) inner_mesd_dict['imports'].append(temp_path) # Prepend the apmec_defs.yaml import file with the full # path to the file toscautils.updateimports(inner_mesd_dict) try: ToscaTemplate(a_file=False, yaml_dict_tpl=inner_mesd_dict) except Exception as e: LOG.exception("tosca-parser error: %s", str(e)) raise meo.ToscaParserFailed(error_msg_details=str(e)) finally: for file_path in new_files: os.remove(file_path) inner_mesd_dict['imports'] = mead_imports if ('description' not in mesd_dict or mesd_dict['description'] == ''): mesd_dict['description'] = inner_mesd_dict.get('description', '') if (('name' not in mesd_dict or not len(mesd_dict['name'])) and 'metadata' in inner_mesd_dict): mesd_dict['name'] = inner_mesd_dict['metadata'].get( 'template_name', '') LOG.debug('mesd %s', mesd)
def validate_tosca(self, template): if "tosca_definitions_version" not in template: raise meo.ToscaParserFailed( error_msg_details='tosca_definitions_version missing in ' 'template') LOG.debug('template yaml: %s', template) toscautils.updateimports(template) try: tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=template) except Exception as e: LOG.exception("tosca-parser error: %s", str(e)) raise meo.ToscaParserFailed(error_msg_details=str(e))
def test_create_delete_tosca_mea_with_multiple_vdus(self): input_yaml = read_file('sample-tosca-mead-multi-vdu.yaml') tosca_dict = yaml.safe_load(input_yaml) mead_name = 'sample-tosca-mead-multi-vdu' tosca_arg = { 'mead': { 'name': mead_name, 'attributes': { 'mead': tosca_dict } } } # Create mead with tosca template mead_instance = self.client.create_mead(body=tosca_arg) self.assertIsNotNone(mead_instance) # Create mea with mead_id mead_id = mead_instance['mead']['id'] mea_arg = { 'mea': { 'mead_id': mead_id, 'name': "test_tosca_mea_with_multiple_vdus" } } mea_instance = self.client.create_mea(body=mea_arg) mea_id = mea_instance['mea']['id'] self.wait_until_mea_active(mea_id, constants.MEA_CIRROS_CREATE_TIMEOUT, constants.ACTIVE_SLEEP_TIME) self.assertEqual('ACTIVE', self.client.show_mea(mea_id)['mea']['status']) self.validate_mea_instance(mead_instance, mea_instance) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_CREATE, evt_constants.PENDING_CREATE, cnt=2) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_CREATE, evt_constants.ACTIVE) # Validate mgmt_url with input yaml file mgmt_url = self.client.show_mea(mea_id)['mea']['mgmt_url'] self.assertIsNotNone(mgmt_url) mgmt_dict = yaml.safe_load(str(mgmt_url)) input_dict = yaml.safe_load(input_yaml) toscautils.updateimports(input_dict) tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=input_dict) vdus = toscautils.findvdus(tosca) self.assertEqual(len(vdus), len(mgmt_dict.keys())) for vdu in vdus: self.assertIsNotNone(mgmt_dict[vdu.name]) self.assertEqual(True, utils.is_valid_ipv4(mgmt_dict[vdu.name])) # Delete mea_instance with mea_id try: self.client.delete_mea(mea_id) except Exception: assert False, "mea Delete of test_mea_with_multiple_vdus failed" self.wait_until_mea_delete(mea_id, constants.MEA_CIRROS_DELETE_TIMEOUT) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_DELETE, evt_constants.PENDING_DELETE, cnt=2) # Delete mead_instance self.addCleanup(self.client.delete_mead, mead_id)
class TestToscaUtils(testtools.TestCase): tosca_openwrt = _get_template('test_tosca_openwrt.yaml') mead_dict = yaml.safe_load(tosca_openwrt) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=mead_dict) tosca_flavor = _get_template('test_tosca_flavor.yaml') def setUp(self): super(TestToscaUtils, self).setUp() def test_updateimport(self): importspath = os.path.abspath('./apmec/tosca/lib/') file1 = importspath + '/apmec_defs.yaml' file2 = importspath + '/apmec_mec_defs.yaml' expected_imports = [file1, file2] self.assertEqual(expected_imports, self.mead_dict['imports']) def test_get_mgmt_driver(self): expected_mgmt_driver = 'openwrt' mgmt_driver = toscautils.get_mgmt_driver(self.tosca) self.assertEqual(expected_mgmt_driver, mgmt_driver) def test_get_vdu_monitoring(self): expected_monitoring = { 'vdus': { 'VDU1': { 'ping': { 'actions': { 'failure': 'respawn' }, 'name': 'ping', 'parameters': { 'count': 3, 'interval': 10 }, 'monitoring_params': { 'count': 3, 'interval': 10 } } } } } monitoring = toscautils.get_vdu_monitoring(self.tosca) self.assertEqual(expected_monitoring, monitoring) def test_get_mgmt_ports(self): expected_mgmt_ports = {'mgmt_ip-VDU1': 'CP1'} mgmt_ports = toscautils.get_mgmt_ports(self.tosca) self.assertEqual(expected_mgmt_ports, mgmt_ports) def test_post_process_template(self): tosca2 = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=self.mead_dict) toscautils.post_process_template(tosca2) invalidNodes = 0 for nt in tosca2.nodetemplates: if (nt.type_definition.is_derived_from(toscautils.MONITORING) or nt.type_definition.is_derived_from(toscautils.FAILURE) or nt.type_definition.is_derived_from( toscautils.PLACEMENT)): invalidNodes += 1 self.assertEqual(0, invalidNodes) deletedProperties = 0 if nt.type in toscautils.delpropmap.keys(): for prop in toscautils.delpropmap[nt.type]: for p in nt.get_properties_objects(): if prop == p.name: deletedProperties += 1 self.assertEqual(0, deletedProperties) convertedProperties = 0 if nt.type in toscautils.convert_prop: for prop in toscautils.convert_prop[nt.type].keys(): for p in nt.get_properties_objects(): if prop == p.name: convertedProperties += 1 self.assertEqual(0, convertedProperties) def test_post_process_heat_template(self): tosca1 = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=self.mead_dict) toscautils.post_process_template(tosca1) translator = tosca_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.safe_load(heat_tpl) expecteddict = yaml.safe_load(expected_heat_tpl) self.assertEqual(expecteddict, heatdict) def test_findvdus(self): vdus = toscautils.findvdus(self.tosca) self.assertEqual(1, len(vdus)) for vdu in vdus: self.assertEqual( True, vdu.type_definition.is_derived_from(toscautils.APMECVDU)) def test_get_flavor_dict(self): mead_dict = yaml.safe_load(self.tosca_flavor) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=mead_dict) expected_flavor_dict = {"VDU1": {"vcpus": 2, "disk": 10, "ram": 512}} actual_flavor_dict = toscautils.get_flavor_dict(tosca) self.assertEqual(expected_flavor_dict, actual_flavor_dict) def test_add_resources_tpl_for_flavor(self): dummy_heat_dict = yaml.safe_load( _get_template('hot_flavor_and_capabilities.yaml')) expected_dict = yaml.safe_load(_get_template('hot_flavor.yaml')) dummy_heat_res = { "flavor": { "VDU1": { "vcpus": 2, "ram": 512, "disk": 10 } } } toscautils.add_resources_tpl(dummy_heat_dict, dummy_heat_res) self.assertEqual(expected_dict, dummy_heat_dict) def test_get_flavor_dict_extra_specs_all_numa_count(self): tosca_fes_all_numa_count = _get_template( 'tosca_flavor_all_numa_count.yaml') mead_dict = yaml.safe_load(tosca_fes_all_numa_count) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=mead_dict) expected_flavor_dict = { "VDU1": { "vcpus": 8, "disk": 10, "ram": 4096, "extra_specs": { 'hw:cpu_policy': 'dedicated', 'hw:mem_page_size': 'any', 'hw:cpu_sockets': 2, 'hw:cpu_threads': 2, 'hw:numa_nodes': 2, 'hw:cpu_cores': 2, 'hw:cpu_threads_policy': 'avoid' } } } actual_flavor_dict = toscautils.get_flavor_dict(tosca) self.assertEqual(expected_flavor_dict, actual_flavor_dict) def test_apmec_conf_heat_extra_specs_all_numa_count(self): tosca_fes_all_numa_count = _get_template( 'tosca_flavor_all_numa_count.yaml') mead_dict = yaml.safe_load(tosca_fes_all_numa_count) toscautils.updateimports(mead_dict) tosca = tosca_template.ToscaTemplate(a_file=False, yaml_dict_tpl=mead_dict) expected_flavor_dict = { "VDU1": { "vcpus": 8, "disk": 10, "ram": 4096, "extra_specs": { 'hw:cpu_policy': 'dedicated', 'hw:mem_page_size': 'any', 'hw:cpu_sockets': 2, 'hw:cpu_threads': 2, 'hw:numa_nodes': 2, 'hw:cpu_cores': 2, 'hw:cpu_threads_policy': 'avoid', 'aggregate_instance_extra_specs:mec': 'true' } } } actual_flavor_dict = toscautils.get_flavor_dict( tosca, {"aggregate_instance_extra_specs:mec": "true"}) self.assertEqual(expected_flavor_dict, actual_flavor_dict) def test_add_resources_tpl_for_image(self): dummy_heat_dict = yaml.safe_load( _get_template('hot_image_before_processed_image.yaml')) expected_dict = yaml.safe_load( _get_template('hot_image_after_processed_image.yaml')) dummy_heat_res = { "image": { "VDU1": { "location": "http://URL/v1/openwrt.qcow2", "container_format": "bare", "disk_format": "raw" } } } toscautils.add_resources_tpl(dummy_heat_dict, dummy_heat_res) self.assertEqual(expected_dict, dummy_heat_dict) def test_convert_unsupported_res_prop_kilo_ver(self): unsupported_res_prop_dict = { 'OS::Neutron::Port': { 'port_security_enabled': 'value_specs', }, } dummy_heat_dict = yaml.safe_load( _get_template('hot_tosca_openwrt.yaml')) expected_heat_dict = yaml.safe_load( _get_template('hot_tosca_openwrt_kilo.yaml')) toscautils.convert_unsupported_res_prop(dummy_heat_dict, unsupported_res_prop_dict) self.assertEqual(expected_heat_dict, dummy_heat_dict) def test_check_for_substitution_mappings(self): tosca_sb_map = _get_template('../../../../../etc/samples/test-nsd-' 'mead1.yaml') param = { 'substitution_mappings': { 'VL2': { 'type': 'tosca.nodes.mec.VL', 'properties': { 'network_name': 'net0', 'vendor': 'apmec' } }, 'VL1': { 'type': 'tosca.nodes.mec.VL', 'properties': { 'network_name': 'net_mgmt', 'vendor': 'apmec' } }, 'requirements': { 'virtualLink2': 'VL2', 'virtualLink1': 'VL1' } } } template = yaml.safe_load(tosca_sb_map) toscautils.updateimports(template) toscautils.check_for_substitution_mappings(template, param) self.assertNotIn('substitution_mappings', param) def test_get_block_storage_details(self): tosca_vol = _get_template('tosca_block_storage.yaml') mead_dict = yaml.safe_load(tosca_vol) expected_dict = { 'volumes': { 'VB1': { 'image': 'cirros-0.3.5-x86_64-disk', 'size': '1' } }, 'volume_attachments': { 'CB1': { 'instance_uuid': { 'get_resource': 'VDU1' }, 'mountpoint': '/dev/vdb', 'volume_id': { 'get_resource': 'VB1' } } } } volume_details = toscautils.get_block_storage_details(mead_dict) self.assertEqual(expected_dict, volume_details)
def test_create_delete_tosca_meac(self): input_yaml = read_file('sample_tosca_meac.yaml') tosca_dict = yaml.safe_load(input_yaml) path = os.path.abspath( os.path.join(os.path.dirname(__file__), "../../etc/samples")) mead_name = 'sample-tosca-meac' tosca_dict['topology_template']['node_templates' ]['firewall_meac' ]['interfaces' ]['Standard']['create'] = path \ + '/install_meac.sh' tosca_arg = { 'mead': { 'name': mead_name, 'attributes': { 'mead': tosca_dict } } } # Create mead with tosca template mead_instance = self.client.create_mead(body=tosca_arg) self.assertIsNotNone(mead_instance) # Create mea with mead_id mead_id = mead_instance['mead']['id'] mea_arg = {'mea': {'mead_id': mead_id, 'name': "test_tosca_meac"}} mea_instance = self.client.create_mea(body=mea_arg) mea_id = mea_instance['mea']['id'] self.wait_until_mea_active(mea_id, constants.MEAC_CREATE_TIMEOUT, constants.ACTIVE_SLEEP_TIME) self.assertEqual('ACTIVE', self.client.show_mea(mea_id)['mea']['status']) self.validate_mea_instance(mead_instance, mea_instance) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_CREATE, evt_constants.PENDING_CREATE, cnt=2) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_CREATE, evt_constants.ACTIVE) # Validate mgmt_url with input yaml file mgmt_url = self.client.show_mea(mea_id)['mea']['mgmt_url'] self.assertIsNotNone(mgmt_url) mgmt_dict = yaml.safe_load(str(mgmt_url)) input_dict = yaml.safe_load(input_yaml) toscautils.updateimports(input_dict) tosca = tosca_template.ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=input_dict) vdus = toscautils.findvdus(tosca) self.assertEqual(len(vdus), len(mgmt_dict.keys())) for vdu in vdus: self.assertIsNotNone(mgmt_dict[vdu.name]) self.assertEqual(True, utils.is_valid_ipv4(mgmt_dict[vdu.name])) # Check the status of SoftwareDeployment heat_stack_id = self.client.show_mea(mea_id)['mea']['instance_id'] resource_types = self.h_client.resources resources = resource_types.list(stack_id=heat_stack_id) for resource in resources: resource = resource.to_dict() if resource['resource_type'] == \ SOFTWARE_DEPLOYMENT: self.assertEqual('CREATE_COMPLETE', resource['resource_status']) break # Delete mea_instance with mea_id try: self.client.delete_mea(mea_id) except Exception: assert False, "mea Delete of test_mea_with_multiple_vdus failed" self.wait_until_mea_delete(mea_id, constants.MEA_CIRROS_DELETE_TIMEOUT) self.verify_mea_crud_events(mea_id, evt_constants.RES_EVT_DELETE, evt_constants.PENDING_DELETE, cnt=2) # Delete mead_instance self.addCleanup(self.client.delete_mead, mead_id)
def _generate_hot_from_tosca(self, mead_dict, dev_attrs): parsed_params = {} if 'param_values' in dev_attrs and dev_attrs['param_values'] != "": try: parsed_params = yaml.safe_load(dev_attrs['param_values']) except Exception as e: LOG.debug("Params not Well Formed: %s", str(e)) raise mem.ParamYAMLNotWellFormed(error_msg_details=str(e)) block_storage_details = toscautils.get_block_storage_details(mead_dict) toscautils.updateimports(mead_dict) if 'substitution_mappings' in str(mead_dict): toscautils.check_for_substitution_mappings(mead_dict, parsed_params) try: tosca = tosca_template.ToscaTemplate(parsed_params=parsed_params, a_file=False, yaml_dict_tpl=mead_dict) except Exception as e: LOG.debug("tosca-parser error: %s", str(e)) raise mem.ToscaParserFailed(error_msg_details=str(e)) metadata = toscautils.get_vdu_metadata(tosca) alarm_resources =\ toscautils.pre_process_alarm_resources(self.mea, tosca, metadata) monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) nested_resource_name = toscautils.get_nested_resources_name(tosca) res_tpl = toscautils.get_resources_dict(tosca, self.STACK_FLAVOR_EXTRA) toscautils.post_process_template(tosca) scaling_policy_names = toscautils.get_scaling_policy(tosca) try: translator = tosca_translator.TOSCATranslator(tosca, parsed_params) heat_template_yaml = translator.translate() if nested_resource_name: sub_heat_template_yaml =\ translator.translate_to_yaml_files_dict( nested_resource_name, True) nested_resource_yaml =\ sub_heat_template_yaml[nested_resource_name] self.nested_resources[nested_resource_name] =\ nested_resource_yaml except Exception as e: LOG.debug("heat-translator error: %s", str(e)) raise mem.HeatTranslatorFailed(error_msg_details=str(e)) if self.nested_resources: nested_tpl = toscautils.update_nested_scaling_resources( self.nested_resources, mgmt_ports, metadata, res_tpl, self.unsupported_props) self.fields['files'] = nested_tpl self.mea['attributes'][nested_resource_name] =\ nested_tpl[nested_resource_name] mgmt_ports.clear() if scaling_policy_names: scaling_group_dict = toscautils.get_scaling_group_dict( heat_template_yaml, scaling_policy_names) self.mea['attributes']['scaling_group_names'] =\ jsonutils.dumps(scaling_group_dict) heat_template_yaml = toscautils.post_process_heat_template( heat_template_yaml, mgmt_ports, metadata, alarm_resources, res_tpl, block_storage_details, self.unsupported_props) self.heat_template_yaml = heat_template_yaml self.monitoring_dict = monitoring_dict self.metadata = metadata