Fix placementConstraints not compliant with SOL003

This patch fixes the following, as placementConstraints
does not comply with the ETSI NFV-SOL003 v3.3.1 in the v2 API.

* Exiting VNFc is not included in the resource attribute
  when scale out operation.
* Elements of placementConstraints are created for the number of
  policies, but policies not related to operation or elements
  with an attribute of resource less than 2 are excluded.

Closes-Bug: #2043351
Change-Id: I586b4a61e4410b494c35cf2f4f10152ff6080ab8
This commit is contained in:
Ken Fujimoto 2023-11-10 08:20:17 +00:00
parent d5f1728078
commit 884fec5660
4 changed files with 57 additions and 14 deletions

View File

@ -387,7 +387,7 @@ class VnfLcmDriverV2(object):
grant_req.addResources = add_reses
# placementConstraints
self._make_placementconstraints(grant_req, vnfd, add_reses)
self._make_placementconstraints(grant_req, vnfd, add_reses, inst)
if req.obj_attr_is_set('additionalParams'):
grant_req.additionalParams = req.additionalParams
@ -724,9 +724,9 @@ class VnfLcmDriverV2(object):
grant_req.addResources = add_reses
# placementConstraints
self._make_placementconstraints(grant_req, vnfd, add_reses)
self._make_placementconstraints(grant_req, vnfd, add_reses, inst)
def _make_placementconstraints(self, grant_req, vnfd, add_reses):
def _make_placementconstraints(self, grant_req, vnfd, add_reses, inst):
affinity_policies = {
'AFFINITY': vnfd.get_affinity_targets(grant_req.flavourId),
'ANTI_AFFINITY': vnfd.get_anti_affinity_targets(
@ -736,14 +736,34 @@ class VnfLcmDriverV2(object):
for key, value in affinity_policies.items():
for targets, scope in value:
res_refs = []
for target in targets:
for res in add_reses:
if res.resourceTemplateId == target:
for res in add_reses:
if res.resourceTemplateId in targets:
res_ref = objects.ConstraintResourceRefV1(
idType='GRANT',
resourceId=res.id)
res_refs.append(res_ref)
if not res_refs:
break
if (inst.obj_attr_is_set('instantiatedVnfInfo') and
inst.instantiatedVnfInfo.obj_attr_is_set(
'vnfcResourceInfo')):
for vnfc in inst.instantiatedVnfInfo.vnfcResourceInfo:
if vnfc.vduId in targets:
res_ref = objects.ConstraintResourceRefV1(
idType='GRANT',
resourceId=res.id)
idType='RES_MGMT',
resourceId=vnfc.computeResource.resourceId,
vimConnectionId=(
vnfc.computeResource.vimConnectionId))
res_refs.append(res_ref)
# NOTE: It is meaningless if the target resource is less
# than 2, because it is intended to show the relationship
# between the resources.
if len(res_refs) < 2:
break
plc_const = objects.PlacementConstraintV1(
affinityOrAntiAffinity=key,
scope=scope.upper(),

View File

@ -140,9 +140,9 @@ class TestVnfd(base.BaseTestCase):
result = self.vnfd_1.get_placement_groups(SAMPLE_FLAVOUR_ID)
self.assertEqual(expected_result, result)
def test_get_tartget(self):
def test_get_target(self):
result = self.vnfd_1.get_affinity_targets(SAMPLE_FLAVOUR_ID)
self.assertEqual([], result)
self.assertEqual([(['VDU2'], 'zone')], result)
expected_result = [(['VDU1', 'VDU2'], 'nfvi_node')]
result = self.vnfd_1.get_anti_affinity_targets(SAMPLE_FLAVOUR_ID)

View File

@ -378,7 +378,7 @@ _inst_info_example = {
"id": "vnfc_res_info_id_VDU2",
"vduId": "VDU2",
"computeResource": {
# "vimConnectionId": omitted
"vimConnectionId": "vim1",
"resourceId": "res_id_VDU2",
"vimLevelResourceType": "OS::Nova::Server"
},
@ -419,7 +419,7 @@ _inst_info_example = {
"id": "vnfc_res_info_id_VDU1_1",
"vduId": "VDU1",
"computeResource": {
# "vimConnectionId": omitted
"vimConnectionId": "vim1",
"resourceId": "res_id_VDU1_1",
"vimLevelResourceType": "OS::Nova::Server"
},
@ -456,7 +456,7 @@ _inst_info_example = {
"id": "vnfc_res_info_id_VDU1_2",
"vduId": "VDU1",
"computeResource": {
# "vimConnectionId": omitted
"vimConnectionId": "vim1",
"resourceId": "res_id_VDU1_2",
"vimLevelResourceType": "OS::Nova::Server"
},
@ -494,7 +494,7 @@ _inst_info_example = {
"id": "vnfc_res_no_cp_info",
"vduId": "VDU1",
"computeResource": {
# "vimConnectionId": omitted
"vimConnectionId": "vim1",
"resourceId": "res_id_VDU1_3",
"vimLevelResourceType": "OS::Nova::Server"
}
@ -622,6 +622,12 @@ _inst_info_example = {
"vduId": "VDU1",
"vnfcResourceInfoId": "vnfc_res_info_id_VDU1_2",
"vnfcState": "STARTED"
},
{
"id": "VDU1-vnfc_res_no_cp_info",
"vduId": "VDU1",
"vnfcResourceInfoId": "vnfc_res_no_cp_info",
"vnfcState": "STARTED"
}
]
}
@ -1095,6 +1101,16 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
for def_id in vdu_def_ids:
expected_placement_constraints[0]['resource'].append(
{'idType': 'GRANT', 'resourceId': def_id})
expected_placement_constraints[0]['resource'].extend([
{'idType': 'RES_MGMT', 'resourceId': 'res_id_VDU2',
'vimConnectionId': 'vim1'},
{'idType': 'RES_MGMT', 'resourceId': 'res_id_VDU1_1',
'vimConnectionId': 'vim1'},
{'idType': 'RES_MGMT', 'resourceId': 'res_id_VDU1_2',
'vimConnectionId': 'vim1'},
{'idType': 'RES_MGMT', 'resourceId': 'res_id_VDU1_3',
'vimConnectionId': 'vim1'}
])
self.assertEqual(expected_placement_constraints,
grant_req['placementConstraints'])

View File

@ -424,3 +424,10 @@ topology_template:
targets: [ affinityOrAntiAffinityGroup1 ]
properties:
scope: nfvi_node
# Definision for grant_req.placementConstraints test
- policy_affinity_group:
type: tosca.policies.nfv.AffinityRule
targets: [ VDU2 ]
properties:
scope: zone