From 5ffbb36ee468de70b878b1cb58e256c1f361522a Mon Sep 17 00:00:00 2001 From: Bharath Thiruveedula Date: Mon, 21 Mar 2016 14:11:47 +0530 Subject: [PATCH] Implements auto flavor creation Partially-implements: automatic-resource-creation Change-Id: I59526f4868fb0189f963dc146d13d24831518b4d --- .../samples/sample-tosca-vnfd-flavor.yaml | 37 ++++++++++ tacker/common/utils.py | 39 +++++++++++ tacker/tests/unit/test_common_utils.py | 12 ++++ .../infra_drivers/heat/data/hot_flavor.yaml | 32 +++++++++ .../data/hot_flavor_and_capabilities.yaml | 26 +++++++ .../heat/data/hot_flavor_defaults.yaml | 32 +++++++++ .../heat/data/hot_flavor_no_units.yaml | 33 +++++++++ .../heat/data/test_tosca_flavor.yaml | 44 ++++++++++++ .../test_tosca_flavor_and_capabilities.yaml | 44 ++++++++++++ .../heat/data/test_tosca_flavor_defaults.yaml | 41 +++++++++++ .../heat/data/test_tosca_flavor_no_units.yaml | 43 ++++++++++++ .../unit/vm/infra_drivers/heat/test_heat.py | 70 ++++++++++++++----- tacker/tests/unit/vm/test_toscautils.py | 33 ++++++++- tacker/vm/infra_drivers/heat/heat.py | 3 +- tacker/vm/tosca/lib/tacker_defs.yaml | 9 +++ tacker/vm/tosca/lib/tacker_nfv_defs.yaml | 3 + tacker/vm/tosca/utils.py | 66 ++++++++++++++++- 17 files changed, 544 insertions(+), 23 deletions(-) create mode 100644 devstack/samples/sample-tosca-vnfd-flavor.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_and_capabilities.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_defaults.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_no_units.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_and_capabilities.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_defaults.yaml create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_no_units.yaml diff --git a/devstack/samples/sample-tosca-vnfd-flavor.yaml b/devstack/samples/sample-tosca-vnfd-flavor.yaml new file mode 100644 index 000000000..6f1e07d1c --- /dev/null +++ b/devstack/samples/sample-tosca-vnfd-flavor.yaml @@ -0,0 +1,37 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: Demo example + +metadata: + template_name: sample-tosca-vnfd + +topology_template: + node_templates: + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + capabilities: + nfv_compute: + properties: + disk_size: 1 GB + mem_size: 512 MB + num_cpus: 2 + properties: + image: cirros-0.3.4-x86_64-uec + mgmt_driver: noop + availability_zone: nova + + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: net1 + vendor: Tacker diff --git a/tacker/common/utils.py b/tacker/common/utils.py index 8557f1125..0cb20c1db 100644 --- a/tacker/common/utils.py +++ b/tacker/common/utils.py @@ -41,6 +41,28 @@ from tacker.openstack.common import log as logging TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" LOG = logging.getLogger(__name__) SYNCHRONIZED_PREFIX = 'tacker-' +MEM_UNITS = { + "MB": { + "MB": { + "op": "*", + "val": "1" + }, + "GB": { + "op": "/", + "val": "1024" + } + }, + "GB": { + "MB": { + "op": "*", + "val": "1024" + }, + "GB": { + "op": "*", + "val": "1" + } + } +} synchronized = lockutils.synchronized_with_prefix(SYNCHRONIZED_PREFIX) @@ -308,3 +330,20 @@ def is_valid_ipv4(address): return netaddr.valid_ipv4(address) except Exception: return False + + +def change_memory_unit(mem, to): + """Changes the memory value(mem) based on the unit('to') specified. + + If the unit is not specified in 'mem', by default, it is considered + as "MB". And this method returns only integer. + """ + + mem = str(mem) + " MB" if str(mem).isdigit() else mem.upper() + for unit, value in MEM_UNITS.iteritems(): + mem_arr = mem.split(unit) + if len(mem_arr) < 2: + continue + return eval(mem_arr[0] + + MEM_UNITS[unit][to]["op"] + + MEM_UNITS[unit][to]["val"]) diff --git a/tacker/tests/unit/test_common_utils.py b/tacker/tests/unit/test_common_utils.py index fe929a1c2..a986fb1eb 100644 --- a/tacker/tests/unit/test_common_utils.py +++ b/tacker/tests/unit/test_common_utils.py @@ -381,3 +381,15 @@ class TestDict2Tuples(base.BaseTestCase): expected = ((42, 'baz'), ('aaa', 'zzz'), ('foo', 'bar')) output_tuple = utils.dict2tuple(input_dict) self.assertEqual(expected, output_tuple) + + +class TestChangeMemory(testtools.TestCase): + def test_change_memory_from_mb_to_gb(self): + actual_val = utils.change_memory_unit("1024 mb", "GB") + expected_val = 1 + self.assertEqual(actual_val, expected_val) + + def test_change_memory_from_gb_to_mb(self): + actual_val = utils.change_memory_unit("1 GB", "MB") + expected_val = 1024 + self.assertEqual(actual_val, expected_val) diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor.yaml new file mode 100644 index 000000000..f5112d61a --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor.yaml @@ -0,0 +1,32 @@ +heat_template_version: 2013-05-23 + +description: > + OpenWRT with services + +outputs: + mgmt_ip-VDU1: + value: + get_attr: [CP1, fixed_ips, 0, ip_address] + +parameters: {} +resources: + VDU1: + type: OS::Nova::Server + properties: + config_drive: false + flavor: {get_resource: VDU1_flavor} + image: OpenWRT + networks: + - port: + get_resource: CP1 + user_data_format: SOFTWARE_CONFIG + CP1: + type: OS::Neutron::Port + properties: + network: existing_network_1 + VDU1_flavor: + type: OS::Nova::Flavor + properties: + disk: 10 + ram: 512 + vcpus: 2 diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_and_capabilities.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_and_capabilities.yaml new file mode 100644 index 000000000..1d03ab70d --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_and_capabilities.yaml @@ -0,0 +1,26 @@ +heat_template_version: 2013-05-23 + +description: > + OpenWRT with services + +outputs: + mgmt_ip-VDU1: + value: + get_attr: [CP1, fixed_ips, 0, ip_address] + +parameters: {} +resources: + VDU1: + type: OS::Nova::Server + properties: + config_drive: false + flavor: m1.nano + image: OpenWRT + networks: + - port: + get_resource: CP1 + user_data_format: SOFTWARE_CONFIG + CP1: + type: OS::Neutron::Port + properties: + network: existing_network_1 diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_defaults.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_defaults.yaml new file mode 100644 index 000000000..b33bf1685 --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_defaults.yaml @@ -0,0 +1,32 @@ +heat_template_version: 2013-05-23 + +description: > + OpenWRT with services + +outputs: + mgmt_ip-VDU1: + value: + get_attr: [CP1, fixed_ips, 0, ip_address] + +parameters: {} +resources: + VDU1: + type: OS::Nova::Server + properties: + config_drive: false + flavor: {get_resource: VDU1_flavor} + image: OpenWRT + networks: + - port: + get_resource: CP1 + user_data_format: SOFTWARE_CONFIG + CP1: + type: OS::Neutron::Port + properties: + network: existing_network_1 + VDU1_flavor: + type: OS::Nova::Flavor + properties: + disk: 10 + ram: 512 + vcpus: 1 diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_no_units.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_no_units.yaml new file mode 100644 index 000000000..817854c8d --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_flavor_no_units.yaml @@ -0,0 +1,33 @@ +heat_template_version: 2013-05-23 + +description: > + OpenWRT with services + +outputs: + mgmt_ip-VDU1: + value: + get_attr: [CP1, fixed_ips, 0, ip_address] + +parameters: {} +resources: + VDU1: + type: OS::Nova::Server + properties: + config_drive: false + flavor: {get_resource: VDU1_flavor} + image: OpenWRT + networks: + - port: + get_resource: CP1 + user_data_format: SOFTWARE_CONFIG + CP1: + type: OS::Neutron::Port + properties: + network: existing_network_1 + + VDU1_flavor: + type: OS::Nova::Flavor + properties: + disk: 2 + ram: 512 + vcpus: 2 diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor.yaml new file mode 100644 index 000000000..8ec4bfa5c --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor.yaml @@ -0,0 +1,44 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: OpenWRT with services + +metadata: + template_name: OpenWRT + +topology_template: + node_templates: + + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + capabilities: + nfv_compute: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + properties: + image: OpenWRT + mgmt_driver: openwrt + monitoring_policy: + name: ping + actions: + - {trigger: failure, action: respawn} + parameters: + count: "3" + interval: "10" + + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: existing_network_1 + vendor: ACME diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_and_capabilities.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_and_capabilities.yaml new file mode 100644 index 000000000..e5fbb0244 --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_and_capabilities.yaml @@ -0,0 +1,44 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: OpenWRT with services + +metadata: + template_name: OpenWRT + +topology_template: + node_templates: + + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + capabilities: + nfv_compute: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + properties: + image: OpenWRT + mgmt_driver: openwrt + flavor: m1.nano + monitoring_policy: + name: ping + actions: + - {trigger: failure, action: respawn} + parameters: + count: "3" + interval: "10" + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: existing_network_1 + vendor: ACME diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_defaults.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_defaults.yaml new file mode 100644 index 000000000..934c3924c --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_defaults.yaml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: OpenWRT with services + +metadata: + template_name: OpenWRT + +topology_template: + node_templates: + + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + capabilities: + nfv_compute: + properties: + disk_size: 10 GB + properties: + image: OpenWRT + mgmt_driver: openwrt + monitoring_policy: + name: ping + actions: + - {trigger: failure, action: respawn} + parameters: + count: "3" + interval: "10" + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: existing_network_1 + vendor: ACME diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_no_units.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_no_units.yaml new file mode 100644 index 000000000..f650b7169 --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_flavor_no_units.yaml @@ -0,0 +1,43 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: OpenWRT with services + +metadata: + template_name: OpenWRT + +topology_template: + node_templates: + + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + capabilities: + nfv_compute: + properties: + num_cpus: 2 + disk_size: 2048 + mem_size: 512 + properties: + image: OpenWRT + mgmt_driver: openwrt + monitoring_policy: + name: ping + actions: + - {trigger: failure, action: respawn} + parameters: + count: "3" + interval: "10" + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: existing_network_1 + vendor: ACME diff --git a/tacker/tests/unit/vm/infra_drivers/heat/test_heat.py b/tacker/tests/unit/vm/infra_drivers/heat/test_heat.py index f87f5d10d..6b7dffcd1 100644 --- a/tacker/tests/unit/vm/infra_drivers/heat/test_heat.py +++ b/tacker/tests/unit/vm/infra_drivers/heat/test_heat.py @@ -17,6 +17,7 @@ import codecs import mock import os import testtools +import yaml from tacker import context from tacker.tests.unit.db import utils @@ -49,8 +50,6 @@ class TestDeviceHeat(testtools.TestCase): hot_param_template = _get_template('hot_openwrt_params.yaml') hot_ipparam_template = _get_template('hot_openwrt_ipparams.yaml') vnfd_openwrt = _get_template('openwrt.yaml') - tosca_openwrt = _get_template('test_tosca_openwrt.yaml') - hot_tosca_openwrt = _get_template('hot_tosca_openwrt.yaml') config_data = _get_template('config_data.yaml') def setUp(self): @@ -192,22 +191,25 @@ class TestDeviceHeat(testtools.TestCase): self.assertEqual(device_obj, expected_device_update) def test_create_device_template_pre_tosca(self): - dtemplate = self._get_device_template(self.tosca_openwrt) - exp_tmpl = self._get_expected_device_template(self.tosca_openwrt) + tosca_tpl = _get_template('test_tosca_openwrt.yaml') + dtemplate = self._get_device_template(tosca_tpl) + exp_tmpl = self._get_expected_device_template(tosca_tpl) self.heat_driver.create_device_template_pre(None, None, dtemplate) self.assertEqual(dtemplate, exp_tmpl) - def _get_expected_fields_tosca(self): + def _get_expected_fields_tosca(self, template): return {'stack_name': 'tacker.vm.infra_drivers.heat.heat_DeviceHeat-eb84260e' '-5ff7-4332-b032-50a14d6c1123', - 'template': self.hot_tosca_openwrt} + 'template': _get_template(template)} - def _get_expected_tosca_device(self): - exp_tmpl = self._get_expected_device_template(self.tosca_openwrt) + def _get_expected_tosca_device(self, tosca_tpl_name, hot_tpl_name): + tosca_tpl = _get_template(tosca_tpl_name) + exp_tmpl = self._get_expected_device_template(tosca_tpl) + tosca_hw_dict = yaml.safe_load(_get_template(hot_tpl_name)) return {'device_template': exp_tmpl['device_template'], 'description': u'OpenWRT with services', - 'attributes': {'heat_template': self.hot_tosca_openwrt, + 'attributes': {'heat_template': tosca_hw_dict, 'monitoring_policy': '{"vdus": {"VDU1":' ' {"name": "ping", "actions": [{"trigger":' ' "failure", "action": "respawn"}],' @@ -220,10 +222,8 @@ class TestDeviceHeat(testtools.TestCase): 'template_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e', 'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437'} - def _get_dummy_tosca_device(self, template=''): - tosca_template = getattr(self, 'tosca_' + template, None) - if not tosca_template: - tosca_template = self.tosca_openwrt + def _get_dummy_tosca_device(self, template): + tosca_template = _get_template(template) device = utils.get_dummy_device_obj() dtemplate = self._get_expected_device_template(tosca_template) dtemplate['service_types'] = [{'service_type': 'vnfd', 'id': @@ -232,14 +232,46 @@ class TestDeviceHeat(testtools.TestCase): device['device_template'] = dtemplate['device_template'] return device - def test_create_tosca(self): - # self.skipTest("Not ready yet") - device = self._get_dummy_tosca_device() + def _test_assert_equal_for_tosca_templates(self, tosca_tpl_name, + hot_tpl_name): + device = self._get_dummy_tosca_device(tosca_tpl_name) expected_result = '4a4c2d44-8a52-4895-9a75-9d1c76c3e738' - expected_fields = self._get_expected_fields_tosca() - expected_device = self._get_expected_tosca_device() + expected_fields = self._get_expected_fields_tosca(hot_tpl_name) + expected_device = self._get_expected_tosca_device(tosca_tpl_name, + hot_tpl_name) result = self.heat_driver.create(plugin=None, context=self.context, device=device) - self.heat_client.create.assert_called_once_with(expected_fields) + # self.heat_client.create.assert_called_once_with(expected_fields) + actual_fields = self.heat_client.create.call_args[0][0] + actual_fields["template"] = yaml.safe_load(actual_fields["template"]) + expected_fields["template"] = \ + yaml.safe_load(expected_fields["template"]) + self.assertEqual(actual_fields, expected_fields) + device["attributes"]["heat_template"] = yaml.safe_load( + device["attributes"]["heat_template"]) self.assertEqual(expected_result, result) self.assertEqual(device, expected_device) + + def test_create_tosca(self): + # self.skipTest("Not ready yet") + self._test_assert_equal_for_tosca_templates('test_tosca_openwrt.yaml', + 'hot_tosca_openwrt.yaml') + + def test_create_tosca_with_new_flavor(self): + self._test_assert_equal_for_tosca_templates('test_tosca_flavor.yaml', + 'hot_flavor.yaml') + + def test_create_tosca_with_new_flavor_with_defaults(self): + self._test_assert_equal_for_tosca_templates( + 'test_tosca_flavor_defaults.yaml', + 'hot_flavor_defaults.yaml') + + def test_create_tosca_with_flavor_and_capabilities(self): + self._test_assert_equal_for_tosca_templates( + 'test_tosca_flavor_and_capabilities.yaml', + 'hot_flavor_and_capabilities.yaml') + + def test_create_tosca_with_flavor_no_units(self): + self._test_assert_equal_for_tosca_templates( + 'test_tosca_flavor_no_units.yaml', + 'hot_flavor_no_units.yaml') diff --git a/tacker/tests/unit/vm/test_toscautils.py b/tacker/tests/unit/vm/test_toscautils.py index 25149b13e..6eeffcbf8 100644 --- a/tacker/tests/unit/vm/test_toscautils.py +++ b/tacker/tests/unit/vm/test_toscautils.py @@ -35,6 +35,7 @@ class TestToscaUtils(testtools.TestCase): toscautils.updateimports(vnfd_dict) tosca = ToscaTemplate(parsed_params={}, a_file=False, yaml_dict_tpl=vnfd_dict) + tosca_flavor = _get_template('test_tosca_flavor.yaml') def setUp(self): super(TestToscaUtils, self).setUp() @@ -106,7 +107,7 @@ class TestToscaUtils(testtools.TestCase): 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) + heat_template_yaml, mgmt_ports, {}) heatdict = yaml.load(heat_tpl) expecteddict = yaml.load(expected_heat_tpl) @@ -120,3 +121,33 @@ class TestToscaUtils(testtools.TestCase): for vdu in vdus: self.assertEqual(vdu.type_definition.is_derived_from( toscautils.TACKERVDU), True) + + def test_get_flavor_dict(self): + vnfd_dict = yaml.load(self.tosca_flavor) + toscautils.updateimports(vnfd_dict) + tosca = ToscaTemplate(a_file=False, yaml_dict_tpl=vnfd_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.load(_get_template( + 'hot_flavor_and_capabilities.yaml')) + expected_dict = yaml.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(dummy_heat_dict, expected_dict) diff --git a/tacker/vm/infra_drivers/heat/heat.py b/tacker/vm/infra_drivers/heat/heat.py index b7b2b08df..adc8cfc7b 100644 --- a/tacker/vm/infra_drivers/heat/heat.py +++ b/tacker/vm/infra_drivers/heat/heat.py @@ -273,6 +273,7 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): monitoring_dict = toscautils.get_vdu_monitoring(tosca) mgmt_ports = toscautils.get_mgmt_ports(tosca) + res_tpl = toscautils.get_resources_dict(tosca) toscautils.post_process_template(tosca) try: translator = TOSCATranslator(tosca, parsed_params) @@ -281,7 +282,7 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): 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) + heat_template_yaml, mgmt_ports, res_tpl) else: assert 'template' not in fields assert 'template_url' not in fields diff --git a/tacker/vm/tosca/lib/tacker_defs.yaml b/tacker/vm/tosca/lib/tacker_defs.yaml index 969f1cece..8d1e4f0ba 100644 --- a/tacker/vm/tosca/lib/tacker_defs.yaml +++ b/tacker/vm/tosca/lib/tacker_defs.yaml @@ -26,6 +26,15 @@ data_types: entry_schema: type: string + tosca.datatypes.compute_properties: + properties: + num_cpus: + type: integer + mem_size: + type: string + disk_size: + type: string + policy_types: tosca.policies.tacker.Placement: derived_from: tosca.policies.Root diff --git a/tacker/vm/tosca/lib/tacker_nfv_defs.yaml b/tacker/vm/tosca/lib/tacker_nfv_defs.yaml index 9602ed5cd..49cbb0f96 100644 --- a/tacker/vm/tosca/lib/tacker_nfv_defs.yaml +++ b/tacker/vm/tosca/lib/tacker_nfv_defs.yaml @@ -1,6 +1,9 @@ node_types: tosca.nodes.nfv.VDU.Tacker: derived_from: tosca.nodes.nfv.VDU + capabilities: + nfv_compute: + type: tosca.datatypes.compute_properties properties: image: # type: tosca.artifacts.Deployment.Image.VM diff --git a/tacker/vm/tosca/utils.py b/tacker/vm/tosca/utils.py index dd49fb1da..905c2b35e 100644 --- a/tacker/vm/tosca/utils.py +++ b/tacker/vm/tosca/utils.py @@ -12,9 +12,11 @@ # under the License. import os +import sys import yaml from tacker.common import log +from tacker.common import utils from tacker.extensions import vnfm from tacker.openstack.common import log as logging @@ -30,6 +32,15 @@ TACKERCP = 'tosca.nodes.nfv.CP.Tacker' TACKERVDU = 'tosca.nodes.nfv.VDU.Tacker' TOSCA_BINDS_TO = 'tosca.relationships.network.BindsTo' VDU = 'tosca.nodes.nfv.VDU' +OS_RESOURCES = { + 'flavor': 'get_flavor_dict' +} + +FLAVOR_PROPS = { + "num_cpus": ("vcpus", 1, None), + "disk_size": ("disk", 1, "GB"), + "mem_size": ("ram", 512, "MB") +} delpropmap = {TACKERVDU: ('mgmt_driver', 'config', 'service_type', @@ -42,6 +53,10 @@ convert_prop = {TACKERCP: {'anti_spoofing_protection': deletenodes = (MONITORING, FAILURE, PLACEMENT) +HEAT_RESOURCE_MAP = { + "flavor": "OS::Nova::Flavor" +} + @log.log def updateimports(template): @@ -95,7 +110,24 @@ def get_mgmt_ports(tosca): @log.log -def post_process_heat_template(heat_tpl, mgmt_ports): +def add_resources_tpl(heat_dict, hot_res_tpl): + for res, res_dict in hot_res_tpl.iteritems(): + for vdu, vdu_dict in res_dict.iteritems(): + res_name = vdu + "_" + res + heat_dict["resources"][res_name] = { + "type": HEAT_RESOURCE_MAP[res], + "properties": {} + } + + for prop, val in vdu_dict.iteritems(): + heat_dict["resources"][res_name]["properties"][prop] = val + heat_dict["resources"][vdu]["properties"][res] = { + "get_resource": res_name + } + + +@log.log +def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl): heat_dict = yamlparser.simple_ordered_parse(heat_tpl) for outputname, portname in mgmt_ports.items(): ipval = {'get_attr': [portname, 'fixed_ips', 0, 'ip_address']} @@ -105,7 +137,7 @@ def post_process_heat_template(heat_tpl, mgmt_ports): else: heat_dict['outputs'] = output LOG.debug(_('Added output for %s') % outputname) - + add_resources_tpl(heat_dict, res_tpl) return yaml.dump(heat_dict) @@ -156,3 +188,33 @@ def findvdus(template): if nt.type_definition.is_derived_from(TACKERVDU): vdus.append(nt) return vdus + + +def get_flavor_dict(template): + flavor_dict = {} + vdus = findvdus(template) + for nt in vdus: + flavor_tmp = nt.get_properties().get('flavor', None) + if flavor_tmp: + continue + if nt.get_capabilities().get("nfv_compute", None): + flavor_dict[nt.name] = {} + properties = nt.get_capabilities()["nfv_compute"].get_properties() + for prop, (hot_prop, default, unit) in \ + FLAVOR_PROPS.iteritems(): + hot_prop_val = (properties[prop].value + if properties.get(prop, None) else None) + if unit and hot_prop_val: + hot_prop_val = \ + utils.change_memory_unit(hot_prop_val, unit) + flavor_dict[nt.name][hot_prop] = \ + hot_prop_val if hot_prop_val else default + return flavor_dict + + +def get_resources_dict(template): + res_dict = dict() + for res, method in OS_RESOURCES.iteritems(): + res_dict[res] = getattr(sys.modules[__name__], + method)(template) + return res_dict