Fix issue of healing after scale out v1 VNF
This patch is: - The number of VNF instances in the stack list after SOL003 heal remains the number after scale out. - About the `vnfcResourceInfo`, `virtualStorageResourceInfo`, and `vnfcInfo` of vnflcm show command after SOL003 heal and scale out, the number of VDUs is correct. - About the `vnfcInfo` of vnflcm show command after scale out and scale in, the number of VDUs is correct. - For the VNF using heat-translator package, after instantiate, the setting of `scaleStatus` of vnflcm show command is correct. - Also about `vimLevelResourceType` of vnflcm show command after scale out, delete extra space before `OS::Nova::Server' or `OS::Cinder::Volume`. Related patch(fix about CNF): https://review.opendev.org/c/openstack/tacker/+/922195 Closes-Bug: #2084621 Change-Id: I127ac59a66ec2daaf49487bbbfb721f0e9c97638
This commit is contained in:
@ -1034,13 +1034,8 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
notify_mock_responses[0],
|
||||
'VnfIdentifierDeletionNotification')
|
||||
|
||||
def assert_instantiate_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
http_client=None,
|
||||
h_client=None,
|
||||
fake_server_manager=None):
|
||||
def assert_instantiate_vnf(self, resp, vnf_instance_id, http_client=None,
|
||||
h_client=None, fake_server_manager=None, expected_show_res=None):
|
||||
if http_client is None:
|
||||
http_client = self.http_client
|
||||
if h_client is None:
|
||||
@ -1083,14 +1078,12 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
'VnfLcmOperationOccurrenceNotification',
|
||||
'COMPLETED')
|
||||
|
||||
def assert_heal_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
expected_stack_status='UPDATE_COMPLETE',
|
||||
http_client=None,
|
||||
h_client=None,
|
||||
fake_server_manager=None):
|
||||
if expected_show_res:
|
||||
self._assert_show_res(vnf_instance, expected_show_res)
|
||||
|
||||
def assert_heal_vnf(self, resp, vnf_instance_id,
|
||||
expected_stack_status='UPDATE_COMPLETE', http_client=None,
|
||||
h_client=None, fake_server_manager=None, expected_show_res=None):
|
||||
if http_client is None:
|
||||
http_client = self.http_client
|
||||
if h_client is None:
|
||||
@ -1133,6 +1126,9 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
'VnfLcmOperationOccurrenceNotification',
|
||||
'COMPLETED')
|
||||
|
||||
if expected_show_res:
|
||||
self._assert_show_res(vnf_instance, expected_show_res)
|
||||
|
||||
def assert_terminate_vnf(
|
||||
self,
|
||||
resp,
|
||||
@ -1195,17 +1191,10 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
'VnfLcmOperationOccurrenceNotification',
|
||||
'COMPLETED')
|
||||
|
||||
def assert_scale_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
pre_stack_resource_list,
|
||||
post_stack_resource_list,
|
||||
scale_type='SCALE_OUT',
|
||||
expected_stack_status='CREATE_COMPLETE',
|
||||
http_client=None,
|
||||
h_client=None,
|
||||
fake_server_manager=None):
|
||||
def assert_scale_vnf(self, resp, vnf_instance_id, pre_stack_resource_list,
|
||||
post_stack_resource_list, scale_type='SCALE_OUT',
|
||||
expected_stack_status='CREATE_COMPLETE', http_client=None,
|
||||
h_client=None, fake_server_manager=None, expected_show_res=None):
|
||||
if http_client is None:
|
||||
http_client = self.http_client
|
||||
if h_client is None:
|
||||
@ -1263,6 +1252,9 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
'VnfLcmOperationOccurrenceNotification',
|
||||
'COMPLETED')
|
||||
|
||||
if expected_show_res:
|
||||
self._assert_show_res(vnf_instance, expected_show_res)
|
||||
|
||||
def assert_rollback_vnf(self, resp, vnf_instance_id,
|
||||
fake_server_manager=None):
|
||||
self.assertEqual(202, resp.status_code)
|
||||
@ -1523,3 +1515,21 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
return resource_dict
|
||||
|
||||
return resource_dict['VDU'][resource_name]['image']
|
||||
|
||||
def _assert_show_res(self, vnf_instance, expected_show_res):
|
||||
# Check result of show vnf instance
|
||||
if expected_show_res['len_vnfc_res_info']:
|
||||
vnfc_res_info = vnf_instance.get('instantiatedVnfInfo', {}).get(
|
||||
'vnfcResourceInfo', [])
|
||||
self.assertEqual(len(vnfc_res_info),
|
||||
expected_show_res['len_vnfc_res_info'])
|
||||
if expected_show_res['len_storage_res_info']:
|
||||
storage_res_info = vnf_instance.get('instantiatedVnfInfo', {}).get(
|
||||
'virtualStorageResourceInfo', [])
|
||||
self.assertEqual(len(storage_res_info),
|
||||
expected_show_res['len_storage_res_info'])
|
||||
if expected_show_res['len_vnfc_info']:
|
||||
vnfc_info = vnf_instance.get('instantiatedVnfInfo', {}).get(
|
||||
'vnfcInfo', [])
|
||||
self.assertEqual(len(vnfc_info),
|
||||
expected_show_res['len_vnfc_info'])
|
||||
|
@ -111,6 +111,142 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
|
||||
- Instantiate VNF.
|
||||
- Get VNF informations.
|
||||
- Scale-Out VNF
|
||||
- Scale-In(is_reverse) VNF
|
||||
- Terminate VNF
|
||||
- Delete VNF
|
||||
- Delete subscription
|
||||
"""
|
||||
# Create subscription and register it.
|
||||
callback_url = os.path.join(vnflcm_base.MOCK_NOTIFY_CALLBACK_URL,
|
||||
self._testMethodName)
|
||||
request_body = fake_vnflcm.Subscription.make_create_request_body(
|
||||
'http://localhost:{}{}'.format(
|
||||
vnflcm_base.FAKE_SERVER_MANAGER.SERVER_PORT,
|
||||
callback_url))
|
||||
resp, response_body = self._register_subscription(request_body)
|
||||
self.assertEqual(201, resp.status_code)
|
||||
self.assert_http_header_location_for_subscription(resp.headers)
|
||||
self.assert_notification_get(callback_url)
|
||||
subscription_id = response_body.get('id')
|
||||
self.addCleanup(
|
||||
self._delete_subscription,
|
||||
subscription_id)
|
||||
|
||||
# Pre Setting: Create vnf package.
|
||||
sample_name = 'functional5'
|
||||
csar_package_path = self._sample_path(sample_name)
|
||||
tempname, _ = vnflcm_base._create_csar_with_unique_vnfd_id(
|
||||
csar_package_path)
|
||||
# upload vnf package
|
||||
vnf_package_id, vnfd_id = vnflcm_base._create_and_upload_vnf_package(
|
||||
self.tacker_client, user_defined_data={
|
||||
"key": sample_name}, temp_csar_path=tempname)
|
||||
|
||||
# Post Setting: Reserve deleting vnf package.
|
||||
self.addCleanup(vnflcm_base._delete_vnf_package, self.tacker_client,
|
||||
vnf_package_id)
|
||||
|
||||
# Create vnf instance
|
||||
resp, vnf_instance = self._create_vnf_instance_from_body(
|
||||
fake_vnflcm.VnfInstances.make_create_request_body(vnfd_id))
|
||||
vnf_instance_id = vnf_instance['id']
|
||||
self._wait_lcm_done(vnf_instance_id=vnf_instance_id)
|
||||
self.assert_create_vnf(resp, vnf_instance, vnf_package_id)
|
||||
self.addCleanup(self._delete_vnf_instance, vnf_instance_id)
|
||||
|
||||
# Instantiate vnf instance
|
||||
request_body = fake_vnflcm.VnfInstances.\
|
||||
make_inst_request_body_include_num_dynamic(
|
||||
self.vim['tenant_id'], self.ext_networks,
|
||||
self.ext_mngd_networks, self.ext_link_ports, self.ext_subnets)
|
||||
resp, _ = self._instantiate_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 2, # = 1(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 1, # = 1(VDU1)
|
||||
'len_vnfc_info': 2 # = 1(VDU1) + 1(VDU2)
|
||||
}
|
||||
self.assert_instantiate_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Scale-out vnf instance
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
|
||||
request_body = fake_vnflcm.VnfInstances.make_scale_request_body(
|
||||
'SCALE_OUT')
|
||||
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
|
||||
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 3, # = 2(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 2, # = 2(VDU1)
|
||||
'len_vnfc_info': 3 # = 2(VDU1) + 1(VDU2)
|
||||
}
|
||||
self._assert_scale_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
pre_stack_resource_list, post_stack_resource_list,
|
||||
scale_type='SCALE_OUT', expected_stack_status='CREATE_COMPLETE',
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Scale-in vnf instance
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
|
||||
request_body = (fake_vnflcm.VnfInstances
|
||||
.make_reverse_scale_request_body('SCALE_IN'))
|
||||
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
|
||||
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 2, # = 1(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 1, # = 1(VDU1)
|
||||
'len_vnfc_info': 2 # = 1(VDU1) + 1(VDU2)
|
||||
}
|
||||
self._assert_scale_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
pre_stack_resource_list, post_stack_resource_list,
|
||||
scale_type='SCALE_IN', expected_stack_status='UPDATE_COMPLETE',
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Terminate VNF
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
resources_list = self._get_heat_resource_list(stack.id)
|
||||
resource_name_list = [r.resource_name for r in resources_list]
|
||||
glance_image_id_list = self._get_glance_image_list_from_stack_resource(
|
||||
stack.id, resource_name_list)
|
||||
|
||||
terminate_req_body = fake_vnflcm.VnfInstances.make_term_request_body()
|
||||
resp, _ = self._terminate_vnf_instance(
|
||||
vnf_instance_id, terminate_req_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
self.assert_terminate_vnf(resp, vnf_instance_id, stack.id,
|
||||
resource_name_list, glance_image_id_list, vnf_package_id)
|
||||
|
||||
# Delete VNF
|
||||
resp, _ = self._delete_vnf_instance(vnf_instance_id)
|
||||
self._wait_lcm_done(vnf_instance_id=vnf_instance_id)
|
||||
self.assert_delete_vnf(resp, vnf_instance_id, vnf_package_id)
|
||||
|
||||
# Subscription delete
|
||||
resp, response_body = self._delete_subscription(subscription_id)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
|
||||
resp, _ = self._show_subscription(subscription_id)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def test_inst_scaling_heal(self):
|
||||
"""Test basic life cycle operations with sample VNFD.
|
||||
|
||||
In this test case, we do following steps.
|
||||
- Create subscription.
|
||||
- Create VNF package.
|
||||
- Upload VNF package.
|
||||
- Create VNF instance.
|
||||
- Instantiate VNF.
|
||||
- Get VNF informations.
|
||||
- Scale-Out VNF
|
||||
- heal all VNF
|
||||
- Scale-In VNF
|
||||
- Terminate VNF
|
||||
- Delete VNF
|
||||
@ -161,39 +297,66 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
|
||||
self.ext_mngd_networks, self.ext_link_ports, self.ext_subnets)
|
||||
resp, _ = self._instantiate_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
self.assert_instantiate_vnf(resp, vnf_instance_id, vnf_package_id)
|
||||
|
||||
# Show vnf instance
|
||||
resp, vnf_instance = self._show_vnf_instance(vnf_instance_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 2, # = 1(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 1, # = 1(VDU1)
|
||||
'len_vnfc_info': 2 # = 1(VDU1) + 1(VDU2)
|
||||
}
|
||||
self.assert_instantiate_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Scale-out vnf instance
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
|
||||
request_body = fake_vnflcm.VnfInstances.make_scale_request_body(
|
||||
'SCALE_OUT')
|
||||
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
|
||||
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 3, # = 2(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 2, # = 2(VDU1)
|
||||
'len_vnfc_info': 3 # = 2(VDU1) + 1(VDU2)
|
||||
}
|
||||
self._assert_scale_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
pre_stack_resource_list, post_stack_resource_list,
|
||||
scale_type='SCALE_OUT', expected_stack_status='CREATE_COMPLETE')
|
||||
scale_type='SCALE_OUT', expected_stack_status='CREATE_COMPLETE',
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Heal vnf (do not specify vnfc_instace_id)
|
||||
# pre check heat status.
|
||||
self.assert_heat_stack_status(vnf_instance_id)
|
||||
# Heal
|
||||
request_body = fake_vnflcm.VnfInstances.make_heal_request_body()
|
||||
resp, _ = self._heal_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 3, # = 2(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 2, # = 2(VDU1)
|
||||
'len_vnfc_info': 3 # = 2(VDU1) + 1(VDU2)
|
||||
}
|
||||
# post check heat status.
|
||||
self.assert_heal_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
expected_stack_status='CREATE_COMPLETE',
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Scale-in vnf instance
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
pre_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
|
||||
request_body = (fake_vnflcm.VnfInstances
|
||||
.make_reverse_scale_request_body('SCALE_IN'))
|
||||
.make_scale_request_body('SCALE_IN'))
|
||||
resp, _ = self._scale_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
|
||||
post_stack_resource_list = self._get_heat_resource_list(stack.id, 2)
|
||||
expected_show_res = {
|
||||
'len_vnfc_res_info': 2, # = 1(VDU1) + 1(VDU2)
|
||||
'len_storage_res_info': 1, # = 1(VDU1)
|
||||
'len_vnfc_info': 2 # = 1(VDU1) + 1(VDU2)
|
||||
}
|
||||
self._assert_scale_vnf(resp, vnf_instance_id, vnf_package_id,
|
||||
pre_stack_resource_list, post_stack_resource_list,
|
||||
scale_type='SCALE_IN', expected_stack_status='UPDATE_COMPLETE')
|
||||
scale_type='SCALE_IN', expected_stack_status='CREATE_COMPLETE',
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
# Terminate VNF
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
@ -2186,25 +2349,20 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
|
||||
vnf_pkg_info,
|
||||
expected_usage_state=fields.PackageUsageStateType.NOT_IN_USE)
|
||||
|
||||
def assert_instantiate_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
vnf_pkg_id):
|
||||
super().assert_instantiate_vnf(resp, vnf_instance_id)
|
||||
def assert_instantiate_vnf(self, resp, vnf_instance_id, vnf_pkg_id,
|
||||
expected_show_res=None):
|
||||
super().assert_instantiate_vnf(resp, vnf_instance_id,
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
resp, vnf_pkg_info = vnflcm_base._show_vnf_package(
|
||||
self.tacker_client, vnf_pkg_id)
|
||||
self.assert_vnf_package_usage_state(vnf_pkg_info)
|
||||
|
||||
def assert_heal_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
vnf_pkg_id,
|
||||
expected_stack_status='UPDATE_COMPLETE'):
|
||||
super().assert_heal_vnf(
|
||||
resp, vnf_instance_id, expected_stack_status=expected_stack_status)
|
||||
def assert_heal_vnf(self, resp, vnf_instance_id, vnf_pkg_id,
|
||||
expected_stack_status='UPDATE_COMPLETE', expected_show_res=None):
|
||||
super().assert_heal_vnf(resp, vnf_instance_id,
|
||||
expected_stack_status=expected_stack_status,
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
resp, vnf_pkg_info = vnflcm_base._show_vnf_package(
|
||||
self.tacker_client, vnf_pkg_id)
|
||||
@ -2235,20 +2393,13 @@ class VnfLcmWithUserDataTest(vnflcm_base.BaseVnfLcmTest):
|
||||
resp, _ = self._show_subscription(sub_id)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def _assert_scale_vnf(
|
||||
self,
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
vnf_pkg_id,
|
||||
pre_stack_resource_list,
|
||||
post_stack_resource_list,
|
||||
scale_type, expected_stack_status):
|
||||
super().assert_scale_vnf(
|
||||
resp,
|
||||
vnf_instance_id,
|
||||
pre_stack_resource_list,
|
||||
post_stack_resource_list,
|
||||
scale_type=scale_type, expected_stack_status=expected_stack_status)
|
||||
def _assert_scale_vnf(self, resp, vnf_instance_id, vnf_pkg_id,
|
||||
pre_stack_resource_list, post_stack_resource_list, scale_type,
|
||||
expected_stack_status, expected_show_res=None):
|
||||
super().assert_scale_vnf(resp, vnf_instance_id,
|
||||
pre_stack_resource_list, post_stack_resource_list,
|
||||
scale_type=scale_type, expected_stack_status=expected_stack_status,
|
||||
expected_show_res=expected_show_res)
|
||||
|
||||
resp, vnf_pkg_info = vnflcm_base._show_vnf_package(
|
||||
self.tacker_client, vnf_pkg_id)
|
||||
|
@ -721,6 +721,667 @@ def get_vnfd_dict(image_path=None):
|
||||
return vnfd_dict
|
||||
|
||||
|
||||
def get_vnfd_dict_for_convert_desired_capacity():
|
||||
vnfd_dict = {
|
||||
'imports': [
|
||||
'etsi_nfv_sol001_common_types.yaml',
|
||||
'etsi_nfv_sol001_vnfd_types.yaml',
|
||||
'helloworld3_types.yaml'
|
||||
],
|
||||
'description': 'Simple deployment flavour for Sample VNF',
|
||||
'topology_template': {
|
||||
'inputs': {
|
||||
'descriptor_id': {
|
||||
'type': 'string'
|
||||
},
|
||||
'flavour_description': {
|
||||
'type': 'string'
|
||||
},
|
||||
'software_version': {
|
||||
'type': 'string'
|
||||
},
|
||||
'flavour_id': {
|
||||
'type': 'string'
|
||||
},
|
||||
'descriptor_version': {
|
||||
'type': 'string'
|
||||
},
|
||||
'provider': {
|
||||
'type': 'string'
|
||||
},
|
||||
'vnfm_info': {
|
||||
'entry_schema': {
|
||||
'type': 'string'
|
||||
},
|
||||
'type': 'list'
|
||||
},
|
||||
'product_name': {
|
||||
'type': 'string'
|
||||
}
|
||||
},
|
||||
'node_templates': {
|
||||
'VDU1': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_storage': 'VirtualStorage'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.Vdu.Compute',
|
||||
'properties': {
|
||||
'vdu_profile': {
|
||||
'max_number_of_instances': 3,
|
||||
'min_number_of_instances': 1
|
||||
},
|
||||
'description': 'VDU1 compute node',
|
||||
'name': 'VDU1'
|
||||
},
|
||||
'capabilities': {
|
||||
'virtual_compute': {
|
||||
'properties': {
|
||||
'requested_additional_capabilities': {
|
||||
'properties': {
|
||||
'requested_additional_capability_name':
|
||||
'm1.tiny',
|
||||
'target_performance_parameters': {
|
||||
'entry_schema': 'test'
|
||||
},
|
||||
'support_mandatory': 'true'
|
||||
}
|
||||
},
|
||||
'virtual_cpu': {
|
||||
'num_virtual_cpu': 1
|
||||
},
|
||||
'virtual_memory': {
|
||||
'virtual_mem_size': '512 MB'
|
||||
},
|
||||
'virtual_local_storage': [
|
||||
{
|
||||
'size_of_storage': '3 GB'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'VirtualStorage': {
|
||||
'type': 'tosca.nodes.nfv.Vdu.VirtualBlockStorage',
|
||||
'properties': {
|
||||
'sw_image_data': {
|
||||
'name': 'cirros-0.5.2-x86_64-disk',
|
||||
'checksum': {
|
||||
'hash': 'fake hash',
|
||||
'algorithm': 'sha-256'
|
||||
},
|
||||
'min_ram': '256 MB',
|
||||
'disk_format': 'qcow2',
|
||||
'version': '0.5.2',
|
||||
'container_format': 'bare',
|
||||
'min_disk': '0 GB',
|
||||
'size': '12 GB'
|
||||
},
|
||||
'virtual_block_storage_data': {
|
||||
'size_of_storage': '1 GB',
|
||||
'rdma_enabled': 'true'
|
||||
}
|
||||
}
|
||||
},
|
||||
'VDU1_CP3': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU1'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL1'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 2
|
||||
}
|
||||
},
|
||||
'VDU2_CP5': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU2'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL3'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 4
|
||||
}
|
||||
},
|
||||
'VDU2_CP4': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU2'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL2'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 3
|
||||
}
|
||||
},
|
||||
'VDU2_CP1': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU2'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 0
|
||||
}
|
||||
},
|
||||
'VDU2_CP3': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU2'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL1'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 2
|
||||
}
|
||||
},
|
||||
'VDU2_CP2': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU2'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 1
|
||||
}
|
||||
},
|
||||
'internalVL1': {
|
||||
'type': 'tosca.nodes.nfv.VnfVirtualLink',
|
||||
'properties': {
|
||||
'connectivity_type': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
]
|
||||
},
|
||||
'vl_profile': {
|
||||
'virtual_link_protocol_data': [
|
||||
{
|
||||
'l3_protocol_data': {
|
||||
'ip_version': 'ipv4',
|
||||
'cidr': '33.33.0.0/24'
|
||||
},
|
||||
'associated_layer_protocol': 'ipv4'
|
||||
}
|
||||
],
|
||||
'min_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
},
|
||||
'max_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'description':
|
||||
'External Managed Virtual link in the VNF'
|
||||
}
|
||||
},
|
||||
'internalVL2': {
|
||||
'type': 'tosca.nodes.nfv.VnfVirtualLink',
|
||||
'properties': {
|
||||
'connectivity_type': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
]
|
||||
},
|
||||
'vl_profile': {
|
||||
'virtual_link_protocol_data': [
|
||||
{
|
||||
'l3_protocol_data': {
|
||||
'ip_version': 'ipv4',
|
||||
'cidr': '33.34.0.0/24'
|
||||
},
|
||||
'associated_layer_protocol': 'ipv4'
|
||||
}
|
||||
],
|
||||
'min_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
},
|
||||
'max_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'description':
|
||||
'External Managed Virtual link in the VNF'
|
||||
}
|
||||
},
|
||||
'VDU1_CP1': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU1'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 0
|
||||
}
|
||||
},
|
||||
'VDU1_CP2': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU1'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 1
|
||||
}
|
||||
},
|
||||
'VNF': {
|
||||
'interfaces': {
|
||||
'Vnflcm': {
|
||||
'instantiate': [],
|
||||
'modify_information_start': [],
|
||||
'modify_information_end': [],
|
||||
'terminate_start': [],
|
||||
'instantiate_start': [],
|
||||
'terminate': [],
|
||||
'instantiate_end': [],
|
||||
'terminate_end': [],
|
||||
'modify_information': []
|
||||
}
|
||||
},
|
||||
'type': 'company.provider.VNF',
|
||||
'properties': {
|
||||
'flavour_description': 'A simple flavour'
|
||||
}
|
||||
},
|
||||
'VDU2': {
|
||||
'type': 'tosca.nodes.nfv.Vdu.Compute',
|
||||
'properties': {
|
||||
'vdu_profile': {
|
||||
'max_number_of_instances': 1,
|
||||
'min_number_of_instances': 1
|
||||
},
|
||||
'description': 'VDU2 compute node',
|
||||
'sw_image_data': {
|
||||
'name': 'cirros-0.5.2-x86_64-disk',
|
||||
'checksum': {
|
||||
'hash': 'fake hash',
|
||||
'algorithm': 'sha-256'
|
||||
},
|
||||
'min_ram': '256 MB',
|
||||
'disk_format': 'qcow2',
|
||||
'version': '0.5.2',
|
||||
'container_format': 'bare',
|
||||
'min_disk': '0 GB',
|
||||
'size': '12 GB'
|
||||
},
|
||||
'name': 'VDU2'
|
||||
},
|
||||
'capabilities': {
|
||||
'virtual_compute': {
|
||||
'properties': {
|
||||
'requested_additional_capabilities': {
|
||||
'properties': {
|
||||
'requested_additional_capability_name':
|
||||
'm1.tiny',
|
||||
'target_performance_parameters': {
|
||||
'entry_schema': 'test'
|
||||
},
|
||||
'support_mandatory': 'true'
|
||||
}
|
||||
},
|
||||
'virtual_cpu': {
|
||||
'num_virtual_cpu': 1
|
||||
},
|
||||
'virtual_memory': {
|
||||
'virtual_mem_size': '512 MB'
|
||||
},
|
||||
'virtual_local_storage': [
|
||||
{
|
||||
'size_of_storage': '3 GB'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'VDU1_CP4': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU1'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL2'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 3
|
||||
}
|
||||
},
|
||||
'VDU1_CP5': {
|
||||
'requirements': [
|
||||
{
|
||||
'virtual_binding': 'VDU1'
|
||||
},
|
||||
{
|
||||
'virtual_link': 'internalVL3'
|
||||
}
|
||||
],
|
||||
'type': 'tosca.nodes.nfv.VduCp',
|
||||
'properties': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
],
|
||||
'order': 4
|
||||
}
|
||||
},
|
||||
'internalVL3': {
|
||||
'type': 'tosca.nodes.nfv.VnfVirtualLink',
|
||||
'properties': {
|
||||
'connectivity_type': {
|
||||
'layer_protocols': [
|
||||
'ipv4'
|
||||
]
|
||||
},
|
||||
'vl_profile': {
|
||||
'virtual_link_protocol_data': [
|
||||
{
|
||||
'l3_protocol_data': {
|
||||
'ip_version': 'ipv4',
|
||||
'cidr': '33.35.0.0/24'
|
||||
},
|
||||
'associated_layer_protocol': 'ipv4'
|
||||
}
|
||||
],
|
||||
'min_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
},
|
||||
'max_bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'description': 'Internal Virtual link in the VNF'
|
||||
}
|
||||
}
|
||||
},
|
||||
'substitution_mappings': {
|
||||
'node_type': 'company.provider.VNF',
|
||||
'properties': {
|
||||
'flavour_id': 'simple'
|
||||
}
|
||||
},
|
||||
'policies': [
|
||||
{
|
||||
'scaling_aspects': {
|
||||
'type': 'tosca.policies.nfv.ScalingAspects',
|
||||
'properties': {
|
||||
'aspects': {
|
||||
'VDU1_scale': {
|
||||
'max_scale_level': 2,
|
||||
'description': 'VDU1 scaling aspect',
|
||||
'name': 'VDU1_scale',
|
||||
'step_deltas': [
|
||||
'delta_1'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'VDU1_initial_delta': {
|
||||
'type': 'tosca.policies.nfv.VduInitialDelta',
|
||||
'properties': {
|
||||
'initial_delta': {
|
||||
'number_of_instances': 1
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'VDU1'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'VDU2_initial_delta': {
|
||||
'type': 'tosca.policies.nfv.VduInitialDelta',
|
||||
'properties': {
|
||||
'initial_delta': {
|
||||
'number_of_instances': 1
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'VDU2'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'VDU1_scaling_aspect_deltas': {
|
||||
'type': 'tosca.policies.nfv.VduScalingAspectDeltas',
|
||||
'properties': {
|
||||
'deltas': {
|
||||
'delta_1': {
|
||||
'number_of_instances': 1
|
||||
}
|
||||
},
|
||||
'aspect': 'VDU1_scale'
|
||||
},
|
||||
'targets': [
|
||||
'VDU1'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'instantiation_levels': {
|
||||
'type': 'tosca.policies.nfv.InstantiationLevels',
|
||||
'properties': {
|
||||
'default_level': 'instantiation_level_1',
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'scale_info': {
|
||||
'VDU1_scale': {
|
||||
'scale_level': 0
|
||||
}
|
||||
},
|
||||
'description': 'Smallest size'
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'scale_info': {
|
||||
'VDU1_scale': {
|
||||
'scale_level': 2
|
||||
}
|
||||
},
|
||||
'description': 'Largest size'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'VDU1_instantiation_levels': {
|
||||
'type': 'tosca.policies.nfv.VduInstantiationLevels',
|
||||
'properties': {
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'number_of_instances': 1
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'number_of_instances': 3
|
||||
}
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'VDU1'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'VDU2_instantiation_levels': {
|
||||
'type': 'tosca.policies.nfv.VduInstantiationLevels',
|
||||
'properties': {
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'number_of_instances': 1
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'number_of_instances': 1
|
||||
}
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'VDU2'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'internalVL1_instantiation_levels': {
|
||||
'type':
|
||||
'tosca.policies.nfv.'
|
||||
'VirtualLinkInstantiationLevels',
|
||||
'properties': {
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'internalVL1'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'internalVL2_instantiation_levels': {
|
||||
'type':
|
||||
'tosca.policies.nfv.'
|
||||
'VirtualLinkInstantiationLevels',
|
||||
'properties': {
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'internalVL2'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'internalVL3_instantiation_levels': {
|
||||
'type':
|
||||
'tosca.policies.nfv.'
|
||||
'VirtualLinkInstantiationLevels',
|
||||
'properties': {
|
||||
'levels': {
|
||||
'instantiation_level_1': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
},
|
||||
'instantiation_level_2': {
|
||||
'bitrate_requirements': {
|
||||
'leaf': 1048576,
|
||||
'root': 1048576
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
'internalVL3'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'policy_antiaffinity_vdu1': {
|
||||
'type': 'tosca.policies.nfv.AntiAffinityRule',
|
||||
'properties': {
|
||||
'scope': 'zone'
|
||||
},
|
||||
'targets': [
|
||||
'VDU1'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'policy_antiaffinity_vdu2': {
|
||||
'type': 'tosca.policies.nfv.AntiAffinityRule',
|
||||
'properties': {
|
||||
'scope': 'zone'
|
||||
},
|
||||
'targets': [
|
||||
'VDU2'
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'tosca_definitions_version': 'tosca_simple_yaml_1_2'
|
||||
}
|
||||
|
||||
return vnfd_dict
|
||||
|
||||
|
||||
def get_dummy_vim_connection_info():
|
||||
return {'access_info': {
|
||||
'auth_url': 'fake/url',
|
||||
|
@ -14,9 +14,11 @@
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import ddt
|
||||
from oslo_config import cfg
|
||||
import yaml
|
||||
|
||||
from tacker.common import exceptions
|
||||
from tacker.objects import fields
|
||||
@ -24,6 +26,7 @@ from tacker.objects.instantiate_vnf_req import InstantiateVnfRequest
|
||||
from tacker.objects.vim_connection import VimConnectionInfo
|
||||
from tacker.tests.unit import base
|
||||
from tacker.tests.unit.vnflcm import fakes
|
||||
from tacker.tests import utils
|
||||
from tacker.tests import uuidsentinel
|
||||
from tacker.vnflcm import utils as vnflcm_utils
|
||||
|
||||
@ -140,3 +143,72 @@ class VnfLcmUtilsTestCase(base.TestCase):
|
||||
'VduInitialDelta parameter from policies '
|
||||
'definition in VNFD.')
|
||||
self.assertEqual(expected_error, str(error))
|
||||
|
||||
def test_convert_desired_capacity_scale_status_none(self):
|
||||
vnfd_dict = fakes.get_vnfd_dict_for_convert_desired_capacity()
|
||||
|
||||
etsi_common_file_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common/Definitions/etsi_nfv_sol001_common_types.yaml')
|
||||
etsi_vnfd_file_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common/Definitions/etsi_nfv_sol001_vnfd_types.yaml')
|
||||
helloworld_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common_artifact/Definitions/helloworld3_types.yaml')
|
||||
|
||||
etsi_common_file_path_tmp = os.path.join(
|
||||
os.path.dirname(__file__), 'etsi_nfv_sol001_common_types.yaml')
|
||||
types_file_path_tmp = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), 'types.yaml'))
|
||||
|
||||
shutil.copy(etsi_common_file_path, etsi_common_file_path_tmp)
|
||||
self.addCleanup(os.remove, etsi_common_file_path_tmp)
|
||||
shutil.copy(helloworld_path, types_file_path_tmp)
|
||||
self.addCleanup(os.remove, types_file_path_tmp)
|
||||
|
||||
with open(types_file_path_tmp) as f:
|
||||
data = yaml.safe_load(f)
|
||||
data['imports'] = [etsi_common_file_path, etsi_vnfd_file_path]
|
||||
with open(types_file_path_tmp, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
vnfd_dict['imports'] = [etsi_common_file_path, etsi_vnfd_file_path,
|
||||
types_file_path_tmp]
|
||||
|
||||
desired_capacity = vnflcm_utils._convert_desired_capacity(
|
||||
'instantiation_level_1', vnfd_dict, 'VDU1')
|
||||
self.assertEqual(desired_capacity, 1)
|
||||
|
||||
def test_convert_desired_capacity_scale_status_specified(self):
|
||||
vnfd_dict = fakes.get_vnfd_dict_for_convert_desired_capacity()
|
||||
|
||||
etsi_common_file_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common/Definitions/etsi_nfv_sol001_common_types.yaml')
|
||||
etsi_vnfd_file_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common/Definitions/etsi_nfv_sol001_vnfd_types.yaml')
|
||||
helloworld_path = utils.test_etc_sample('etsi/nfv',
|
||||
'common_artifact/Definitions/helloworld3_types.yaml')
|
||||
|
||||
etsi_common_file_path_tmp = os.path.join(
|
||||
os.path.dirname(__file__), 'etsi_nfv_sol001_common_types.yaml')
|
||||
types_file_path_tmp = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), 'types.yaml'))
|
||||
|
||||
shutil.copy(etsi_common_file_path, etsi_common_file_path_tmp)
|
||||
self.addCleanup(os.remove, etsi_common_file_path_tmp)
|
||||
shutil.copy(helloworld_path, types_file_path_tmp)
|
||||
self.addCleanup(os.remove, types_file_path_tmp)
|
||||
|
||||
with open(types_file_path_tmp) as f:
|
||||
data = yaml.safe_load(f)
|
||||
data['imports'] = [etsi_common_file_path, etsi_vnfd_file_path]
|
||||
with open(types_file_path_tmp, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
vnfd_dict['imports'] = [etsi_common_file_path, etsi_vnfd_file_path,
|
||||
types_file_path_tmp]
|
||||
|
||||
scale_status = [{'aspect_id': 'VDU1_scale', 'scale_level': 1}]
|
||||
|
||||
desired_capacity = vnflcm_utils._convert_desired_capacity(
|
||||
'instantiation_level_1', vnfd_dict, 'VDU1',
|
||||
scale_status=scale_status)
|
||||
self.assertEqual(desired_capacity, 2)
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import ddt
|
||||
import importlib
|
||||
import json
|
||||
@ -327,6 +328,103 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._create_stack_with_user_data')
|
||||
@mock.patch('tacker.tosca.utils.get_scale_group')
|
||||
@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')
|
||||
def test_create_normal_with_scaling_group_and_scale_status(
|
||||
self, mock_OpenstackClients_heat, mock_get_base_hot_dict,
|
||||
mock_get_vnflcm_interface, mock_format_base_hot,
|
||||
mock_get_scale_group, mock_create_stack_with_user_data):
|
||||
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
|
||||
scaling_group=True, flavour='simple')
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
s_status = {'aspect_id': 'VDU1_scale', 'scale_level': 1}
|
||||
vnf['scale_status'] = [objects.ScaleInfo(**s_status)]
|
||||
vnf_package_path_test = self._nfv_sample(
|
||||
'user_data_sample_normal_scaling')
|
||||
inst_req_info_test = type('', (), {})
|
||||
test_json = self._json_load(
|
||||
'instantiate_vnf_request_lcm_userdata.json')
|
||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||
inst_req_info_test.ext_virtual_links = None
|
||||
inst_req_info_test.flavour_id = 'simple'
|
||||
vnf_resource = type('', (), {})
|
||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||
nested_hot_dict = {'parameters': {'vnf': 'test'}}
|
||||
base_hot_dict = self._read_file(scale_input_file=True)
|
||||
mock_get_base_hot_dict.return_value = (base_hot_dict, nested_hot_dict)
|
||||
mock_get_scale_group.return_value = {
|
||||
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
|
||||
'num': 1, 'maxLevel': 2, 'initialNum': 1,
|
||||
'initialLevel': 0, 'default': 1}}}
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||
vnf_package_path=vnf_package_path_test,
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
self.assertEqual(mock_create_stack_with_user_data.call_count, 1)
|
||||
# Expect desired_capacity in base_hot_dict to be changed
|
||||
# by specified scale_statue
|
||||
(base_hot_dict['resources']['VDU1_scale']['properties']
|
||||
['desired_capacity']) = 2
|
||||
mock_create_stack_with_user_data.assert_called_with(
|
||||
mock.ANY, mock.ANY, base_hot_dict, mock.ANY, mock.ANY
|
||||
)
|
||||
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._create_stack_with_user_data')
|
||||
@mock.patch('tacker.tosca.utils.get_scale_group')
|
||||
@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')
|
||||
def test_create_normal_with_scaling_group_and_not_scale_status(
|
||||
self, mock_OpenstackClients_heat, mock_get_base_hot_dict,
|
||||
mock_get_vnflcm_interface, mock_format_base_hot,
|
||||
mock_get_scale_group, mock_create_stack_with_user_data):
|
||||
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
|
||||
scaling_group=True, flavour='simple')
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
vnf_package_path_test = self._nfv_sample(
|
||||
'user_data_sample_normal_scaling')
|
||||
inst_req_info_test = type('', (), {})
|
||||
test_json = self._json_load(
|
||||
'instantiate_vnf_request_lcm_userdata.json')
|
||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||
inst_req_info_test.ext_virtual_links = None
|
||||
inst_req_info_test.flavour_id = 'simple'
|
||||
vnf_resource = type('', (), {})
|
||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||
nested_hot_dict = {'parameters': {'vnf': 'test'}}
|
||||
base_hot_dict = self._read_file(scale_input_file=True)
|
||||
mock_get_base_hot_dict.return_value = (base_hot_dict, nested_hot_dict)
|
||||
mock_get_scale_group.return_value = {
|
||||
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
|
||||
'num': 1, 'maxLevel': 2, 'initialNum': 1,
|
||||
'initialLevel': 0, 'default': 1}}}
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||
vnf_package_path=vnf_package_path_test,
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
self.assertEqual(mock_create_stack_with_user_data.call_count, 1)
|
||||
# Expect desired_capacity in base_hot_dict to be unchanged
|
||||
mock_create_stack_with_user_data.assert_called_with(
|
||||
mock.ANY, mock.ANY, base_hot_dict, mock.ANY, mock.ANY
|
||||
)
|
||||
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._format_base_hot')
|
||||
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
|
||||
@ -825,30 +923,45 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
|
||||
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
|
||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||
def test_create_heat_stack(self, mock_OpenstackClients_heat):
|
||||
def test_create_heat_stack(self, mock_OpenstackClients_heat,
|
||||
mock_vnfd_dict):
|
||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
vnf_package_path = None
|
||||
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
|
||||
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
inst_req_info = fd_utils.get_instantiate_vnf_request()
|
||||
self.assertIsNone(vnf.get('scale_status', None))
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, vnf_package_path)
|
||||
self.auth_attr, vnf_package_path, inst_req_info=inst_req_info,
|
||||
grant_info=None, vnf_instance=vnf_instance)
|
||||
self.assertIsNotNone(vnf.get('scale_status', None))
|
||||
|
||||
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
|
||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._update_stack')
|
||||
@mock.patch.object(hc.HeatClient, "find_stack")
|
||||
def test_create_heat_stack_with_error_point_post_vim_control(self,
|
||||
mock_find_stack, mock_update_stack,
|
||||
mock_OpenstackClients_heat):
|
||||
mock_OpenstackClients_heat, mock_vnfd_dict):
|
||||
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
vnf_package_path = None
|
||||
vnf['before_error_point'] = fields.ErrorPoint.POST_VIM_CONTROL
|
||||
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
inst_req_info = fd_utils.get_instantiate_vnf_request()
|
||||
self.assertIsNone(vnf.get('scale_status', None))
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, vnf_package_path)
|
||||
self.auth_attr, vnf_package_path, inst_req_info=inst_req_info,
|
||||
grant_info=None, vnf_instance=vnf_instance)
|
||||
mock_find_stack.assert_called_once()
|
||||
mock_update_stack.assert_called_once()
|
||||
self.assertIsNotNone(vnf.get('scale_status', None))
|
||||
|
||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||
def test_create_userdata_none(self, mock_OpenstackClients_heat):
|
||||
@ -1919,11 +2032,12 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
mock_log.info.assert_called()
|
||||
self.assertEqual(delete_image_url.call_count, 2)
|
||||
|
||||
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.translate_template.'
|
||||
'TOSCAToHOT._get_unsupported_resource_props')
|
||||
@mock.patch.object(hc.HeatClient, "find_stack")
|
||||
def test_instantiate_vnf(self, mock_get_unsupported_resource_props,
|
||||
mock_find_stack):
|
||||
mock_find_stack, mock_vnfd_dict):
|
||||
vim_connection_info = fd_utils.get_vim_connection_info_object()
|
||||
inst_req_info = fd_utils.get_instantiate_vnf_request()
|
||||
grant_response = fd_utils.get_grant_response_dict()
|
||||
@ -1939,7 +2053,7 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
'before_error_point': fields.ErrorPoint.PRE_VIM_CONTROL,
|
||||
'status': ''
|
||||
}
|
||||
|
||||
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
|
||||
instance_id = self.openstack.instantiate_vnf(
|
||||
self.context, vnf_instance, vnfd_dict, vim_connection_info,
|
||||
inst_req_info, grant_response, self.plugin)
|
||||
@ -3320,8 +3434,8 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
vnf_virtual_link_resource_info[0].vnf_link_ports[0].
|
||||
resource_handle.resource_id)
|
||||
|
||||
@mock.patch.object(hc.HeatClient, "resource_get")
|
||||
@mock.patch.object(hc.HeatClient, "resource_get_list")
|
||||
@mock.patch.object(hc.HeatClient, 'resource_get')
|
||||
@mock.patch.object(hc.HeatClient, 'resource_get_list')
|
||||
def test_scale_resource_update_scale_out_with_grant(
|
||||
self, mock_list, mock_resource):
|
||||
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
|
||||
@ -3332,11 +3446,11 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
number_of_steps=1)
|
||||
vim_connection_info = fd_utils.get_vim_connection_info_object()
|
||||
vnf_info = {}
|
||||
v_s_resource_info = fd_utils.\
|
||||
get_virtual_storage_resource_info_for_grant(desc_id="storage1")
|
||||
v_s_resource_info = (fd_utils.
|
||||
get_virtual_storage_resource_info_for_grant(desc_id='storage1'))
|
||||
storage_resource_ids = [v_s_resource_info.id]
|
||||
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
|
||||
vdu_id="workerNode", storage_resource_ids=storage_resource_ids)
|
||||
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
|
||||
vnfc_resource_info_list = []
|
||||
vnfc_resource_info_list.append(vnfc_resource_info)
|
||||
virtual_st_rsc_list = []
|
||||
@ -3422,16 +3536,25 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
self.assertEqual(
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
|
||||
uuidsentinel.vnfc_resource_id)
|
||||
return_vnfc_res = \
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0]
|
||||
return_vnfc_res = (
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0])
|
||||
self.assertEqual(return_vnfc_res.vnfc_cp_info[0].id,
|
||||
uuidsentinel.vnfc_cp_info_id)
|
||||
self.assertEqual(uuidsentinel.storage_id_1,
|
||||
vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info[0].id)
|
||||
self.assertEqual(
|
||||
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
|
||||
self.assertEqual(
|
||||
return_vnfc_res.compute_resource.vim_level_resource_type,
|
||||
'OS::Nova::Server')
|
||||
self.assertEqual(
|
||||
(vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info[0].storage_resource.
|
||||
vim_level_resource_type), 'OS::Cinder::Volume')
|
||||
|
||||
@mock.patch.object(hc.HeatClient, "resource_get")
|
||||
@mock.patch.object(hc.HeatClient, "resource_get_list")
|
||||
@mock.patch.object(hc.HeatClient, 'resource_get')
|
||||
@mock.patch.object(hc.HeatClient, 'resource_get_list')
|
||||
def test_scale_resource_update_scale_out(self, mock_list, mock_resource):
|
||||
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
|
||||
vnf_instance = fd_utils.get_vnf_instance_object(
|
||||
@ -3440,11 +3563,11 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
aspect_id='worker_instance',
|
||||
number_of_steps=1)
|
||||
vim_connection_info = fd_utils.get_vim_connection_info_object()
|
||||
v_s_resource_info = fd_utils. \
|
||||
get_virtual_storage_resource_info(desc_id="storage1")
|
||||
v_s_resource_info = (fd_utils.
|
||||
get_virtual_storage_resource_info(desc_id='storage1'))
|
||||
storage_resource_ids = [v_s_resource_info.id]
|
||||
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
|
||||
vdu_id="workerNode", storage_resource_ids=storage_resource_ids)
|
||||
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
|
||||
vnfc_resource_info_list = []
|
||||
vnfc_resource_info_list.append(vnfc_resource_info)
|
||||
virtual_st_rsc_list = []
|
||||
@ -3530,11 +3653,111 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
self.assertNotEqual(
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
|
||||
uuidsentinel.vnfc_resource_id)
|
||||
return_vnfc_res = \
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0]
|
||||
return_vnfc_res = (
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0])
|
||||
self.assertNotEqual(return_vnfc_res.vnfc_cp_info[0].id,
|
||||
uuidsentinel.vnfc_cp_info_id)
|
||||
self.assertNotEqual(uuidsentinel.storage_id,
|
||||
vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info[0].id)
|
||||
self.assertEqual(uuidsentinel.storage_id, v_s_resource_info.id)
|
||||
self.assertEqual(
|
||||
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
|
||||
self.assertEqual(
|
||||
return_vnfc_res.compute_resource.vim_level_resource_type,
|
||||
'OS::Nova::Server')
|
||||
self.assertEqual(
|
||||
(vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info[0].storage_resource.
|
||||
vim_level_resource_type), 'OS::Cinder::Volume')
|
||||
|
||||
@mock.patch.object(hc.HeatClient, 'resource_get_list')
|
||||
def test_scale_resource_update_scale_in(self, mock_list):
|
||||
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
|
||||
vnf_instance = fd_utils.get_vnf_instance_object(
|
||||
instantiated_vnf_info=inst_vnf_info)
|
||||
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_IN',
|
||||
aspect_id='worker_instance',
|
||||
number_of_steps=1)
|
||||
vim_connection_info = fd_utils.get_vim_connection_info_object()
|
||||
vnf_info = {'grant': 'test'}
|
||||
|
||||
# instantiated_vnf_info - virtual_storage_resource_info
|
||||
v_s_resource_info = (fd_utils.
|
||||
get_virtual_storage_resource_info(desc_id='storage1'))
|
||||
v_s_resource_info2 = copy.deepcopy(v_s_resource_info)
|
||||
v_s_resource_info2.id = uuidsentinel.storage_id2
|
||||
v_s_resource_info2.storage_resource.resource_id = (
|
||||
uuidsentinel.storage_id2)
|
||||
vnf_instance.instantiated_vnf_info.virtual_storage_resource_info = [
|
||||
v_s_resource_info, v_s_resource_info2]
|
||||
|
||||
# instantiated_vnf_info - vnfc_resource_info
|
||||
storage_resource_ids = [v_s_resource_info.id]
|
||||
storage_resource_ids2 = [v_s_resource_info2.id]
|
||||
vnfc_resource_info = fd_utils.get_vnfc_resource_info(
|
||||
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
|
||||
vnfc_resource_info2 = fd_utils.get_vnfc_resource_info(
|
||||
vdu_id='workerNode', storage_resource_ids=storage_resource_ids2)
|
||||
vnfc_resource_info2.id = uuidsentinel.vnfc_resource_id2
|
||||
vnfc_resource_info2.compute_resource.resource_id = (
|
||||
uuidsentinel.storage_resource_id2)
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [
|
||||
vnfc_resource_info, vnfc_resource_info2]
|
||||
|
||||
# instantiated_vnf_info - vnfc_info
|
||||
vnfc_info = objects.VnfcInfo(id=uuidsentinel.vnfc_info_id,
|
||||
vdu_id='workerNode', vnfc_state=fields.VnfcState.STARTED)
|
||||
vnfc_info2 = copy.deepcopy(vnfc_info)
|
||||
vnfc_info2.id = uuidsentinel.vnfc_info_id2
|
||||
vnf_instance.instantiated_vnf_info.vnfc_info = [
|
||||
vnfc_info, vnfc_info2]
|
||||
|
||||
# heat resource
|
||||
res_list1 = []
|
||||
resource1 = resources.Resource(None, {
|
||||
'resource_name': 'workerNode',
|
||||
'creation_time': '2020-01-01T00:00:00',
|
||||
'resource_type': 'OS::Nova::Server',
|
||||
'resource_status': 'CREATE_COMPLETE',
|
||||
'physical_resource_id':
|
||||
vnfc_resource_info2.compute_resource.resource_id,
|
||||
'id': '1111'
|
||||
})
|
||||
res_list1.append(resource1)
|
||||
resource2 = resources.Resource(None, {
|
||||
'resource_name': 'storage1',
|
||||
'creation_time': '2020-01-01T00:00:00',
|
||||
'resource_type': 'OS::Cinder::Volume',
|
||||
'resource_status': 'CREATE_COMPLETE',
|
||||
'physical_resource_id':
|
||||
v_s_resource_info2.storage_resource.resource_id,
|
||||
'id': '1111'
|
||||
})
|
||||
res_list1.append(resource2)
|
||||
mock_list.side_effect = [res_list1]
|
||||
|
||||
# execute test target method
|
||||
self.openstack.scale_resource_update(
|
||||
context, vnf_instance,
|
||||
scale_vnf_request, vnf_info,
|
||||
vim_connection_info)
|
||||
|
||||
self.assertEqual(
|
||||
len(vnf_instance.instantiated_vnf_info.vnfc_resource_info), 1)
|
||||
self.assertEqual(
|
||||
(vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].
|
||||
compute_resource.resource_id),
|
||||
vnfc_resource_info2.compute_resource.resource_id)
|
||||
self.assertEqual(
|
||||
len(vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info), 1)
|
||||
self.assertEqual(
|
||||
(vnf_instance.instantiated_vnf_info.
|
||||
virtual_storage_resource_info[0].storage_resource.resource_id),
|
||||
v_s_resource_info2.storage_resource.resource_id)
|
||||
self.assertEqual(
|
||||
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
|
||||
self.assertEqual(
|
||||
vnf_instance.instantiated_vnf_info.vnfc_info[0].id,
|
||||
uuidsentinel.vnfc_info_id2)
|
||||
|
@ -549,15 +549,16 @@ def _get_vim_connection_info_from_vnf_req(vnf_instance, instantiate_vnf_req):
|
||||
|
||||
|
||||
def _build_instantiated_vnf_info(vnfd_dict, instantiate_vnf_req,
|
||||
vnf_instance, vim_id):
|
||||
vnf_instance, vim_id, scale_status=None):
|
||||
inst_vnf_info = vnf_instance.instantiated_vnf_info
|
||||
inst_vnf_info.vnf_state = fields.VnfOperationalStateType.STARTED
|
||||
|
||||
node_templates = vnfd_dict.get(
|
||||
'topology_template', {}).get('node_templates')
|
||||
|
||||
vnfc_resource_info, virtual_storage_resource_info = \
|
||||
_get_vnfc_resource_info(vnfd_dict, instantiate_vnf_req, vim_id)
|
||||
vnfc_resource_info, virtual_storage_resource_info = (
|
||||
_get_vnfc_resource_info(
|
||||
vnfd_dict, instantiate_vnf_req, vim_id, scale_status=scale_status))
|
||||
|
||||
inst_vnf_info.vnfc_resource_info = vnfc_resource_info
|
||||
|
||||
@ -599,7 +600,7 @@ def _update_instantiated_vnf_info(change_ext_conn_req, vnf_instance):
|
||||
vnf_instance.instantiated_vnf_info = inst_vnf_info
|
||||
|
||||
|
||||
def _get_compute_nodes(vnfd_dict, instantiate_vnf_req):
|
||||
def _get_compute_nodes(vnfd_dict, instantiate_vnf_req, scale_status=None):
|
||||
"""Read the node templates and prepare VDU data in below format
|
||||
|
||||
{
|
||||
@ -619,7 +620,8 @@ def _get_compute_nodes(vnfd_dict, instantiate_vnf_req):
|
||||
continue
|
||||
|
||||
desired_capacity = _convert_desired_capacity(
|
||||
instantiate_vnf_req.instantiation_level_id, vnfd_dict, key)
|
||||
instantiate_vnf_req.instantiation_level_id, vnfd_dict, key,
|
||||
scale_status=scale_status)
|
||||
|
||||
cp_list = _get_cp_for_vdu(key, node_templates)
|
||||
|
||||
@ -838,8 +840,10 @@ def _build_virtual_storage_info(virtual_storages):
|
||||
yield virtual_storage
|
||||
|
||||
|
||||
def _get_vnfc_resource_info(vnfd_dict, instantiate_vnf_req, vim_id):
|
||||
vdu_resources = _get_compute_nodes(vnfd_dict, instantiate_vnf_req)
|
||||
def _get_vnfc_resource_info(vnfd_dict, instantiate_vnf_req, vim_id,
|
||||
scale_status=None):
|
||||
vdu_resources = _get_compute_nodes(
|
||||
vnfd_dict, instantiate_vnf_req, scale_status=scale_status)
|
||||
vnfc_resource_info_list = []
|
||||
virtual_storage_resource_info_list = []
|
||||
|
||||
@ -1119,7 +1123,8 @@ def _build_ext_managed_virtual_link_info(instantiate_vnf_req, inst_vnf_info):
|
||||
return ext_managed_virtual_link_info
|
||||
|
||||
|
||||
def _convert_desired_capacity(inst_level_id, vnfd_dict, vdu):
|
||||
def _convert_desired_capacity(
|
||||
inst_level_id, vnfd_dict, vdu, scale_status=None):
|
||||
aspect_delta_dict = {}
|
||||
aspect_vdu_dict = {}
|
||||
inst_level_dict = {}
|
||||
@ -1166,7 +1171,12 @@ def _convert_desired_capacity(inst_level_id, vnfd_dict, vdu):
|
||||
initial_delta = vdu_delta_dict.get(vdu)
|
||||
|
||||
if initial_delta is not None:
|
||||
desired_capacity = initial_delta + delta_num * level_num
|
||||
scale_level = level_num
|
||||
if scale_status is not None:
|
||||
for scale in scale_status:
|
||||
if scale['aspect_id'] == aspect_id:
|
||||
scale_level = scale['scale_level']
|
||||
desired_capacity = initial_delta + delta_num * scale_level
|
||||
|
||||
return desired_capacity
|
||||
|
||||
|
@ -897,7 +897,8 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
|
||||
else:
|
||||
vnflcm_utils._build_instantiated_vnf_info(
|
||||
vnfd_dict, instantiate_vnf_request, vnf_instance,
|
||||
vim_connection_info.vim_id)
|
||||
vim_connection_info.vim_id,
|
||||
scale_status=vnf_dict.get('scale_status', None))
|
||||
|
||||
try:
|
||||
self._instantiate_vnf(context, vnf_instance, vnf_dict,
|
||||
|
@ -52,6 +52,7 @@ from tacker.vnfm.infra_drivers.openstack import update_template as ut
|
||||
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 import utils as user_data_utils
|
||||
from toscaparser import tosca_template
|
||||
|
||||
|
||||
eventlet.monkey_patch(time=True)
|
||||
@ -251,17 +252,34 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
raise vnfm.LCMUserDataFailed(reason=error_reason)
|
||||
|
||||
if scale_dict:
|
||||
scale_status_list = []
|
||||
for name, value in scale_group_dict['scaleGroupDict'].items():
|
||||
key_name = name + '_desired_capacity'
|
||||
if base_hot_dict.get('parameters') and \
|
||||
base_hot_dict['parameters'].get(key_name):
|
||||
hot_param_dict[key_name] = value['default']
|
||||
scale_status = objects.ScaleInfo(
|
||||
aspect_id=name,
|
||||
scale_level=value['initialLevel'])
|
||||
scale_status_list.append(scale_status)
|
||||
vnf['scale_status'] = scale_status_list
|
||||
if vnf.get('scale_status'):
|
||||
# When instantiate by SOL003 heal after scale out,
|
||||
# calculate `desired_capacity` using `scale_level`
|
||||
# in scale_status
|
||||
for name, value in (
|
||||
scale_group_dict['scaleGroupDict'].items()):
|
||||
for scale in vnf.get('scale_status'):
|
||||
if (scale['aspect_id'] == name and
|
||||
name in base_hot_dict.get('resources') and
|
||||
(base_hot_dict['resources'][name]
|
||||
.get('properties').get('desired_capacity'))):
|
||||
dc = (value['initialNum'] +
|
||||
value['num'] * scale['scale_level'])
|
||||
(base_hot_dict['resources'][name]['properties']
|
||||
['desired_capacity']) = dc
|
||||
else:
|
||||
scale_status_list = []
|
||||
for name, value in (
|
||||
scale_group_dict['scaleGroupDict'].items()):
|
||||
key_name = name + '_desired_capacity'
|
||||
if base_hot_dict.get('parameters') and \
|
||||
base_hot_dict['parameters'].get(key_name):
|
||||
hot_param_dict[key_name] = value['default']
|
||||
scale_status = objects.ScaleInfo(
|
||||
aspect_id=name,
|
||||
scale_level=value['initialLevel'])
|
||||
scale_status_list.append(scale_status)
|
||||
vnf['scale_status'] = scale_status_list
|
||||
if vnf.get('grant'):
|
||||
base_hot_dict, nested_hot_dict, hot_param_dict = \
|
||||
self._setup_hot_for_grant_resources(vnf, vnf_instance,
|
||||
@ -306,6 +324,30 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
|
||||
elif user_data_path is None and user_data_class is None:
|
||||
LOG.info('Execute heat-translator and create heat-stack.')
|
||||
|
||||
if not vnf.get('scale_status'):
|
||||
# scale_status is not stored when instantiate operation
|
||||
vnfd = vnflcm_utils.get_vnfd_dict(context,
|
||||
vnf_instance.vnfd_id, inst_req_info.flavour_id)
|
||||
tosca = tosca_template.ToscaTemplate(
|
||||
parsed_params={}, a_file=False, yaml_dict_tpl=vnfd,
|
||||
local_defs=tosca_utils.tosca_tmpl_local_defs())
|
||||
extract_policy_infos = (
|
||||
vnflcm_utils.get_extract_policy_infos(tosca))
|
||||
vnf['scale_status'] = []
|
||||
if inst_req_info.instantiation_level_id:
|
||||
inst_level_id = inst_req_info.instantiation_level_id
|
||||
else:
|
||||
inst_level_id = (
|
||||
extract_policy_infos['default_inst_level_id'])
|
||||
al_dict = (extract_policy_infos['inst_level_dict'].
|
||||
get(inst_level_id))
|
||||
if al_dict:
|
||||
vnf['scale_status'] = [
|
||||
objects.ScaleInfo(
|
||||
aspect_id=aspect_id, scale_level=level_num)
|
||||
for aspect_id, level_num in al_dict.items()]
|
||||
|
||||
tth = translate_template.TOSCAToHOT(vnf, heatclient,
|
||||
inst_req_info, grant_info)
|
||||
tth.generate_hot()
|
||||
@ -1779,8 +1821,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
vim_connection_info.id
|
||||
resource.resource_id =\
|
||||
rsc_info.physical_resource_id
|
||||
resource.vim_level_resource_type = '\
|
||||
OS::Nova::Server'
|
||||
resource.vim_level_resource_type = (
|
||||
'OS::Nova::Server')
|
||||
vnfc_resource_info.compute_resource = resource
|
||||
vnfc_resource_info.metadata.update(
|
||||
{"stack_id":
|
||||
@ -1794,6 +1836,11 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
storage_dict[vol['id']] = \
|
||||
vnfc_resource_info.id
|
||||
vnfc_rscs.append(vnfc_resource_info)
|
||||
vnfc = objects.VnfcInfo(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vdu_id=rsc.resource_name,
|
||||
vnfc_state=fields.VnfcState.STARTED)
|
||||
inst_vnf_info.vnfc_info.append(vnfc)
|
||||
if len(vnfc_rscs) == 0:
|
||||
continue
|
||||
|
||||
@ -1901,8 +1948,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
resource.vim_connection_id =\
|
||||
vim_connection_info.id
|
||||
resource.resource_id = rsc.physical_resource_id
|
||||
resource.vim_level_resource_type = '\
|
||||
OS::Cinder::Volume'
|
||||
resource.vim_level_resource_type = (
|
||||
'OS::Cinder::Volume')
|
||||
virtual_storage_resource_info.\
|
||||
storage_resource = resource
|
||||
inst_vnf_info.virtual_storage_resource_info.\
|
||||
@ -1932,10 +1979,15 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
after_port_list.append(rsc.physical_resource_id)
|
||||
LOG.debug("after_st_list %s", after_st_list)
|
||||
del_index = []
|
||||
del_vdu_id = {}
|
||||
for index, vnfc in enumerate(
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info):
|
||||
if vnfc.compute_resource.resource_id not in after_vnfcs_list:
|
||||
del_index.append(index)
|
||||
if vnfc.vdu_id in del_vdu_id:
|
||||
del_vdu_id[vnfc.vdu_id] += 1
|
||||
else:
|
||||
del_vdu_id[vnfc.vdu_id] = 1
|
||||
for ind in del_index[::-1]:
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info.pop(ind)
|
||||
|
||||
@ -1962,6 +2014,17 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
for ind in del_index[::-1]:
|
||||
vl.vnf_link_ports.pop(ind)
|
||||
|
||||
del_index = []
|
||||
# delete vnfc_info from earliest registerd
|
||||
for index, vnfci in enumerate(
|
||||
vnf_instance.instantiated_vnf_info.vnfc_info):
|
||||
for vdu_id in del_vdu_id:
|
||||
if vnfci.vdu_id == vdu_id and del_vdu_id[vdu_id] > 0:
|
||||
del_index.append(index)
|
||||
del_vdu_id[vdu_id] -= 1
|
||||
for ind in del_index[::-1]:
|
||||
vnf_instance.instantiated_vnf_info.vnfc_info.pop(ind)
|
||||
|
||||
@log.log
|
||||
def scale_in_reverse(self, context, plugin, auth_attr, vnf_info,
|
||||
scale_vnf_request, region_name,
|
||||
|
Reference in New Issue
Block a user