Fix for Multi BaseHot VNF cannot be instantiated
This fix will allow Instantiation to be successful when
Multiple Base Hot is defined in the VNFD Package.
Closes-Bug: # 1895830
https://bugs.launchpad.net/tacker/+bug/1895830
Change-Id: I2d5e677820a4978d609ab492aa64cdc5269fd5c9
(cherry picked from commit 59e166b62a
)
This commit is contained in:
parent
e72a66bbba
commit
3795395a62
|
@ -134,8 +134,15 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
yaml_file_dict = yaml.safe_load(f)
|
yaml_file_dict = yaml.safe_load(f)
|
||||||
return yaml_file_dict
|
return yaml_file_dict
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||||
|
'.OpenStack._format_base_hot')
|
||||||
|
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_normal(self, mock_OpenstackClients_heat):
|
def test_create_normal(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict,
|
||||||
|
mock_get_vnflcm_interface,
|
||||||
|
mock_format_base_hot):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -148,14 +155,20 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'instantiate_vnf_request_lcm_userdata.json')
|
'instantiate_vnf_request_lcm_userdata.json')
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
vnf_resource = type('', (), {})
|
vnf_resource = type('', (), {})
|
||||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||||
|
nested_hot_dict = {'parameters': {'vnf': 'test'}}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.openstack.create(self.plugin, self.context, vnf,
|
self.openstack.create(self.plugin, self.context, vnf,
|
||||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
base_hot_dict=base_hot_dict_test,
|
base_hot_dict=base_hot_dict_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_heat_stack(self, mock_OpenstackClients_heat):
|
def test_create_heat_stack(self, mock_OpenstackClients_heat):
|
||||||
|
@ -218,8 +231,10 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_userdata_null(self, mock_OpenstackClients_heat):
|
def test_create_userdata_null(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -235,17 +250,25 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
|
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_userdataclass_null(self, mock_OpenstackClients_heat):
|
def test_create_userdataclass_null(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -261,17 +284,25 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
|
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_import_module_exception(self, mock_OpenstackClients_heat):
|
def test_create_import_module_exception(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -284,7 +315,12 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'instantiate_vnf_request_lcm_userdata.json')
|
'instantiate_vnf_request_lcm_userdata.json')
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
with mock.patch.object(importlib, 'import_module') as mock_importlib:
|
with mock.patch.object(importlib, 'import_module') as mock_importlib:
|
||||||
mock_importlib.side_effect = Exception('Test Exception')
|
mock_importlib.side_effect = Exception('Test Exception')
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
|
@ -293,10 +329,13 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_getattr_none(self, mock_OpenstackClients_heat):
|
def test_create_getattr_none(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -309,7 +348,12 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'instantiate_vnf_request_lcm_userdata.json')
|
'instantiate_vnf_request_lcm_userdata.json')
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
with mock.patch.object(importlib, 'import_module') as mock_importlib:
|
with mock.patch.object(importlib, 'import_module') as mock_importlib:
|
||||||
mock_importlib.return_value = None
|
mock_importlib.return_value = None
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
|
@ -318,10 +362,13 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_missing_file(self, mock_OpenstackClients_heat):
|
def test_create_missing_file(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -334,19 +381,27 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'instantiate_vnf_request_lcm_userdata.json')
|
'instantiate_vnf_request_lcm_userdata.json')
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
vnf_resource = type('', (), {})
|
vnf_resource = type('', (), {})
|
||||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
base_hot_dict=base_hot_dict_test,
|
base_hot_dict=base_hot_dict_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_return_none_dict(self, mock_OpenstackClients_heat):
|
def test_create_return_none_dict(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -361,38 +416,54 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'UserData/lcm_user_data_non_dict.py'
|
'UserData/lcm_user_data_non_dict.py'
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
vnf_resource = type('', (), {})
|
vnf_resource = type('', (), {})
|
||||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
base_hot_dict=base_hot_dict_test,
|
base_hot_dict=base_hot_dict_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_none_base_hot_dict(self, mock_OpenstackClients_heat):
|
def test_create_none_base_hot_dict(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
inst_req_info_test = type('', (), {})
|
inst_req_info_test = type('', (), {})
|
||||||
test_json = self._json_load(
|
test_json = self._json_load(
|
||||||
'instantiate_vnf_request_lcm_userdata.json')
|
'instantiate_vnf_request_lcm_userdata.json')
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
base_hot_dict_test = None
|
base_hot_dict_test = None
|
||||||
vnf_package_path_test = None
|
vnf_package_path_test = None
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_invalid_user_data(self, mock_OpenstackClients_heat):
|
def test_create_invalid_user_data(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -409,18 +480,26 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
|
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_invalid_user_data_class(self,
|
def test_create_invalid_user_data_class(self,
|
||||||
mock_OpenstackClients_heat):
|
mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -437,18 +516,25 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
|
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
grant_info_test = None
|
grant_info_test = None
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, base_hot_dict_test,
|
self.auth_attr, base_hot_dict_test,
|
||||||
vnf_package_path_test,
|
vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test,
|
inst_req_info=inst_req_info_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_lcm_user_data_and_user_data_class_no_value(self,
|
def test_create_lcm_user_data_and_user_data_class_no_value(self,
|
||||||
mock_OpenstackClients_heat):
|
mock_OpenstackClients_heat, mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -466,16 +552,22 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
|
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = test_json['extVirtualLinks']
|
inst_req_info_test.ext_virtual_links = test_json['extVirtualLinks']
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
vnf_resource = type('', (), {})
|
vnf_resource = type('', (), {})
|
||||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
base_hot_dict=base_hot_dict_test,
|
base_hot_dict=base_hot_dict_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_lcm_user_data_and_user_data_class_none(self,
|
def test_create_lcm_user_data_and_user_data_class_none(self,
|
||||||
|
@ -523,8 +615,10 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
inst_req_info=inst_req_info_test)
|
inst_req_info=inst_req_info_test)
|
||||||
|
|
||||||
|
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||||
def test_create_instance_exception(self, mock_OpenstackClients_heat):
|
def test_create_instance_exception(self, mock_OpenstackClients_heat,
|
||||||
|
mock_get_base_hot_dict):
|
||||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||||
base_hot_dict_test = self._read_file()
|
base_hot_dict_test = self._read_file()
|
||||||
|
@ -539,16 +633,22 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
'UserData/lcm_user_data_invalid_script.py'
|
'UserData/lcm_user_data_invalid_script.py'
|
||||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||||
inst_req_info_test.ext_virtual_links = None
|
inst_req_info_test.ext_virtual_links = None
|
||||||
|
inst_req_info_test.flavour_id = test_json['flavourId']
|
||||||
vnf_resource = type('', (), {})
|
vnf_resource = type('', (), {})
|
||||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||||
|
nested_hot_dict = {'test': 'test'}
|
||||||
|
mock_get_base_hot_dict.return_value = \
|
||||||
|
self._read_file(), nested_hot_dict
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
self.assertRaises(vnfm.LCMUserDataFailed,
|
self.assertRaises(vnfm.LCMUserDataFailed,
|
||||||
self.openstack.create,
|
self.openstack.create,
|
||||||
self.plugin, self.context, vnf,
|
self.plugin, self.context, vnf,
|
||||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||||
vnf_package_path=vnf_package_path_test,
|
vnf_package_path=vnf_package_path_test,
|
||||||
base_hot_dict=base_hot_dict_test,
|
base_hot_dict=base_hot_dict_test,
|
||||||
grant_info=grant_info_test)
|
grant_info=grant_info_test,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
|
|
||||||
def test_create_wait(self):
|
def test_create_wait(self):
|
||||||
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
|
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
|
||||||
|
@ -1082,10 +1182,11 @@ class TestOpenStack(base.FixturedTestCase):
|
||||||
self.requests_mock.register_uri(
|
self.requests_mock.register_uri(
|
||||||
'POST', url, json={'stack': fd_utils.get_dummy_stack()},
|
'POST', url, json={'stack': fd_utils.get_dummy_stack()},
|
||||||
headers=self.json_headers)
|
headers=self.json_headers)
|
||||||
|
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||||
|
|
||||||
instance_id = self.openstack.instantiate_vnf(
|
instance_id = self.openstack.instantiate_vnf(
|
||||||
self.context, None, vnfd_dict, vim_connection_info,
|
self.context, vnf_instance, vnfd_dict, vim_connection_info,
|
||||||
inst_req_info, grant_response)
|
inst_req_info, grant_response, self.plugin)
|
||||||
|
|
||||||
self.assertEqual(uuidsentinel.instance_id, instance_id)
|
self.assertEqual(uuidsentinel.instance_id, instance_id)
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,8 @@ class TestUtils(testtools.TestCase):
|
||||||
return yaml_file_dict
|
return yaml_file_dict
|
||||||
|
|
||||||
def test_create_initial_param_dict(self):
|
def test_create_initial_param_dict(self):
|
||||||
base_hot_dict = self._read_file("hot_lcm_user_data.yaml")
|
base_hot_dict = {}
|
||||||
|
base_hot_dict['resources'] = self._read_file("hot_lcm_user_data.yaml")
|
||||||
initial_param_dict = utils.create_initial_param_dict(base_hot_dict)
|
initial_param_dict = utils.create_initial_param_dict(base_hot_dict)
|
||||||
self.assertEqual(example_initial_param_dict, initial_param_dict)
|
self.assertEqual(example_initial_param_dict, initial_param_dict)
|
||||||
|
|
||||||
|
@ -153,7 +154,8 @@ class TestUtils(testtools.TestCase):
|
||||||
self.assertEqual({}, vdu_image_dict)
|
self.assertEqual({}, vdu_image_dict)
|
||||||
|
|
||||||
def test_create_cpd_vl_dict(self):
|
def test_create_cpd_vl_dict(self):
|
||||||
base_hot_dict = {'resources': {'dummy_cpd_id': "101010_d"}}
|
base_hot_dict = \
|
||||||
|
{'resources': {'resources': {'dummy_cpd_id': "101010_d"}}}
|
||||||
inst_req_info = instantiate_vnf_req.InstantiateVnfRequest()
|
inst_req_info = instantiate_vnf_req.InstantiateVnfRequest()
|
||||||
ext_virtual_links_test_value = instantiate_vnf_req.ExtVirtualLinkData()
|
ext_virtual_links_test_value = instantiate_vnf_req.ExtVirtualLinkData()
|
||||||
ext_virtual_links_test_value.resource_id = 'dummy_resource_id'
|
ext_virtual_links_test_value.resource_id = 'dummy_resource_id'
|
||||||
|
@ -169,7 +171,8 @@ class TestUtils(testtools.TestCase):
|
||||||
self.assertEqual({'dummy_cpd_id': 'dummy_resource_id'}, cpd_vl_dict)
|
self.assertEqual({'dummy_cpd_id': 'dummy_resource_id'}, cpd_vl_dict)
|
||||||
|
|
||||||
def test_create_cpd_vl_dict_no_cp_resource(self):
|
def test_create_cpd_vl_dict_no_cp_resource(self):
|
||||||
base_hot_dict = {'resources': {'dummy_cpd_id': "101010_d"}}
|
base_hot_dict = \
|
||||||
|
{'resources': {'resources': {'dummy_cpd_id': "101010_d"}}}
|
||||||
inst_req_info = instantiate_vnf_req.InstantiateVnfRequest()
|
inst_req_info = instantiate_vnf_req.InstantiateVnfRequest()
|
||||||
ext_virtual_links_test_value = instantiate_vnf_req.ExtVirtualLinkData()
|
ext_virtual_links_test_value = instantiate_vnf_req.ExtVirtualLinkData()
|
||||||
ext_virtual_links_test_value.resource_id = 'dummy_resource_id'
|
ext_virtual_links_test_value.resource_id = 'dummy_resource_id'
|
||||||
|
|
|
@ -76,6 +76,36 @@ def _get_vnfd_dict(context, vnfd_id, flavour_id):
|
||||||
return vnfd_dict
|
return vnfd_dict
|
||||||
|
|
||||||
|
|
||||||
|
def _get_vnflcm_interface(context, interface, vnf_instance, flavour_id):
|
||||||
|
'''Gets the interface found in vnfd
|
||||||
|
|
||||||
|
...
|
||||||
|
node_templates:
|
||||||
|
VNF:
|
||||||
|
interfaces:
|
||||||
|
Vnflcm:
|
||||||
|
<interface>
|
||||||
|
'''
|
||||||
|
interface_value = None
|
||||||
|
vnfd_dict = _get_vnfd_dict(context, vnf_instance.vnfd_id, flavour_id)
|
||||||
|
|
||||||
|
if not isinstance(vnfd_dict, dict):
|
||||||
|
raise exceptions.InvalidContentType(msg="VNFD not valid")
|
||||||
|
|
||||||
|
if vnfd_dict.get('topology_template'):
|
||||||
|
topology_template = vnfd_dict.get('topology_template')
|
||||||
|
if topology_template.get('node_templates'):
|
||||||
|
for a_val in topology_template.get('node_templates').values():
|
||||||
|
if 'interfaces' in a_val.keys():
|
||||||
|
interfaces = a_val.get('interfaces')
|
||||||
|
if interfaces.get('Vnflcm'):
|
||||||
|
vnflcm = interfaces.get('Vnflcm')
|
||||||
|
if vnflcm:
|
||||||
|
interface_value = vnflcm.get(interface)
|
||||||
|
|
||||||
|
return interface_value
|
||||||
|
|
||||||
|
|
||||||
def _build_affected_resources(vnf_instance,
|
def _build_affected_resources(vnf_instance,
|
||||||
change_type=fields.ResourceChangeType.ADDED):
|
change_type=fields.ResourceChangeType.ADDED):
|
||||||
'''build affected resources from vnf_instance instantiated info '''
|
'''build affected resources from vnf_instance instantiated info '''
|
||||||
|
@ -1022,3 +1052,31 @@ def _get_base_hot_dict(context, vnfd_id):
|
||||||
base_hot_dict = yaml.safe_load(open(source_file_path))
|
base_hot_dict = yaml.safe_load(open(source_file_path))
|
||||||
LOG.debug("Loaded base hot: %s", base_hot_dict)
|
LOG.debug("Loaded base hot: %s", base_hot_dict)
|
||||||
return base_hot_dict
|
return base_hot_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_nest_hot_dict(context, flavour_id, vnfd_id):
|
||||||
|
vnf_package_id = _get_vnf_package_id(context, vnfd_id)
|
||||||
|
vnf_package_base_path = cfg.CONF.vnf_package.vnf_package_csar_path
|
||||||
|
vnf_package_csar_path = vnf_package_base_path + '/' + vnf_package_id
|
||||||
|
base_hot_dir = 'BaseHOT'
|
||||||
|
ext = [".yaml", ".yml"]
|
||||||
|
|
||||||
|
base_hot_path = vnf_package_csar_path + '/' + \
|
||||||
|
base_hot_dir + '/' + flavour_id
|
||||||
|
base_hot_dict = None
|
||||||
|
nested_hot_path = base_hot_path + '/nested'
|
||||||
|
nested_hot_dict = {}
|
||||||
|
if os.path.exists(base_hot_path):
|
||||||
|
for file in os.listdir(base_hot_path):
|
||||||
|
if file.endswith(tuple(ext)):
|
||||||
|
source_file_path = os.path.join(base_hot_path, file)
|
||||||
|
base_hot_dict = yaml.safe_load(open(source_file_path))
|
||||||
|
if os.path.exists(nested_hot_path):
|
||||||
|
for file in os.listdir(nested_hot_path):
|
||||||
|
if file.endswith(tuple(ext)):
|
||||||
|
source_file_path = os.path.join(nested_hot_path, file)
|
||||||
|
nested_hot = yaml.safe_load(open(source_file_path))
|
||||||
|
nested_hot_dict[file] = nested_hot
|
||||||
|
LOG.debug("Loaded base hot: %s", base_hot_dict)
|
||||||
|
LOG.debug("Loaded nested_hot_dict: %s", nested_hot_dict)
|
||||||
|
return base_hot_dict, nested_hot_dict
|
||||||
|
|
|
@ -136,8 +136,10 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
|
||||||
vim_connection_info, instantiate_vnf_req):
|
vim_connection_info, instantiate_vnf_req):
|
||||||
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnf_instance.vnfd_id,
|
vnfd_dict = vnflcm_utils._get_vnfd_dict(context, vnf_instance.vnfd_id,
|
||||||
instantiate_vnf_req.flavour_id)
|
instantiate_vnf_req.flavour_id)
|
||||||
base_hot_dict = vnflcm_utils._get_base_hot_dict(
|
base_hot_dict, nested_hot_dict = vnflcm_utils. \
|
||||||
context, vnf_instance.vnfd_id)
|
get_base_nest_hot_dict(context,
|
||||||
|
instantiate_vnf_req.flavour_id,
|
||||||
|
vnf_instance.vnfd_id)
|
||||||
vnf_package_path = None
|
vnf_package_path = None
|
||||||
if base_hot_dict is not None:
|
if base_hot_dict is not None:
|
||||||
vnf_package_path = vnflcm_utils._get_vnf_package_path(
|
vnf_package_path = vnflcm_utils._get_vnf_package_path(
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
import eventlet
|
import eventlet
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import yaml
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
@ -28,8 +29,6 @@ from oslo_serialization import jsonutils
|
||||||
from oslo_utils import encodeutils
|
from oslo_utils import encodeutils
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
import yaml
|
|
||||||
|
|
||||||
from tacker._i18n import _
|
from tacker._i18n import _
|
||||||
from tacker.common import exceptions
|
from tacker.common import exceptions
|
||||||
from tacker.common import log
|
from tacker.common import log
|
||||||
|
@ -39,6 +38,7 @@ from tacker.extensions import vnfm
|
||||||
from tacker import objects
|
from tacker import objects
|
||||||
from tacker.objects import fields
|
from tacker.objects import fields
|
||||||
from tacker.tosca.utils import represent_odict
|
from tacker.tosca.utils import represent_odict
|
||||||
|
from tacker.vnflcm import utils as vnflcm_utils
|
||||||
from tacker.vnfm.infra_drivers import abstract_driver
|
from tacker.vnfm.infra_drivers import abstract_driver
|
||||||
from tacker.vnfm.infra_drivers.openstack import constants as infra_cnst
|
from tacker.vnfm.infra_drivers.openstack import constants as infra_cnst
|
||||||
from tacker.vnfm.infra_drivers.openstack import glance_client as gc
|
from tacker.vnfm.infra_drivers.openstack import glance_client as gc
|
||||||
|
@ -48,6 +48,7 @@ from tacker.vnfm.infra_drivers.openstack import vdu
|
||||||
from tacker.vnfm.infra_drivers import scale_driver
|
from tacker.vnfm.infra_drivers import scale_driver
|
||||||
from tacker.vnfm.lcm_user_data.constants import USER_DATA_TIMEOUT
|
from tacker.vnfm.lcm_user_data.constants import USER_DATA_TIMEOUT
|
||||||
|
|
||||||
|
|
||||||
eventlet.monkey_patch(time=True)
|
eventlet.monkey_patch(time=True)
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -89,6 +90,8 @@ OUTPUT_PREFIX = 'mgmt_ip-'
|
||||||
ALARMING_POLICY = 'tosca.policies.tacker.Alarming'
|
ALARMING_POLICY = 'tosca.policies.tacker.Alarming'
|
||||||
SCALING_POLICY = 'tosca.policies.tacker.Scaling'
|
SCALING_POLICY = 'tosca.policies.tacker.Scaling'
|
||||||
|
|
||||||
|
NOVA_SERVER_RESOURCE = "OS::Nova::Server"
|
||||||
|
|
||||||
|
|
||||||
def get_scaling_policy_name(action, policy_name):
|
def get_scaling_policy_name(action, policy_name):
|
||||||
return '%s_scale_%s' % (policy_name, action)
|
return '%s_scale_%s' % (policy_name, action)
|
||||||
|
@ -117,7 +120,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
@log.log
|
@log.log
|
||||||
def create(self, plugin, context, vnf, auth_attr,
|
def create(self, plugin, context, vnf, auth_attr,
|
||||||
base_hot_dict=None, vnf_package_path=None,
|
base_hot_dict=None, vnf_package_path=None,
|
||||||
inst_req_info=None, grant_info=None):
|
inst_req_info=None, grant_info=None,
|
||||||
|
vnf_instance=None):
|
||||||
LOG.debug('vnf %s', vnf)
|
LOG.debug('vnf %s', vnf)
|
||||||
region_name = vnf.get('placement_attr', {}).get('region_name', None)
|
region_name = vnf.get('placement_attr', {}).get('region_name', None)
|
||||||
heatclient = hc.HeatClient(auth_attr, region_name)
|
heatclient = hc.HeatClient(auth_attr, region_name)
|
||||||
|
@ -138,10 +142,20 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
|
|
||||||
if user_data_path is not None and user_data_class is not None:
|
if user_data_path is not None and user_data_class is not None:
|
||||||
LOG.info('Execute user data and create heat-stack.')
|
LOG.info('Execute user data and create heat-stack.')
|
||||||
|
base_hot_dict, nested_hot_dict = vnflcm_utils. \
|
||||||
|
get_base_nest_hot_dict(context,
|
||||||
|
inst_req_info.flavour_id,
|
||||||
|
vnf_instance.vnfd_id)
|
||||||
if base_hot_dict is None:
|
if base_hot_dict is None:
|
||||||
error_reason = _("failed to get Base HOT.")
|
error_reason = _("failed to get Base HOT.")
|
||||||
raise vnfm.LCMUserDataFailed(reason=error_reason)
|
raise vnfm.LCMUserDataFailed(reason=error_reason)
|
||||||
|
|
||||||
|
if base_hot_dict is None:
|
||||||
|
nested_hot_dict = {}
|
||||||
|
|
||||||
|
for name, hot in nested_hot_dict.items():
|
||||||
|
vnf['attributes'][name] = self._format_base_hot(hot)
|
||||||
|
|
||||||
vnfd_str = vnf['vnfd']['attributes']['vnfd']
|
vnfd_str = vnf['vnfd']['attributes']['vnfd']
|
||||||
vnfd_dict = yaml.safe_load(vnfd_str)
|
vnfd_dict = yaml.safe_load(vnfd_str)
|
||||||
LOG.debug('VNFD: %s', vnfd_dict)
|
LOG.debug('VNFD: %s', vnfd_dict)
|
||||||
|
@ -175,10 +189,13 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
|
|
||||||
# Set the timeout and execute the UserData script.
|
# Set the timeout and execute the UserData script.
|
||||||
hot_param_dict = None
|
hot_param_dict = None
|
||||||
|
param_base_hot_dict = copy.deepcopy(nested_hot_dict)
|
||||||
|
param_base_hot_dict['heat_template'] = base_hot_dict
|
||||||
with eventlet.timeout.Timeout(USER_DATA_TIMEOUT, False):
|
with eventlet.timeout.Timeout(USER_DATA_TIMEOUT, False):
|
||||||
try:
|
try:
|
||||||
hot_param_dict = klass.instantiate(
|
hot_param_dict = klass.instantiate(
|
||||||
base_hot_dict, vnfd_dict, inst_req_info, grant_info)
|
param_base_hot_dict, vnfd_dict,
|
||||||
|
inst_req_info, grant_info)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
@ -196,9 +213,13 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
"is not in dict format.")
|
"is not in dict format.")
|
||||||
raise vnfm.LCMUserDataFailed(reason=error_reason)
|
raise vnfm.LCMUserDataFailed(reason=error_reason)
|
||||||
|
|
||||||
|
# Add stack param to vnf_attributes
|
||||||
|
vnf['attributes'].update({'stack_param': str(hot_param_dict)})
|
||||||
|
|
||||||
# Create heat-stack with BaseHOT and parameters
|
# Create heat-stack with BaseHOT and parameters
|
||||||
stack = self._create_stack_with_user_data(
|
stack = self._create_stack_with_user_data(
|
||||||
heatclient, vnf, base_hot_dict, hot_param_dict)
|
heatclient, vnf, base_hot_dict,
|
||||||
|
nested_hot_dict, hot_param_dict)
|
||||||
|
|
||||||
elif user_data_path is None and user_data_class is None:
|
elif user_data_path is None and user_data_class is None:
|
||||||
LOG.info('Execute heat-translator and create heat-stack.')
|
LOG.info('Execute heat-translator and create heat-stack.')
|
||||||
|
@ -230,13 +251,18 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
|
|
||||||
@log.log
|
@log.log
|
||||||
def _create_stack_with_user_data(self, heatclient, vnf,
|
def _create_stack_with_user_data(self, heatclient, vnf,
|
||||||
base_hot_dict, hot_param_dict):
|
base_hot_dict, nested_hot_dict,
|
||||||
|
hot_param_dict):
|
||||||
fields = {}
|
fields = {}
|
||||||
fields['stack_name'] = ("vnflcm_" + vnf["id"])
|
fields['stack_name'] = ("vnflcm_" + vnf["id"])
|
||||||
fields['template'] = self._format_base_hot(base_hot_dict)
|
fields['template'] = self._format_base_hot(base_hot_dict)
|
||||||
fields['parameters'] = hot_param_dict
|
fields['parameters'] = hot_param_dict
|
||||||
fields['timeout_mins'] = (
|
fields['timeout_mins'] = (
|
||||||
self.STACK_RETRIES * self.STACK_RETRY_WAIT // 60)
|
self.STACK_RETRIES * self.STACK_RETRY_WAIT // 60)
|
||||||
|
if nested_hot_dict:
|
||||||
|
fields['files'] = {}
|
||||||
|
for name, value in nested_hot_dict.items():
|
||||||
|
fields['files'][name] = self._format_base_hot(value)
|
||||||
|
|
||||||
LOG.debug('fields: %s', fields)
|
LOG.debug('fields: %s', fields)
|
||||||
LOG.debug('template: %s', fields['template'])
|
LOG.debug('template: %s', fields['template'])
|
||||||
|
@ -771,7 +797,7 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
|
|
||||||
def instantiate_vnf(self, context, vnf_instance, vnfd_dict,
|
def instantiate_vnf(self, context, vnf_instance, vnfd_dict,
|
||||||
vim_connection_info, instantiate_vnf_req,
|
vim_connection_info, instantiate_vnf_req,
|
||||||
grant_response,
|
grant_response, plugin,
|
||||||
base_hot_dict=None, vnf_package_path=None):
|
base_hot_dict=None, vnf_package_path=None):
|
||||||
access_info = vim_connection_info.access_info
|
access_info = vim_connection_info.access_info
|
||||||
region_name = access_info.get('region')
|
region_name = access_info.get('region')
|
||||||
|
@ -779,10 +805,11 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||||
placement_attr.update({'region_name': region_name})
|
placement_attr.update({'region_name': region_name})
|
||||||
vnfd_dict['placement_attr'] = placement_attr
|
vnfd_dict['placement_attr'] = placement_attr
|
||||||
|
|
||||||
instance_id = self.create(None, context, vnfd_dict,
|
instance_id = self.create(plugin, context, vnfd_dict,
|
||||||
access_info, base_hot_dict, vnf_package_path,
|
access_info, base_hot_dict, vnf_package_path,
|
||||||
inst_req_info=instantiate_vnf_req,
|
inst_req_info=instantiate_vnf_req,
|
||||||
grant_info=grant_response)
|
grant_info=grant_response,
|
||||||
|
vnf_instance=vnf_instance)
|
||||||
vnfd_dict['instance_id'] = instance_id
|
vnfd_dict['instance_id'] = instance_id
|
||||||
return instance_id
|
return instance_id
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,11 @@ LOG = logging.getLogger(__name__)
|
||||||
HOT_NOVA_SERVER = 'OS::Nova::Server'
|
HOT_NOVA_SERVER = 'OS::Nova::Server'
|
||||||
HOT_NOVA_FLAVOR = 'OS::Nova::Flavor'
|
HOT_NOVA_FLAVOR = 'OS::Nova::Flavor'
|
||||||
HOT_NEUTRON_PORT = 'OS::Neutron::Port'
|
HOT_NEUTRON_PORT = 'OS::Neutron::Port'
|
||||||
SUPPORTED_HOT_TYPE = [HOT_NOVA_SERVER, HOT_NOVA_FLAVOR, HOT_NEUTRON_PORT]
|
AUTO_SCALING_GROUP = 'OS::Heat::AutoScalingGroup'
|
||||||
|
HOT_CINDER_VOLUME = 'OS::Cinder::Volume'
|
||||||
|
SUPPORTED_HOT_TYPE = [HOT_NOVA_SERVER, HOT_NOVA_FLAVOR,
|
||||||
|
HOT_NEUTRON_PORT, HOT_CINDER_VOLUME]
|
||||||
|
PORT_SERVER_TYPE = [HOT_NOVA_SERVER, HOT_NEUTRON_PORT, HOT_CINDER_VOLUME]
|
||||||
|
|
||||||
|
|
||||||
def create_initial_param_dict(base_hot_dict):
|
def create_initial_param_dict(base_hot_dict):
|
||||||
|
@ -55,20 +59,123 @@ def create_initial_param_dict(base_hot_dict):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resources = base_hot_dict.get('resources', {})
|
for hot_dict in base_hot_dict.values():
|
||||||
for resource_name, resource_val in resources.items():
|
param_nfv = hot_dict.get('parameters', {}).get('nfv')
|
||||||
resource_type = resource_val.get('type')
|
if not param_nfv:
|
||||||
if resource_type in SUPPORTED_HOT_TYPE:
|
continue
|
||||||
resource_props = resource_val.get('properties', {})
|
resources = hot_dict.get('resources', {})
|
||||||
for prop_key, prop_val in resource_props.items():
|
for resource_name, resource_val in resources.items():
|
||||||
if isinstance(prop_val, dict) and 'get_param' in prop_val:
|
resource_type = resource_val.get('type')
|
||||||
param_list = prop_val['get_param']
|
if resource_type in SUPPORTED_HOT_TYPE:
|
||||||
if len(param_list) == 4:
|
resource_props = resource_val.get('properties', {})
|
||||||
resource_info = initial_param_dict.get(
|
for prop_key, prop_val in resource_props.items():
|
||||||
param_list[0], {}).get(
|
if isinstance(prop_val, dict) and 'get_param' in prop_val:
|
||||||
param_list[1], {})
|
param_list = prop_val['get_param']
|
||||||
if param_list[2] not in resource_info:
|
if len(param_list) == 4:
|
||||||
resource_info[param_list[2]] = {}
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
if resource_type == HOT_NOVA_SERVER:
|
||||||
|
cinder_boot = resource_props.get('block_device_mapping_v2',
|
||||||
|
{})
|
||||||
|
if cinder_boot:
|
||||||
|
for boot in cinder_boot:
|
||||||
|
b_param = boot.get('image')
|
||||||
|
if b_param and \
|
||||||
|
isinstance(b_param, dict) and \
|
||||||
|
'get_param' in b_param:
|
||||||
|
param_list = b_param['get_param']
|
||||||
|
if len(param_list) == 4:
|
||||||
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
elif resource_type == AUTO_SCALING_GROUP:
|
||||||
|
resource_nest = resource_val.get('properties').get('resource')
|
||||||
|
resource_props = resource_nest.get('properties', {})
|
||||||
|
for prop_key, prop_val in resource_props.items():
|
||||||
|
if isinstance(prop_val, dict) and 'get_param' in prop_val:
|
||||||
|
param_list = prop_val['get_param']
|
||||||
|
if len(param_list) == 4:
|
||||||
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
|
||||||
|
LOG.info('initial_param_dict: %s', initial_param_dict)
|
||||||
|
return initial_param_dict
|
||||||
|
|
||||||
|
|
||||||
|
def create_initial_param_server_port_dict(base_hot_dict):
|
||||||
|
"""Create initial dict containing information about get_param resources.
|
||||||
|
|
||||||
|
:param base_hot_dict: dict(Base HOT dict format)
|
||||||
|
:return: dict('nfv', Initial HOT resource dict)
|
||||||
|
|
||||||
|
NOTE: 'nfv' is a fixed value for 1st element.
|
||||||
|
'VDU' and 'CP' are supported for 2nd element.
|
||||||
|
3rd and 4th element are mandatory.
|
||||||
|
"""
|
||||||
|
initial_param_dict = {
|
||||||
|
'nfv': {
|
||||||
|
'VDU': {
|
||||||
|
},
|
||||||
|
'CP': {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for hot_dict in base_hot_dict.values():
|
||||||
|
LOG.debug("init hot_dict: %s", hot_dict)
|
||||||
|
param_nfv = hot_dict.get('parameters', {}).get('nfv')
|
||||||
|
if not param_nfv:
|
||||||
|
continue
|
||||||
|
resources = hot_dict.get('resources', {})
|
||||||
|
for resource_name, resource_val in resources.items():
|
||||||
|
resource_type = resource_val.get('type')
|
||||||
|
if resource_type in PORT_SERVER_TYPE:
|
||||||
|
resource_props = resource_val.get('properties', {})
|
||||||
|
for prop_key, prop_val in resource_props.items():
|
||||||
|
if isinstance(prop_val, dict) and 'get_param' in prop_val:
|
||||||
|
param_list = prop_val['get_param']
|
||||||
|
if len(param_list) == 4:
|
||||||
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
if resource_type == HOT_NOVA_SERVER:
|
||||||
|
cinder_boot = resource_props.get('block_device_mapping_v2',
|
||||||
|
{})
|
||||||
|
if cinder_boot:
|
||||||
|
for boot in cinder_boot:
|
||||||
|
b_param = boot.get('image')
|
||||||
|
if b_param and \
|
||||||
|
isinstance(b_param, dict) and \
|
||||||
|
'get_param' in b_param:
|
||||||
|
param_list = b_param['get_param']
|
||||||
|
if len(param_list) == 4:
|
||||||
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
elif resource_type == AUTO_SCALING_GROUP:
|
||||||
|
resource_nest = resource_val.get('properties').get('resource')
|
||||||
|
resource_props = resource_nest.get('properties', {})
|
||||||
|
for prop_key, prop_val in resource_props.items():
|
||||||
|
if isinstance(prop_val, dict) and 'get_param' in prop_val:
|
||||||
|
param_list = prop_val['get_param']
|
||||||
|
if len(param_list) == 4:
|
||||||
|
resource_info = initial_param_dict.get(
|
||||||
|
param_list[0], {}).get(
|
||||||
|
param_list[1], {})
|
||||||
|
if param_list[2] not in resource_info:
|
||||||
|
resource_info[param_list[2]] = {}
|
||||||
|
|
||||||
LOG.info('initial_param_dict: %s', initial_param_dict)
|
LOG.info('initial_param_dict: %s', initial_param_dict)
|
||||||
return initial_param_dict
|
return initial_param_dict
|
||||||
|
@ -162,11 +269,107 @@ def create_cpd_vl_dict(base_hot_dict, inst_req_info):
|
||||||
ext_cps = ext_vl.ext_cps
|
ext_cps = ext_vl.ext_cps
|
||||||
vl_uuid = ext_vl.resource_id
|
vl_uuid = ext_vl.resource_id
|
||||||
for ext_cp in ext_cps:
|
for ext_cp in ext_cps:
|
||||||
cp_resource = base_hot_dict['resources'].get(
|
for hot_dict in base_hot_dict.values():
|
||||||
ext_cp.cpd_id)
|
cp_resource = hot_dict['resources'].get(
|
||||||
if cp_resource is None:
|
ext_cp.cpd_id)
|
||||||
continue
|
if cp_resource is None:
|
||||||
cpd_vl_dict[ext_cp.cpd_id] = vl_uuid
|
continue
|
||||||
|
cpd_vl_dict[ext_cp.cpd_id] = vl_uuid
|
||||||
|
break
|
||||||
|
|
||||||
LOG.info('cpd_vl_dict: %s', cpd_vl_dict)
|
LOG.info('cpd_vl_dict: %s', cpd_vl_dict)
|
||||||
return cpd_vl_dict
|
return cpd_vl_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_diff_base_hot_param_from_api(base_hot_dict, inst_req_info):
|
||||||
|
"""Compare base hot param from API param.
|
||||||
|
|
||||||
|
:param base_hot_dict: dict(Base HOT dict format)
|
||||||
|
:param inst_req_info: dict(Instantiation request information format)
|
||||||
|
:return: dict(Parameters)
|
||||||
|
"""
|
||||||
|
param_value = {}
|
||||||
|
additional_param = inst_req_info.additional_params
|
||||||
|
|
||||||
|
if additional_param is None:
|
||||||
|
additional_param = {}
|
||||||
|
input_attributes = base_hot_dict['heat_template'].get('parameters')
|
||||||
|
|
||||||
|
for input_attr, value in input_attributes.items():
|
||||||
|
if additional_param.get(input_attr):
|
||||||
|
param_value.update({input_attr: additional_param.get(
|
||||||
|
input_attr)})
|
||||||
|
|
||||||
|
return param_value
|
||||||
|
|
||||||
|
|
||||||
|
def create_vdu_flavor_capability_name_dict(vnfd_dict):
|
||||||
|
"""Create a dict containing information about VDU's flavor.
|
||||||
|
|
||||||
|
:param vnfd_dict: dict(VNFD dict format)
|
||||||
|
:return: dict(VDU name, VDU Capability Name dict)
|
||||||
|
"""
|
||||||
|
vdu_flavor_dict = {}
|
||||||
|
node_templates = vnfd_dict.get(
|
||||||
|
'topology_template', {}).get(
|
||||||
|
'node_templates', {})
|
||||||
|
|
||||||
|
for vdu_name, val in node_templates.items():
|
||||||
|
vdu_flavor_props = val.get(
|
||||||
|
'capabilities', {}).get(
|
||||||
|
'virtual_compute', {}).get('properties', {})
|
||||||
|
if vdu_flavor_props is not {}:
|
||||||
|
for key, val in vdu_flavor_props.items():
|
||||||
|
if key == 'requested_additional_capabilities':
|
||||||
|
capability_props = val.get('properties', {})
|
||||||
|
if 'requested_additional_capability_name'\
|
||||||
|
in capability_props.keys():
|
||||||
|
vdu_flavor_dict[vdu_name] = \
|
||||||
|
capability_props[
|
||||||
|
"requested_additional"
|
||||||
|
"_capability_name"]
|
||||||
|
|
||||||
|
LOG.info('vdu_flavor_dict: %s', vdu_flavor_dict)
|
||||||
|
return vdu_flavor_dict
|
||||||
|
|
||||||
|
|
||||||
|
def create_sw_image_dict(vnfd_dict):
|
||||||
|
"""Create a dict containing information about VDU's flavor.
|
||||||
|
|
||||||
|
:param vnfd_dict: dict(VNFD dict format)
|
||||||
|
:return: dict(VDU name, VDU SW Image data dict)
|
||||||
|
"""
|
||||||
|
sw_image_data = {}
|
||||||
|
node_templates = vnfd_dict.get(
|
||||||
|
'topology_template', {}).get(
|
||||||
|
'node_templates', {})
|
||||||
|
|
||||||
|
for vdu_name, val in node_templates.items():
|
||||||
|
sw_image_data_props = val.get(
|
||||||
|
'properties', {}).get('sw_image_data', {})
|
||||||
|
if sw_image_data_props is not {}:
|
||||||
|
if 'name' in sw_image_data_props.keys():
|
||||||
|
sw_image_data[vdu_name] = sw_image_data_props['name']
|
||||||
|
|
||||||
|
LOG.info('sw_image_data: %s', sw_image_data)
|
||||||
|
return sw_image_data
|
||||||
|
|
||||||
|
|
||||||
|
def create_network_dict(inst_req_info, param_dict):
|
||||||
|
"""Create a dict containing information about VDU's network.
|
||||||
|
|
||||||
|
:param inst_req_info: dict(Instantiation request information format)
|
||||||
|
:param param_dict: dict('nfv', Initial HOT resource dict)
|
||||||
|
:return: dict(VDU name, VDU SW Image data dict)
|
||||||
|
"""
|
||||||
|
cp_data = {}
|
||||||
|
ext_vl_param = inst_req_info.ext_virtual_links
|
||||||
|
cp_param = param_dict.get('nfv', {}).get('CP')
|
||||||
|
|
||||||
|
for ext_vl in ext_vl_param:
|
||||||
|
for ext_cp in ext_vl.ext_cps:
|
||||||
|
if ext_cp.cpd_id in cp_param.keys():
|
||||||
|
cp_data[ext_cp.cpd_id] = ext_vl.resource_id
|
||||||
|
|
||||||
|
LOG.info('cp_data: %s', cp_data)
|
||||||
|
return cp_data
|
||||||
|
|
Loading…
Reference in New Issue