Improve Unit Test for V2 API
In the existing v2 unit test, there are many public methods that are not tested. This led to bugs in some code and also increased rework in FT. This patch adds tests to some public methods and improves some existing tests. Also fixed several minor issues checked out in UT. Change-Id: I15b45d99646babbb57606dbb46aa156aa9dfb51c
This commit is contained in:
parent
fec4f537fb
commit
1d9321498f
|
@ -171,7 +171,7 @@ def match_inst_subsc_filter(inst_filter, inst):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if inst_filter.obj_attr_is_set('vnfInstanceNames'):
|
if inst_filter.obj_attr_is_set('vnfInstanceNames'):
|
||||||
if inst.vnfInstanceNames not in inst_filter.vnfInstanceNames:
|
if inst.vnfInstanceName not in inst_filter.vnfInstanceNames:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -77,7 +77,10 @@ class Vnfd(object):
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self.csar_dir_is_tmp:
|
if self.csar_dir_is_tmp:
|
||||||
shutil.rmtree(self.csar_dir)
|
try:
|
||||||
|
shutil.rmtree(self.csar_dir)
|
||||||
|
except Exception:
|
||||||
|
LOG.exception("rmtree %s failed", self.csar_dir)
|
||||||
|
|
||||||
def get_vnfd_flavour(self, flavour_id):
|
def get_vnfd_flavour(self, flavour_id):
|
||||||
if flavour_id in self.vnfd_flavours:
|
if flavour_id in self.vnfd_flavours:
|
||||||
|
@ -336,6 +339,8 @@ class Vnfd(object):
|
||||||
|
|
||||||
def get_interface_script(self, flavour_id, operation):
|
def get_interface_script(self, flavour_id, operation):
|
||||||
vnfd = self.get_vnfd_flavour(flavour_id)
|
vnfd = self.get_vnfd_flavour(flavour_id)
|
||||||
|
if not vnfd:
|
||||||
|
return
|
||||||
nodes = (vnfd.get('topology_template', {})
|
nodes = (vnfd.get('topology_template', {})
|
||||||
.get('node_templates', {}))
|
.get('node_templates', {}))
|
||||||
for node in nodes.values():
|
for node in nodes.values():
|
||||||
|
|
|
@ -39,7 +39,9 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
|
|
||||||
expected_result = {
|
expected_result = {
|
||||||
'VDU': {
|
'VDU': {
|
||||||
'VDU1': {'computeFlavourId': None},
|
'VDU1': {'computeFlavourId': None,
|
||||||
|
'desired_capacity': None,
|
||||||
|
'locationConstraints': None},
|
||||||
'VirtualStorage': {'vcImageId': None},
|
'VirtualStorage': {'vcImageId': None},
|
||||||
'VDU2': {'computeFlavourId': None, 'vcImageId': None}
|
'VDU2': {'computeFlavourId': None, 'vcImageId': None}
|
||||||
},
|
},
|
||||||
|
@ -56,6 +58,9 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
}
|
}
|
||||||
result = common_script_utils.init_nfv_dict(top_hot)
|
result = common_script_utils.init_nfv_dict(top_hot)
|
||||||
self.assertEqual(expected_result, result)
|
self.assertEqual(expected_result, result)
|
||||||
|
self.assertIsNone(result['CP'].get('VDU1_CP6'))
|
||||||
|
self.assertIsNone(result['CP'].get('VDU1_CP7'))
|
||||||
|
self.assertIsNone(result['CP'].get('VDU1_CP8'))
|
||||||
|
|
||||||
def test_get_param_flavor(self):
|
def test_get_param_flavor(self):
|
||||||
flavor = 'm1.large'
|
flavor = 'm1.large'
|
||||||
|
@ -79,6 +84,24 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
self.vnfd_1, grant)
|
self.vnfd_1, grant)
|
||||||
self.assertEqual('m1.tiny', result)
|
self.assertEqual('m1.tiny', result)
|
||||||
|
|
||||||
|
def test_get_param_flavor_no_compute_resource_flavours(self):
|
||||||
|
grant = {
|
||||||
|
'vimAssets': {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# if not exist in grant, get from VNFD
|
||||||
|
result = common_script_utils.get_param_flavor(
|
||||||
|
'VDU1', SAMPLE_FLAVOUR_ID,
|
||||||
|
self.vnfd_1, grant)
|
||||||
|
self.assertEqual('m1.tiny', result)
|
||||||
|
|
||||||
|
# if not exist in grant, get from VNFD
|
||||||
|
result = common_script_utils.get_param_flavor(
|
||||||
|
'VDU2', SAMPLE_FLAVOUR_ID,
|
||||||
|
self.vnfd_1, grant)
|
||||||
|
self.assertEqual('m1.tiny', result)
|
||||||
|
|
||||||
def test_get_param_image(self):
|
def test_get_param_image(self):
|
||||||
image_id = 'f30e149d-b3c7-497a-8b19-a092bc81e47b'
|
image_id = 'f30e149d-b3c7-497a-8b19-a092bc81e47b'
|
||||||
grant = {
|
grant = {
|
||||||
|
@ -96,6 +119,33 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
self.vnfd_1, grant)
|
self.vnfd_1, grant)
|
||||||
self.assertEqual(image_id, result)
|
self.assertEqual(image_id, result)
|
||||||
|
|
||||||
|
def test_get_param_image_no_software_images(self):
|
||||||
|
grant = {
|
||||||
|
'vimAssets': {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = common_script_utils.get_param_image('VDU2', SAMPLE_FLAVOUR_ID,
|
||||||
|
self.vnfd_1, grant)
|
||||||
|
self.assertEqual('VDU2-image', result)
|
||||||
|
|
||||||
|
def test_get_param_image_no_match_image(self):
|
||||||
|
image_id = 'f30e149d-b3c7-497a-8b19-a092bc81e47b'
|
||||||
|
grant = {
|
||||||
|
'vimAssets': {
|
||||||
|
'softwareImages': [
|
||||||
|
{'vnfdSoftwareImageId': 'VDU3',
|
||||||
|
'vimSoftwareImageId': image_id},
|
||||||
|
{'vnfdSoftwareImageId': 'VirtualStorage',
|
||||||
|
'vimSoftwareImageId': 'image-1.0.0-x86_64-disk'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = common_script_utils.get_param_image('VDU2', SAMPLE_FLAVOUR_ID,
|
||||||
|
self.vnfd_1, grant)
|
||||||
|
self.assertEqual('VDU2-image', result)
|
||||||
|
|
||||||
def test_get_param_zone(self):
|
def test_get_param_zone(self):
|
||||||
grant_req = {
|
grant_req = {
|
||||||
'addResources': [
|
'addResources': [
|
||||||
|
@ -118,6 +168,75 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
result = common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
result = common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
||||||
self.assertEqual('nova', result)
|
self.assertEqual('nova', result)
|
||||||
|
|
||||||
|
def test_get_param_zone_no_zones(self):
|
||||||
|
grant_req = {
|
||||||
|
'addResources': [
|
||||||
|
{'id': 'dd60c89a-29a2-43bc-8cff-a534515523df',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU1'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
grant = {
|
||||||
|
'addResources': [
|
||||||
|
{'resourceDefinitionId':
|
||||||
|
'dd60c89a-29a2-43bc-8cff-a534515523df',
|
||||||
|
'zoneId': '717f6ae9-3094-46b6-b070-89ede8337571'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
||||||
|
|
||||||
|
def test_get_param_zone_no_add_resources(self):
|
||||||
|
grant_req = {
|
||||||
|
'addResources': [
|
||||||
|
{'id': 'dd60c89a-29a2-43bc-8cff-a534515523df',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU1'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
grant = {
|
||||||
|
'zones': [
|
||||||
|
{'id': '717f6ae9-3094-46b6-b070-89ede8337571',
|
||||||
|
'zoneId': 'nova'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
||||||
|
|
||||||
|
def test_get_param_zone_no_zone_id(self):
|
||||||
|
grant_req = {
|
||||||
|
'addResources': [
|
||||||
|
{'id': 'dd60c89a-29a2-43bc-8cff-a534515523df',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU1'},
|
||||||
|
{'id': 'e3ac628c-29a4-2878-b4a2-29aa685dcd70',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU1'},
|
||||||
|
{'id': '36628ed5-6821-6f55-8c99-cbab0890fc71',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU2'},
|
||||||
|
{'id': 'eed6860c-e9b2-ef79-5deb-89dee39785ec',
|
||||||
|
'type': 'COMPUTE', 'resourceTemplateId': 'VDU3'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
grant = {
|
||||||
|
'zones': [
|
||||||
|
{'id': '717f6ae9-3094-46b6-b070-89ede8337571',
|
||||||
|
'zoneId': 'nova'}
|
||||||
|
],
|
||||||
|
'addResources': [
|
||||||
|
{'resourceDefinitionId': 'eed6860c-e9b2-'
|
||||||
|
'ef79-5deb-89dee39785ec'},
|
||||||
|
{'resourceDefinitionId': 'e3ac628c-29a4-'
|
||||||
|
'2878-b4a2-29aa685dcd70',
|
||||||
|
'zoneId': '99171a93-d0b2-d2cd-83c1-b0694a3f771b'},
|
||||||
|
{'resourceDefinitionId': '36628ed5-6821-'
|
||||||
|
'6f55-8c99-cbab0890fc71',
|
||||||
|
'zoneId': '717f6ae9-3094-46b6-b070-89ede8337571'},
|
||||||
|
{'resourceDefinitionId': 'dd60c89a-29a2-'
|
||||||
|
'43bc-8cff-a534515523df',
|
||||||
|
'zoneId': '717f6ae9-3094-46b6-b070-89ede8337571'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
result = common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
||||||
|
self.assertEqual('nova', result)
|
||||||
|
|
||||||
def test_get_param_capacity(self):
|
def test_get_param_capacity(self):
|
||||||
# test get_current_capacity at the same time
|
# test get_current_capacity at the same time
|
||||||
grant_req = {
|
grant_req = {
|
||||||
|
@ -214,6 +333,81 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
||||||
result = common_script_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
result = common_script_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
||||||
self.assertEqual(expected_result, result)
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
|
def test_get_param_fixed_ips_other_cases(self):
|
||||||
|
ip_address = "10.10.1.101"
|
||||||
|
subnet_id = "9defebca-3e9c-4bd2-9fa0-c4210c56ece6"
|
||||||
|
ext_cp = {
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
ip_address
|
||||||
|
],
|
||||||
|
"subnetId": subnet_id
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"VDU2_CP2_2": {
|
||||||
|
},
|
||||||
|
"VDU2_CP2_3": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"VDU2_CP2_4": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"VDU2_CP2_5": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req = {
|
||||||
|
"extVirtualLinks": [
|
||||||
|
{
|
||||||
|
"id": "8b49f4b6-1ff9-4a03-99cf-ff445b788436",
|
||||||
|
"resourceId": "4c54f742-5f1d-4287-bb81-37bf2e6ddc3e",
|
||||||
|
"extCps": [ext_cp]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
expected_result = [{'ip_address': ip_address, 'subnet': subnet_id}]
|
||||||
|
|
||||||
|
# no vls
|
||||||
|
common_script_utils.get_param_fixed_ips('VDU2_CP2', {}, {})
|
||||||
|
# with other cases
|
||||||
|
result = common_script_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
||||||
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
def _inst_example_get_network_fixed_ips_from_inst(self):
|
def _inst_example_get_network_fixed_ips_from_inst(self):
|
||||||
ext_cp = {
|
ext_cp = {
|
||||||
"cpdId": "VDU2_CP2",
|
"cpdId": "VDU2_CP2",
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
from tacker import context
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
from tacker.sol_refactored.common import lcm_op_occ_utils as lcmocc_utils
|
from tacker.sol_refactored.common import lcm_op_occ_utils as lcmocc_utils
|
||||||
from tacker.sol_refactored import objects
|
from tacker.sol_refactored import objects
|
||||||
from tacker.sol_refactored.objects.v2 import fields
|
from tacker.sol_refactored.objects.v2 import fields
|
||||||
|
@ -2108,6 +2110,31 @@ _expected_resource_changes_change_vnfpkg = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# lcmocc_info_example
|
||||||
|
_error = {
|
||||||
|
'status': 1,
|
||||||
|
'detail': 'error'
|
||||||
|
}
|
||||||
|
_lcmocc_modify_value = {
|
||||||
|
'id': 'test-1',
|
||||||
|
'vnfInstanceId': 'instance-1',
|
||||||
|
'operation': 'MODIFY_INFO',
|
||||||
|
'operationState': 'PROCESSING',
|
||||||
|
'isAutomaticInvocation': False,
|
||||||
|
'startTime': '2021-01-22 13:41:03+00:00'
|
||||||
|
}
|
||||||
|
_lcmocc_inst_value = {
|
||||||
|
'id': 'test-2',
|
||||||
|
'vnfInstanceId': 'instance-2',
|
||||||
|
'operation': 'INSTANTIATE',
|
||||||
|
'operationState': 'COMPLETED',
|
||||||
|
'isAutomaticInvocation': False,
|
||||||
|
'startTime': '2021-01-23 13:41:03+00:00',
|
||||||
|
'resourceChanges': _expected_resource_changes_instantiate,
|
||||||
|
'changedInfo': _expected_changedInfo
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestLcmOpOccUtils(base.BaseTestCase):
|
class TestLcmOpOccUtils(base.BaseTestCase):
|
||||||
|
|
||||||
|
@ -2312,3 +2339,149 @@ class TestLcmOpOccUtils(base.BaseTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_expected_resource_changes_change_vnfpkg,
|
_expected_resource_changes_change_vnfpkg,
|
||||||
self._sort_resource_changes(lcmocc['resourceChanges']))
|
self._sort_resource_changes(lcmocc['resourceChanges']))
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_lcmocc(self, mock_lcmocc):
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
operation='INSTANTIATE')
|
||||||
|
expected_result = objects.VnfLcmOpOccV2(
|
||||||
|
operation='INSTANTIATE')
|
||||||
|
|
||||||
|
result = lcmocc_utils.get_lcmocc(context, 'lcmocc_id')
|
||||||
|
self.assertEqual(expected_result.operation, result.operation)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_lcmocc_error(self, mock_lcmocc):
|
||||||
|
mock_lcmocc.return_value = None
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfLcmOpOccNotFound,
|
||||||
|
lcmocc_utils.get_lcmocc, context, 'lcmocc_id')
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_lcmocc_all(self, mock_lcmocc):
|
||||||
|
mock_lcmocc.return_value = [objects.VnfLcmOpOccV2(
|
||||||
|
operation='INSTANTIATE')]
|
||||||
|
expected_result = [objects.VnfLcmOpOccV2(
|
||||||
|
operation='INSTANTIATE')]
|
||||||
|
|
||||||
|
result = lcmocc_utils.get_lcmocc_all(context)
|
||||||
|
self.assertEqual(expected_result[0].operation, result[0].operation)
|
||||||
|
|
||||||
|
def test_make_lcmocc_links(self):
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(
|
||||||
|
id='test-1', vnfInstanceId='instance-1', operation='INSTANTIATE')
|
||||||
|
endpoint = 'http://127.0.0.1:9890'
|
||||||
|
|
||||||
|
expected_result = objects.VnfLcmOpOccV2_Links()
|
||||||
|
expected_result.self = objects.Link(
|
||||||
|
href=f'{endpoint}/vnflcm/v2/vnf_lcm_op_occs/{lcmocc.id}')
|
||||||
|
expected_result.vnfInstance = objects.Link(
|
||||||
|
href=f'{endpoint}/vnflcm/v2/vnf_instances/{lcmocc.vnfInstanceId}')
|
||||||
|
expected_result.retry = objects.Link(
|
||||||
|
href=f'{endpoint}/vnflcm/v2/vnf_lcm_op_occs/{lcmocc.id}/retry')
|
||||||
|
expected_result.rollback = objects.Link(
|
||||||
|
href=f'{endpoint}/vnflcm/v2/vnf_lcm_op_occs/{lcmocc.id}/rollback')
|
||||||
|
expected_result.fail = objects.Link(
|
||||||
|
href=f'{endpoint}/vnflcm/v2/vnf_lcm_op_occs/{lcmocc.id}/fail')
|
||||||
|
|
||||||
|
result = lcmocc_utils.make_lcmocc_links(lcmocc, endpoint)
|
||||||
|
self.assertEqual(expected_result.self.href, result.self.href)
|
||||||
|
self.assertEqual(expected_result.vnfInstance.href,
|
||||||
|
result.vnfInstance.href)
|
||||||
|
self.assertEqual(expected_result.retry.href, result.retry.href)
|
||||||
|
self.assertEqual(expected_result.rollback.href, result.rollback.href)
|
||||||
|
self.assertEqual(expected_result.fail.href, result.fail.href)
|
||||||
|
|
||||||
|
def test_make_lcmocc_notif_data(self):
|
||||||
|
subsc_modify = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT')
|
||||||
|
subsc_inst = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='FULL')
|
||||||
|
lcmocc_modify = objects.VnfLcmOpOccV2.from_dict(_lcmocc_modify_value)
|
||||||
|
lcmocc_modify.error = objects.ProblemDetails.from_dict(_error)
|
||||||
|
lcmocc_inst = objects.VnfLcmOpOccV2.from_dict(_lcmocc_inst_value)
|
||||||
|
endpoint = 'http://127.0.0.1:9890'
|
||||||
|
|
||||||
|
# execute modify lcmocc
|
||||||
|
modify_result = lcmocc_utils.make_lcmocc_notif_data(
|
||||||
|
subsc_modify, lcmocc_modify, endpoint)
|
||||||
|
# execute inst lcmocc
|
||||||
|
inst_result = lcmocc_utils.make_lcmocc_notif_data(
|
||||||
|
subsc_inst, lcmocc_inst, endpoint)
|
||||||
|
|
||||||
|
self.assertEqual('START', modify_result.notificationStatus)
|
||||||
|
self.assertEqual('error', modify_result.error.detail)
|
||||||
|
self.assertIsNotNone(inst_result.affectedVnfcs)
|
||||||
|
self.assertIsNotNone(inst_result.changedInfo)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_filter')
|
||||||
|
def test_get_inst_lcmocc(self, mock_value):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
value_1 = {
|
||||||
|
'id': 'test-1',
|
||||||
|
'vnfInstanceId': 'instance-1',
|
||||||
|
'operation': 'INSTANTIATE',
|
||||||
|
'operationState': 'COMPLETED',
|
||||||
|
'startTime': '2021-01-22 13:41:03+00:00'
|
||||||
|
}
|
||||||
|
value_2 = {
|
||||||
|
'id': 'test-2',
|
||||||
|
'vnfInstanceId': 'instance-2',
|
||||||
|
'operation': 'INSTANTIATE',
|
||||||
|
'operationState': 'COMPLETED',
|
||||||
|
'startTime': '2021-01-23 13:41:03+00:00'
|
||||||
|
}
|
||||||
|
mock_value.return_value = [
|
||||||
|
objects.VnfLcmOpOccV2.from_dict(value_1),
|
||||||
|
objects.VnfLcmOpOccV2.from_dict(value_2)
|
||||||
|
]
|
||||||
|
expected_result = objects.VnfLcmOpOccV2.from_dict(value_2)
|
||||||
|
result = lcmocc_utils.get_inst_lcmocc(context, inst)
|
||||||
|
self.assertEqual(expected_result.id, result.id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_filter')
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_grant_req_and_grant(self, mock_grant, mock_grant_reqs):
|
||||||
|
lcmocc_modify = objects.VnfLcmOpOccV2.from_dict(_lcmocc_modify_value)
|
||||||
|
lcmocc_inst = objects.VnfLcmOpOccV2.from_dict(_lcmocc_inst_value)
|
||||||
|
|
||||||
|
# execute modify lcmocc
|
||||||
|
modify_grant_req, modify_grant = lcmocc_utils.get_grant_req_and_grant(
|
||||||
|
context, lcmocc_modify)
|
||||||
|
self.assertIsNone(modify_grant_req)
|
||||||
|
self.assertIsNone(modify_grant)
|
||||||
|
|
||||||
|
# execute inst lcmocc
|
||||||
|
lcmocc_inst.grantId = 'grant-1'
|
||||||
|
mock_grant_reqs.return_value = [objects.GrantRequestV1(
|
||||||
|
vnfInstanceId='inst-1', vnfLcmOpOccId='lcmocc-1',
|
||||||
|
vnfdId='vnfd-1', operation='INSTANTIATE',
|
||||||
|
isAutomaticInvocation=False)]
|
||||||
|
mock_grant.return_value = objects.GrantV1(
|
||||||
|
id='grant-1', vnfInstanceId='inst-1', vnfLcmOpOccId='lcmocc-1')
|
||||||
|
inst_grant_req, inst_grant = lcmocc_utils.get_grant_req_and_grant(
|
||||||
|
context, lcmocc_inst)
|
||||||
|
self.assertEqual('inst-1', inst_grant_req.vnfInstanceId)
|
||||||
|
self.assertEqual('grant-1', inst_grant.id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject,
|
||||||
|
'get_by_filter')
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_grant_req_and_grant_error(self, mock_grant_reqs, mock_grant):
|
||||||
|
lcmocc_modify = objects.VnfLcmOpOccV2.from_dict(_lcmocc_modify_value)
|
||||||
|
lcmocc_inst = objects.VnfLcmOpOccV2.from_dict(_lcmocc_inst_value)
|
||||||
|
|
||||||
|
# execute modify lcmocc
|
||||||
|
modify_grant_req, modify_grant = lcmocc_utils.get_grant_req_and_grant(
|
||||||
|
context, lcmocc_modify)
|
||||||
|
self.assertIsNone(modify_grant_req)
|
||||||
|
self.assertIsNone(modify_grant)
|
||||||
|
|
||||||
|
# execute inst lcmocc
|
||||||
|
lcmocc_inst.grantId = 'grant-1'
|
||||||
|
mock_grant_reqs.return_value = None
|
||||||
|
mock_grant.return_value = objects.GrantV1(
|
||||||
|
id='grant-1', vnfInstanceId='inst-1', vnfLcmOpOccId='lcmocc-1')
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.GrantRequestOrGrantNotFound,
|
||||||
|
lcmocc_utils.get_grant_req_and_grant, context, lcmocc_inst)
|
||||||
|
|
|
@ -0,0 +1,383 @@
|
||||||
|
# Copyright (C) 2022 FUJITSU
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import requests
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.api import api_version
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
|
from tacker.sol_refactored.common import http_client
|
||||||
|
from tacker.sol_refactored.common import subscription_utils as subsc_utils
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
|
from tacker.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestSubscriptionUtils(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSubscriptionUtils, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
self.context.api_version = api_version.APIVersion('2.0.0')
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_subsc(self, mock_subsc):
|
||||||
|
mock_subsc.return_value = objects.LccnSubscriptionV2(id='subsc-1')
|
||||||
|
|
||||||
|
result = subsc_utils.get_subsc(context, 'subsc-1')
|
||||||
|
self.assertEqual('subsc-1', result.id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_subsc_error(self, mock_subsc):
|
||||||
|
mock_subsc.return_value = None
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.LccnSubscriptionNotFound,
|
||||||
|
subsc_utils.get_subsc, context, 'subsc-1')
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_subsc_all(self, mock_subsc):
|
||||||
|
mock_subsc.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
|
||||||
|
result = subsc_utils.get_subsc_all(context)
|
||||||
|
self.assertEqual('subsc-1', result[0].id)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_send_notification(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
notif_data_no_auth = objects.VnfLcmOperationOccurrenceNotificationV2(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
resp_no_auth = requests.Response()
|
||||||
|
resp_no_auth.status_code = 204
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
subsc_utils.send_notification(subsc_no_auth, notif_data_no_auth)
|
||||||
|
|
||||||
|
subsc_basic_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-2', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback',
|
||||||
|
authentication=objects.SubscriptionAuthentication(
|
||||||
|
paramsBasic=objects.SubscriptionAuthentication_ParamsBasic(
|
||||||
|
userName='test', password='test')))
|
||||||
|
|
||||||
|
# execute basic_auth
|
||||||
|
subsc_utils.send_notification(subsc_basic_auth, notif_data_no_auth)
|
||||||
|
|
||||||
|
subsc_oauth2 = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-3', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback',
|
||||||
|
authentication=objects.SubscriptionAuthentication(
|
||||||
|
paramsOauth2ClientCredentials=(
|
||||||
|
objects.SubscriptionAuthentication_ParamsOauth2(
|
||||||
|
clientId='test', clientPassword='test',
|
||||||
|
tokenEndpoint='http://127.0.0.1/token'))))
|
||||||
|
|
||||||
|
# execute oauth2
|
||||||
|
subsc_utils.send_notification(subsc_oauth2, notif_data_no_auth)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_send_notification_error_code(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
notif_data_no_auth = objects.VnfLcmOperationOccurrenceNotificationV2(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
resp_no_auth = requests.Response()
|
||||||
|
resp_no_auth.status_code = 200
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
subsc_utils.send_notification(subsc_no_auth, notif_data_no_auth)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_send_notification_error(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
notif_data_no_auth = objects.VnfLcmOperationOccurrenceNotificationV2(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
resp_no_auth = Exception()
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
subsc_utils.send_notification(subsc_no_auth, notif_data_no_auth)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_test_notification(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
|
||||||
|
resp_no_auth = requests.Response()
|
||||||
|
resp_no_auth.status_code = 204
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
subsc_utils.test_notification(subsc_no_auth)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_test_notification_error_code(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
resp_no_auth = requests.Response()
|
||||||
|
resp_no_auth.status_code = 200
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
self.assertRaises(sol_ex.TestNotificationFailed,
|
||||||
|
subsc_utils.test_notification, subsc_no_auth)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_test_notification_error(self, mock_resp):
|
||||||
|
subsc_no_auth = objects.LccnSubscriptionV2(
|
||||||
|
id='sub-1', verbosity='SHORT',
|
||||||
|
callbackUri='http://127.0.0.1/callback')
|
||||||
|
resp_no_auth = Exception()
|
||||||
|
mock_resp.return_value = (resp_no_auth, None)
|
||||||
|
|
||||||
|
# execute no_auth
|
||||||
|
self.assertRaises(sol_ex.TestNotificationFailed,
|
||||||
|
subsc_utils.test_notification, subsc_no_auth)
|
||||||
|
|
||||||
|
def test_match_version(self):
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
id='test-instance', vnfSoftwareVersion='1.1.1', vnfdVersion='1.2')
|
||||||
|
version_mismatch = (
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts_Versions(
|
||||||
|
vnfSoftwareVersion='1.1.2'))
|
||||||
|
result_1 = subsc_utils.match_version(version_mismatch, inst)
|
||||||
|
self.assertEqual(False, result_1)
|
||||||
|
|
||||||
|
version_match = (
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts_Versions(
|
||||||
|
vnfSoftwareVersion='1.1.1'))
|
||||||
|
result_2 = subsc_utils.match_version(version_match, inst)
|
||||||
|
self.assertEqual(True, result_2)
|
||||||
|
|
||||||
|
version_vnfd = (
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts_Versions(
|
||||||
|
vnfSoftwareVersion='1.1.1', vnfdVersions=['1.2']))
|
||||||
|
result_3 = subsc_utils.match_version(version_vnfd, inst)
|
||||||
|
self.assertEqual(True, result_3)
|
||||||
|
|
||||||
|
def test_match_products_per_provider(self):
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
id='test-instance', vnfProvider='company',
|
||||||
|
vnfSoftwareVersion='1.1.1', vnfdVersion='1.2',
|
||||||
|
vnfProductName='test')
|
||||||
|
products_mismatch = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='test')
|
||||||
|
result_1 = subsc_utils.match_products_per_provider(
|
||||||
|
products_mismatch, inst)
|
||||||
|
self.assertEqual(False, result_1)
|
||||||
|
|
||||||
|
products_vnfproducts_no_exist = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company')
|
||||||
|
result_2 = subsc_utils.match_products_per_provider(
|
||||||
|
products_vnfproducts_no_exist, inst)
|
||||||
|
self.assertEqual(True, result_2)
|
||||||
|
|
||||||
|
products_vnf_mismatch = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company', vnfProducts=[
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts(
|
||||||
|
vnfProductName='error'),
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts(
|
||||||
|
vnfProductName='test', versions=[
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts_Versions(
|
||||||
|
vnfSoftwareVersion='1.1.2'
|
||||||
|
)])
|
||||||
|
])
|
||||||
|
result_3 = subsc_utils.match_products_per_provider(
|
||||||
|
products_vnf_mismatch, inst)
|
||||||
|
self.assertEqual(False, result_3)
|
||||||
|
|
||||||
|
products_vnf_match_with_no_versions = (
|
||||||
|
objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company', vnfProducts=[
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts(
|
||||||
|
vnfProductName='test')]))
|
||||||
|
|
||||||
|
result_4 = subsc_utils.match_products_per_provider(
|
||||||
|
products_vnf_match_with_no_versions, inst)
|
||||||
|
self.assertEqual(True, result_4)
|
||||||
|
|
||||||
|
products_vnf_match_with_versions = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company', vnfProducts=[
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts(
|
||||||
|
vnfProductName='test', versions=[
|
||||||
|
objects._VnfProductsFromProviders_VnfProducts_Versions(
|
||||||
|
vnfSoftwareVersion='1.1.1'
|
||||||
|
)])
|
||||||
|
])
|
||||||
|
|
||||||
|
result_5 = subsc_utils.match_products_per_provider(
|
||||||
|
products_vnf_match_with_versions, inst)
|
||||||
|
self.assertEqual(True, result_5)
|
||||||
|
|
||||||
|
def test_match_inst_subsc_filter(self):
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
id='test-instance', vnfProvider='company',
|
||||||
|
vnfSoftwareVersion='1.1.1', vnfdVersion='1.2',
|
||||||
|
vnfProductName='test', vnfdId='vnfdid-1',
|
||||||
|
vnfInstanceName='test')
|
||||||
|
inst_filter_mismatch_vnfdid = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfdIds=['error'])
|
||||||
|
result_1 = subsc_utils.match_inst_subsc_filter(
|
||||||
|
inst_filter_mismatch_vnfdid, inst)
|
||||||
|
self.assertEqual(False, result_1)
|
||||||
|
|
||||||
|
products_vnfproducts_no_exist = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company')
|
||||||
|
inst_filter_match_products = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfProductsFromProviders=[products_vnfproducts_no_exist])
|
||||||
|
result_2 = subsc_utils.match_inst_subsc_filter(
|
||||||
|
inst_filter_match_products, inst)
|
||||||
|
self.assertEqual(True, result_2)
|
||||||
|
|
||||||
|
products_mismatch = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='test')
|
||||||
|
inst_filter_mismatch_products = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfProductsFromProviders=[products_mismatch])
|
||||||
|
result_3 = subsc_utils.match_inst_subsc_filter(
|
||||||
|
inst_filter_mismatch_products, inst)
|
||||||
|
self.assertEqual(False, result_3)
|
||||||
|
|
||||||
|
inst_filter_mismatch_inst_id = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfInstanceIds=['instanceid-2'])
|
||||||
|
result_4 = subsc_utils.match_inst_subsc_filter(
|
||||||
|
inst_filter_mismatch_inst_id, inst)
|
||||||
|
self.assertEqual(False, result_4)
|
||||||
|
|
||||||
|
inst_filter_mismatch_inst_name = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfInstanceNames=['instance_name-2'])
|
||||||
|
result_5 = subsc_utils.match_inst_subsc_filter(
|
||||||
|
inst_filter_mismatch_inst_name, inst)
|
||||||
|
self.assertEqual(False, result_5)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_inst_create_subscs(self, mock_subscs):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
result = subsc_utils.get_inst_create_subscs(context, inst)
|
||||||
|
|
||||||
|
self.assertEqual('subsc-1', result[0].id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_inst_delete_subscs(self, mock_subscs):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
result = subsc_utils.get_inst_delete_subscs(context, inst)
|
||||||
|
|
||||||
|
self.assertEqual('subsc-1', result[0].id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_lcmocc_subscs(self, mock_subscs):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(operationState='COMPLETED',
|
||||||
|
operation='INSTANTIATE')
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
result = subsc_utils.get_lcmocc_subscs(context, lcmocc, inst)
|
||||||
|
|
||||||
|
self.assertEqual('subsc-1', result[0].id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_matched_subscs(self, mock_subscs):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance', vnfProvider='company')
|
||||||
|
notif_type = 'VnfLcmOperationOccurrenceNotification'
|
||||||
|
op_type = 'INSTANTIATE'
|
||||||
|
op_status = 'COMPLETED'
|
||||||
|
|
||||||
|
subscs_no_fileter = objects.LccnSubscriptionV2(id='subsc-1')
|
||||||
|
|
||||||
|
products_vnfproducts_no_exist = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='company')
|
||||||
|
inst_filter_match_products = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfProductsFromProviders=[products_vnfproducts_no_exist])
|
||||||
|
subscs_filter_match = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-2',
|
||||||
|
filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
vnfInstanceSubscriptionFilter=inst_filter_match_products))
|
||||||
|
|
||||||
|
products_mismatch = objects._VnfProductsFromProviders(
|
||||||
|
vnfProvider='test')
|
||||||
|
inst_filter_mismatch_products = objects.VnfInstanceSubscriptionFilter(
|
||||||
|
vnfProductsFromProviders=[products_mismatch])
|
||||||
|
subscs_filter_mismatch = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-3',
|
||||||
|
filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
vnfInstanceSubscriptionFilter=inst_filter_mismatch_products))
|
||||||
|
|
||||||
|
subscs_noti_type_match = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-4', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
notificationTypes=['VnfLcmOperationOccurrenceNotification']))
|
||||||
|
subscs_noti_type_mismatch = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-5', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
notificationTypes=['VnfIdentifierCreationNotification']))
|
||||||
|
|
||||||
|
subscs_op_type_match = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-6', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
operationTypes=['INSTANTIATE']))
|
||||||
|
subscs_op_type_mismatch = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-7', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
operationTypes=['TERMINATE']))
|
||||||
|
|
||||||
|
subscs_op_status_match = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-8', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
operationStatus=['COMPLETED']))
|
||||||
|
subscs_op_status_mismatch = objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-9', filter=objects.LifecycleChangeNotificationsFilterV2(
|
||||||
|
operationStatus=['FAILED_TEMP']))
|
||||||
|
|
||||||
|
mock_subscs.return_value = [
|
||||||
|
subscs_no_fileter, subscs_filter_match, subscs_filter_mismatch,
|
||||||
|
subscs_noti_type_match, subscs_noti_type_mismatch,
|
||||||
|
subscs_op_type_match, subscs_op_type_mismatch,
|
||||||
|
subscs_op_status_match, subscs_op_status_mismatch]
|
||||||
|
|
||||||
|
result = subsc_utils.get_matched_subscs(
|
||||||
|
context, inst, notif_type, op_type, op_status)
|
||||||
|
|
||||||
|
expected_ids = ['subsc-1', 'subsc-2', 'subsc-4', 'subsc-6', 'subsc-8']
|
||||||
|
|
||||||
|
result_ids = [sub.id for sub in result]
|
||||||
|
self.assertEqual(expected_ids, result_ids)
|
||||||
|
|
||||||
|
def test_make_create_inst_notif_data(self):
|
||||||
|
subsc = objects.LccnSubscriptionV2(id='subsc-1')
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
endpoint = 'http://127.0.0.1:9890'
|
||||||
|
|
||||||
|
result = subsc_utils.make_create_inst_notif_data(subsc, inst, endpoint)
|
||||||
|
|
||||||
|
self.assertEqual('subsc-1', result.subscriptionId)
|
||||||
|
self.assertEqual('test-instance', result.vnfInstanceId)
|
||||||
|
|
||||||
|
def test_make_delete_inst_notif_data(self):
|
||||||
|
subsc = objects.LccnSubscriptionV2(id='subsc-1')
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
endpoint = 'http://127.0.0.1:9890'
|
||||||
|
|
||||||
|
result = subsc_utils.make_delete_inst_notif_data(subsc, inst, endpoint)
|
||||||
|
|
||||||
|
self.assertEqual('subsc-1', result.subscriptionId)
|
||||||
|
self.assertEqual('test-instance', result.vnfInstanceId)
|
|
@ -0,0 +1,114 @@
|
||||||
|
# Copyright (C) 2022 FUJITSU
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.api import api_version
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
|
from tacker.sol_refactored.common import vim_utils
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
|
from tacker.tests import base
|
||||||
|
from tacker.vnfm import vim_client
|
||||||
|
|
||||||
|
_vim_openstack = {
|
||||||
|
"placement_attr": {
|
||||||
|
"regions": ['RegionOne']
|
||||||
|
},
|
||||||
|
"vim_auth": {
|
||||||
|
"username": "nfv_user",
|
||||||
|
"password": "devstack",
|
||||||
|
"project_name": "nfv",
|
||||||
|
"project_domain_name": "Default",
|
||||||
|
"user_domain_name": "Default",
|
||||||
|
"auth_url": "http://127.0.0.1/identity"
|
||||||
|
},
|
||||||
|
"vim_type": "openstack",
|
||||||
|
"vim_id": "openstack-1"
|
||||||
|
}
|
||||||
|
_vim_kubernetes_bearer_token = {
|
||||||
|
"placement_attr": {
|
||||||
|
"regions": ['RegionOne']
|
||||||
|
},
|
||||||
|
"vim_auth": {
|
||||||
|
"username": None,
|
||||||
|
"password": None,
|
||||||
|
"bearer_token": "test_token",
|
||||||
|
"auth_url": "https://127.0.0.1:6443",
|
||||||
|
"ssl_ca_cert": "test_ssl"
|
||||||
|
},
|
||||||
|
"vim_type": "kubernetes",
|
||||||
|
"vim_id": "kubernetes-1"
|
||||||
|
}
|
||||||
|
_vim_kubernetes_user = {
|
||||||
|
"vim_auth": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin",
|
||||||
|
"auth_url": "https://127.0.0.1:6443"
|
||||||
|
},
|
||||||
|
"vim_type": "kubernetes",
|
||||||
|
"vim_id": "kubernetes-2"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestVimUtils(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVimUtils, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
self.context.api_version = api_version.APIVersion('2.0.0')
|
||||||
|
|
||||||
|
@mock.patch.object(vim_client.VimClient, 'get_vim')
|
||||||
|
def test_get_default_vim(self, mock_vim):
|
||||||
|
mock_vim.return_value = _vim_openstack
|
||||||
|
result = vim_utils.get_default_vim(context)
|
||||||
|
|
||||||
|
self.assertEqual('openstack-1', result.vimId)
|
||||||
|
|
||||||
|
@mock.patch.object(vim_client.VimClient, 'get_vim')
|
||||||
|
def test_get_default_vim_error(self, mock_vim):
|
||||||
|
mock_vim.return_value = Exception
|
||||||
|
vim_utils.get_default_vim(context)
|
||||||
|
|
||||||
|
@mock.patch.object(vim_client.VimClient, 'get_vim')
|
||||||
|
def test_get_vim(self, mock_vim):
|
||||||
|
mock_vim.return_value = _vim_kubernetes_bearer_token
|
||||||
|
result = vim_utils.get_vim(context, 'kubernetes-1')
|
||||||
|
|
||||||
|
self.assertEqual('kubernetes-1', result.vimId)
|
||||||
|
|
||||||
|
@mock.patch.object(vim_client.VimClient, 'get_vim')
|
||||||
|
def test_get_vim_error(self, mock_vim):
|
||||||
|
mock_vim.return_value = Exception
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VimNotFound, vim_utils.get_vim, context, 'test')
|
||||||
|
|
||||||
|
def test_vim_to_conn_info(self):
|
||||||
|
vim_openstack = _vim_openstack
|
||||||
|
vim_kubernetes_1 = _vim_kubernetes_bearer_token
|
||||||
|
vim_kubernetes_2 = _vim_kubernetes_user
|
||||||
|
|
||||||
|
result_1 = vim_utils.vim_to_conn_info(vim_openstack)
|
||||||
|
self.assertEqual('openstack-1', result_1.vimId)
|
||||||
|
|
||||||
|
result_2 = vim_utils.vim_to_conn_info(vim_kubernetes_1)
|
||||||
|
self.assertEqual('kubernetes-1', result_2.vimId)
|
||||||
|
|
||||||
|
result_3 = vim_utils.vim_to_conn_info(vim_kubernetes_2)
|
||||||
|
self.assertEqual('kubernetes-2', result_3.vimId)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.SolException, vim_utils.vim_to_conn_info,
|
||||||
|
{'vim_type': 'test', 'vim_auth': 'test'})
|
|
@ -12,23 +12,31 @@
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
from tacker.sol_refactored.common import vnf_instance_utils as inst_utils
|
from tacker.sol_refactored.common import vnf_instance_utils as inst_utils
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
from tacker.tests import base
|
from tacker.tests import base
|
||||||
|
|
||||||
|
|
||||||
class TestVnfInstanceUtils(base.BaseTestCase):
|
class TestVnfInstanceUtils(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVnfInstanceUtils, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
|
||||||
def test_json_merge_patch(self):
|
def test_json_merge_patch(self):
|
||||||
# patch is not dict.
|
# patch is not dict.
|
||||||
target = {"key1", "value1"}
|
target = {"key1": "value1"}
|
||||||
patch = "text"
|
patch = "text"
|
||||||
result = inst_utils.json_merge_patch(target, patch)
|
result = inst_utils.json_merge_patch(target, patch)
|
||||||
self.assertEqual(patch, result)
|
self.assertEqual(patch, result)
|
||||||
|
|
||||||
# target is not dict.
|
# target is not dict.
|
||||||
target = "text"
|
target = "text"
|
||||||
patch = {"key1", "value1"}
|
patch = {"key1": "value1"}
|
||||||
result = inst_utils.json_merge_patch(target, patch)
|
result = inst_utils.json_merge_patch(target, patch)
|
||||||
self.assertEqual(patch, result)
|
self.assertEqual(patch, result)
|
||||||
|
|
||||||
|
@ -65,3 +73,24 @@ class TestVnfInstanceUtils(base.BaseTestCase):
|
||||||
}
|
}
|
||||||
result = inst_utils.json_merge_patch(target, patch)
|
result = inst_utils.json_merge_patch(target, patch)
|
||||||
self.assertEqual(expected_result, result)
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_inst(self, mock_inst):
|
||||||
|
mock_inst.return_value = objects.VnfInstanceV2(id='inst-1')
|
||||||
|
|
||||||
|
result = inst_utils.get_inst(context, 'inst-1')
|
||||||
|
self.assertEqual('inst-1', result.id)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id')
|
||||||
|
def test_get_inst_error(self, mock_inst):
|
||||||
|
mock_inst.return_value = None
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfInstanceNotFound,
|
||||||
|
inst_utils.get_inst, context, 'inst-1')
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
def test_get_inst_all(self, mock_inst):
|
||||||
|
mock_inst.return_value = [objects.VnfInstanceV2(id='inst-1')]
|
||||||
|
|
||||||
|
result = inst_utils.get_inst_all(context)
|
||||||
|
self.assertEqual('inst-1', result[0].id)
|
||||||
|
|
|
@ -12,8 +12,13 @@
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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 os
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
import yaml
|
||||||
|
|
||||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
from tacker.sol_refactored.common import vnfd_utils
|
from tacker.sol_refactored.common import vnfd_utils
|
||||||
|
@ -22,6 +27,7 @@ from tacker.tests import base
|
||||||
|
|
||||||
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
||||||
SAMPLE_FLAVOUR_ID = "simple"
|
SAMPLE_FLAVOUR_ID = "simple"
|
||||||
|
LOG = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
class TestVnfd(base.BaseTestCase):
|
class TestVnfd(base.BaseTestCase):
|
||||||
|
@ -179,3 +185,126 @@ class TestVnfd(base.BaseTestCase):
|
||||||
result = self.vnfd_1.get_max_scale_level(SAMPLE_FLAVOUR_ID,
|
result = self.vnfd_1.get_max_scale_level(SAMPLE_FLAVOUR_ID,
|
||||||
'VDU1_scale')
|
'VDU1_scale')
|
||||||
self.assertEqual(2, result)
|
self.assertEqual(2, result)
|
||||||
|
|
||||||
|
def test_init_from_zip_file(self):
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
tmp_dir = tempfile.mkdtemp()
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_path = os.path.join(cur_dir, "../samples/sample1")
|
||||||
|
shutil.make_archive(tmp_dir, 'zip', root_dir=sample_path)
|
||||||
|
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
with open(f'{tmp_dir}.zip', "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
vnfd.init_from_zip_file(content)
|
||||||
|
with open(f'{sample_path}/TOSCA-Metadata/TOSCA.meta', 'r') as f:
|
||||||
|
tosca_content = yaml.safe_load(f.read())
|
||||||
|
with open(f'{sample_path}/Definitions/'
|
||||||
|
f'ut_sample1_df_simple.yaml', 'r') as f:
|
||||||
|
definition_content = yaml.safe_load(f.read())
|
||||||
|
self.assertEqual(tosca_content, vnfd.tosca_meta)
|
||||||
|
self.assertEqual(True, vnfd.csar_dir_is_tmp)
|
||||||
|
self.assertEqual(
|
||||||
|
definition_content, vnfd.definitions['ut_sample1_df_simple.yaml'])
|
||||||
|
|
||||||
|
def test_init_vnfd_error(self):
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
vnfd.csar_dir = 'test'
|
||||||
|
self.assertRaises(sol_ex.InvalidVnfdFormat, vnfd.init_vnfd)
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
os.mkdir("/tmp/test")
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
vnfd.csar_dir_is_tmp = True
|
||||||
|
vnfd.csar_dir = "/tmp/test"
|
||||||
|
vnfd.delete()
|
||||||
|
result = os.path.isdir(vnfd.csar_dir)
|
||||||
|
self.assertEqual(False, result)
|
||||||
|
|
||||||
|
def test_get_vnfd_properties(self):
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
expected_result = {
|
||||||
|
'vnfConfigurableProperties': {},
|
||||||
|
'extensions': {},
|
||||||
|
'metadata': {}
|
||||||
|
}
|
||||||
|
result = vnfd.get_vnfd_properties()
|
||||||
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
|
def test_get_base_hot_abnormal(self):
|
||||||
|
flavour_id = 'simple'
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
vnfd.csar_dir = '/test/'
|
||||||
|
base_hot_result = vnfd.get_base_hot(flavour_id)
|
||||||
|
self.assertEqual({}, base_hot_result)
|
||||||
|
|
||||||
|
flavour_id = 'error'
|
||||||
|
base_hot_result = self.vnfd_1.get_base_hot(flavour_id)
|
||||||
|
self.assertIsNotNone(base_hot_result['template'])
|
||||||
|
|
||||||
|
def test_remove_tmp_csar_dir(self):
|
||||||
|
os.mkdir("/tmp/test")
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
tmp_dir = "/tmp/test"
|
||||||
|
vnfd.remove_tmp_csar_dir(tmp_dir)
|
||||||
|
result = os.path.isdir(tmp_dir)
|
||||||
|
self.assertEqual(False, result)
|
||||||
|
|
||||||
|
def test_remove_tmp_csar_dir_error(self):
|
||||||
|
vnfd_id = uuidutils.generate_uuid()
|
||||||
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
|
log_name = "tacker.sol_refactored.common.vnfd_utils"
|
||||||
|
with self.assertLogs(logger=log_name, level=logging.DEBUG) as cm:
|
||||||
|
vnfd.remove_tmp_csar_dir('test')
|
||||||
|
|
||||||
|
msg = (f'ERROR:{log_name}:rmtree test failed')
|
||||||
|
self.assertIn(f'{msg}', cm.output[0].split('\n')[0])
|
||||||
|
|
||||||
|
def test_get_policy_values_by_type(self):
|
||||||
|
result = self.vnfd_1.get_policy_values_by_type(
|
||||||
|
'error', 'tosca.policies.nfv.AntiAffinityRule')
|
||||||
|
self.assertEqual('nfvi_node', result[0]['properties']['scope'])
|
||||||
|
|
||||||
|
def test_get_vdu_num_none(self):
|
||||||
|
result = self.vnfd_1.get_vdu_num('error', 'VDU1', 'default')
|
||||||
|
self.assertEqual(0, result)
|
||||||
|
|
||||||
|
def test_get_affinity_targets(self):
|
||||||
|
result = self.vnfd_1.get_affinity_targets('error')
|
||||||
|
expected_result = [(['VDU3'], 'zone')]
|
||||||
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
|
def test_get_interface_script_abnormal(self):
|
||||||
|
result = self.vnfd_1.get_interface_script('error', 'instantiate_start')
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
||||||
|
result = self.vnfd_1.get_interface_script('error', 'instantiate_end')
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
||||||
|
self.vnfd_1.get_interface_script('error', 'instantiate_end')
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.SolHttpError422, self.vnfd_1.get_interface_script,
|
||||||
|
'error', 'terminate_start')
|
||||||
|
|
||||||
|
def test_get_scale_vdu_and_num_abnormal(self):
|
||||||
|
result = self.vnfd_1.get_scale_vdu_and_num('error', 'VDU1_scale')
|
||||||
|
self.assertEqual({}, result)
|
||||||
|
|
||||||
|
def test_get_scale_info_from_inst_level_abnormal(self):
|
||||||
|
result = self.vnfd_1.get_scale_info_from_inst_level('error', 'default')
|
||||||
|
self.assertEqual({}, result)
|
||||||
|
|
||||||
|
def test_get_max_scale_level_abnormal(self):
|
||||||
|
result = self.vnfd_1.get_max_scale_level('error', 'VDU1_scale')
|
||||||
|
self.assertEqual(0, result)
|
||||||
|
|
||||||
|
def test_get_vnf_artifact_files_manifest(self):
|
||||||
|
result = self.vnfd_1.get_vnf_artifact_files()
|
||||||
|
expected_result = ['Scripts/install.sh',
|
||||||
|
'Files/kubernetes/deployment.yaml']
|
||||||
|
self.assertEqual(expected_result, result)
|
||||||
|
|
|
@ -39,8 +39,9 @@ class TestConductorV2(db_base.SqlTestCase):
|
||||||
self.conductor = conductor_v2.ConductorV2()
|
self.conductor = conductor_v2.ConductorV2()
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
|
||||||
def _create_inst_and_lcmocc(self,
|
def _create_inst_and_lcmocc(
|
||||||
op_state=fields.LcmOperationStateType.STARTING):
|
self, op_state=fields.LcmOperationStateType.STARTING,
|
||||||
|
is_change_vnfpkg=False):
|
||||||
inst = objects.VnfInstanceV2(
|
inst = objects.VnfInstanceV2(
|
||||||
# required fields
|
# required fields
|
||||||
id=uuidutils.generate_uuid(),
|
id=uuidutils.generate_uuid(),
|
||||||
|
@ -65,6 +66,9 @@ class TestConductorV2(db_base.SqlTestCase):
|
||||||
isCancelPending=False,
|
isCancelPending=False,
|
||||||
operationParams=req)
|
operationParams=req)
|
||||||
|
|
||||||
|
if is_change_vnfpkg:
|
||||||
|
lcmocc.operation = fields.LcmOperationType.CHANGE_VNFPKG
|
||||||
|
|
||||||
inst.create(self.context)
|
inst.create(self.context)
|
||||||
lcmocc.create(self.context)
|
lcmocc.create(self.context)
|
||||||
|
|
||||||
|
@ -530,3 +534,98 @@ class TestConductorV2(db_base.SqlTestCase):
|
||||||
lcmocc = lcmocc_utils.get_lcmocc(self.context, lcmocc.id)
|
lcmocc = lcmocc_utils.get_lcmocc(self.context, lcmocc.id)
|
||||||
expected = ex.make_problem_details()
|
expected = ex.make_problem_details()
|
||||||
self.assertEqual(expected, lcmocc.error.to_dict())
|
self.assertEqual(expected, lcmocc.error.to_dict())
|
||||||
|
|
||||||
|
def test_start_lcm_op_abnormal(self):
|
||||||
|
# prepare
|
||||||
|
lcmocc = self._create_inst_and_lcmocc(
|
||||||
|
op_state=fields.LcmOperationStateType.PROCESSING)
|
||||||
|
|
||||||
|
result = self.conductor.start_lcm_op(self.context, lcmocc.id)
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
||||||
|
@mock.patch.object(nfvo_client.NfvoClient, 'send_lcmocc_notification')
|
||||||
|
@mock.patch.object(nfvo_client.NfvoClient, 'get_vnfd')
|
||||||
|
@mock.patch.object(vnflcm_driver_v2.VnfLcmDriverV2, 'post_grant')
|
||||||
|
@mock.patch.object(vnflcm_driver_v2.VnfLcmDriverV2, 'process')
|
||||||
|
def test_retry_lcm_op_abnormal(self, mocked_process, mocked_post_grant,
|
||||||
|
mocked_get_vnfd, mocked_send_lcmocc_notification):
|
||||||
|
# operation state incorrect
|
||||||
|
lcmocc = self._create_inst_and_lcmocc(
|
||||||
|
op_state=fields.LcmOperationStateType.PROCESSING)
|
||||||
|
result = self.conductor.retry_lcm_op(self.context, lcmocc.id)
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
||||||
|
# operation is change_vnfpkg
|
||||||
|
# prepare
|
||||||
|
lcmocc = self._create_inst_and_lcmocc(
|
||||||
|
op_state=fields.LcmOperationStateType.FAILED_TEMP)
|
||||||
|
lcmocc.operation = fields.LcmOperationType.CHANGE_VNFPKG
|
||||||
|
lcmocc.operationParams = objects.ChangeCurrentVnfPkgRequest(
|
||||||
|
vnfdId='test-vnfdid')
|
||||||
|
self._create_grant_req_and_grant(lcmocc)
|
||||||
|
mocked_get_vnfd.return_value = mock.Mock()
|
||||||
|
|
||||||
|
op_state = []
|
||||||
|
|
||||||
|
def _store_state(context, lcmocc, inst, endpoint):
|
||||||
|
op_state.append(lcmocc.operationState)
|
||||||
|
|
||||||
|
mocked_send_lcmocc_notification.side_effect = _store_state
|
||||||
|
|
||||||
|
# run retry_lcm_op
|
||||||
|
self.conductor.retry_lcm_op(self.context, lcmocc.id)
|
||||||
|
|
||||||
|
# check operationState transition
|
||||||
|
self.assertEqual(2, mocked_send_lcmocc_notification.call_count)
|
||||||
|
self.assertEqual(fields.LcmOperationStateType.PROCESSING, op_state[0])
|
||||||
|
self.assertEqual(fields.LcmOperationStateType.COMPLETED, op_state[1])
|
||||||
|
|
||||||
|
# check grant_req and grant are deleted
|
||||||
|
self.assertRaises(sol_ex.GrantRequestOrGrantNotFound,
|
||||||
|
lcmocc_utils.get_grant_req_and_grant, self.context, lcmocc)
|
||||||
|
|
||||||
|
@mock.patch.object(nfvo_client.NfvoClient, 'send_lcmocc_notification')
|
||||||
|
@mock.patch.object(nfvo_client.NfvoClient, 'get_vnfd')
|
||||||
|
@mock.patch.object(vnflcm_driver_v2.VnfLcmDriverV2, 'post_grant')
|
||||||
|
@mock.patch.object(vnflcm_driver_v2.VnfLcmDriverV2, 'rollback')
|
||||||
|
def test_rollback_lcm_op_abnormal(self, mocked_rollback,
|
||||||
|
mocked_post_grant, mocked_get_vnfd,
|
||||||
|
mocked_send_lcmocc_notification):
|
||||||
|
# operation state incorrect
|
||||||
|
lcmocc = self._create_inst_and_lcmocc(
|
||||||
|
op_state=fields.LcmOperationStateType.PROCESSING)
|
||||||
|
result = self.conductor.rollback_lcm_op(self.context, lcmocc.id)
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
||||||
|
# operation is change_vnfpkg
|
||||||
|
lcmocc = self._create_inst_and_lcmocc(
|
||||||
|
op_state=fields.LcmOperationStateType.FAILED_TEMP,
|
||||||
|
is_change_vnfpkg=True)
|
||||||
|
self._create_grant_req_and_grant(lcmocc)
|
||||||
|
mocked_get_vnfd.return_value = mock.Mock()
|
||||||
|
|
||||||
|
op_state = []
|
||||||
|
|
||||||
|
def _store_state(context, lcmocc, inst, endpoint):
|
||||||
|
op_state.append(lcmocc.operationState)
|
||||||
|
|
||||||
|
mocked_send_lcmocc_notification.side_effect = _store_state
|
||||||
|
|
||||||
|
# run rollback_lcm_op
|
||||||
|
self.conductor.rollback_lcm_op(self.context, lcmocc.id)
|
||||||
|
|
||||||
|
# check operationState transition
|
||||||
|
self.assertEqual(2, mocked_send_lcmocc_notification.call_count)
|
||||||
|
self.assertEqual(fields.LcmOperationStateType.ROLLING_BACK,
|
||||||
|
op_state[0])
|
||||||
|
self.assertEqual(fields.LcmOperationStateType.ROLLED_BACK, op_state[1])
|
||||||
|
|
||||||
|
# check grant_req and grant are deleted
|
||||||
|
self.assertRaises(sol_ex.GrantRequestOrGrantNotFound,
|
||||||
|
lcmocc_utils.get_grant_req_and_grant, self.context, lcmocc)
|
||||||
|
|
||||||
|
def test_modify_vnfinfo_abnormal(self):
|
||||||
|
lcmocc = self._create_inst_and_lcmocc()
|
||||||
|
|
||||||
|
result = self.conductor.modify_vnfinfo(self.context, lcmocc.id)
|
||||||
|
self.assertEqual(None, result)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,8 @@ from oslo_utils import uuidutils
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from tacker import context
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.common import config
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
from tacker.sol_refactored.common import vnfd_utils
|
from tacker.sol_refactored.common import vnfd_utils
|
||||||
from tacker.sol_refactored.infra_drivers.openstack import openstack
|
from tacker.sol_refactored.infra_drivers.openstack import openstack
|
||||||
from tacker.sol_refactored import objects
|
from tacker.sol_refactored import objects
|
||||||
|
@ -35,13 +37,6 @@ SAMPLE_FLAVOUR_ID = "simple"
|
||||||
_vim_connection_info_example = {
|
_vim_connection_info_example = {
|
||||||
"vimId": "vim_id_1",
|
"vimId": "vim_id_1",
|
||||||
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",
|
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",
|
||||||
# "interfaceInfo": omitted
|
|
||||||
# "accessInfo": omitted
|
|
||||||
}
|
|
||||||
|
|
||||||
_vim_connection_info_for_change_vnfpkg = {
|
|
||||||
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",
|
|
||||||
"vimId": uuidutils.generate_uuid(),
|
|
||||||
"interfaceInfo": {"endpoint": "http://127.0.0.1/identity"},
|
"interfaceInfo": {"endpoint": "http://127.0.0.1/identity"},
|
||||||
"accessInfo": {
|
"accessInfo": {
|
||||||
"username": "nfv_user",
|
"username": "nfv_user",
|
||||||
|
@ -51,7 +46,6 @@ _vim_connection_info_for_change_vnfpkg = {
|
||||||
"projectDomain": "Default",
|
"projectDomain": "Default",
|
||||||
"userDomain": "Default"
|
"userDomain": "Default"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_instantiate_req_example = {
|
_instantiate_req_example = {
|
||||||
|
@ -2639,6 +2633,110 @@ mock_resource_list_3 = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_heat_parameters = {
|
||||||
|
'VDU': {
|
||||||
|
'VDU1': {
|
||||||
|
'desired_capacity': 1,
|
||||||
|
'computeFlavourId': 'm1.tiny',
|
||||||
|
'locationConstraints': None
|
||||||
|
},
|
||||||
|
'VirtualStorage': {
|
||||||
|
'vcImageId': 'image-1.0.0-x86_64-disk'
|
||||||
|
},
|
||||||
|
'VDU2': {
|
||||||
|
'computeFlavourId': 'm1.small',
|
||||||
|
'vcImageId': 'image-VDU2'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'CP': {
|
||||||
|
'VDU1_CP1': {
|
||||||
|
'network': 'res_id_ext_vl_1'
|
||||||
|
},
|
||||||
|
'VDU1_CP2': {
|
||||||
|
'network': 'res_id_id_ext_vl_2',
|
||||||
|
'fixed_ips': [{
|
||||||
|
'subnet': 'res_id_subnet_1'
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
'VDU2_CP1': {
|
||||||
|
'network': 'res_id_ext_vl_1',
|
||||||
|
'fixed_ips': [{
|
||||||
|
'ip_address': '10.10.0.102'
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
'VDU2_CP2': {
|
||||||
|
'network': 'res_id_id_ext_vl_2',
|
||||||
|
'fixed_ips': []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_grant_req_example = {
|
||||||
|
'operation': 'SCALE',
|
||||||
|
'removeResources': [{
|
||||||
|
'id': 'ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1',
|
||||||
|
'vimLevelResourceType': 'OS::Nova::Server'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VDU1_CP1-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'LINKPORT',
|
||||||
|
'resourceTemplateId': 'VDU1_CP1',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1_CP1',
|
||||||
|
'vimLevelResourceType': 'OS::Neutron::Port'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VDU1_CP2-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'LINKPORT',
|
||||||
|
'resourceTemplateId': 'VDU1_CP2',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1_CP2',
|
||||||
|
'vimLevelResourceType': 'OS::Neutron::Port'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VDU1_CP3-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'LINKPORT',
|
||||||
|
'resourceTemplateId': 'VDU1_CP3',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1_CP3',
|
||||||
|
'vimLevelResourceType': 'OS::Neutron::Port'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VDU1_CP4-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'LINKPORT',
|
||||||
|
'resourceTemplateId': 'VDU1_CP4',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1_CP4',
|
||||||
|
'vimLevelResourceType': 'OS::Neutron::Port'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VDU1_CP5-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'LINKPORT',
|
||||||
|
'resourceTemplateId': 'VDU1_CP5',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1_CP5',
|
||||||
|
'vimLevelResourceType': 'OS::Neutron::Port'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VirtualStorage-ed52e40b-922f-4e01-bc30-d4bf80029280',
|
||||||
|
'type': 'STORAGE',
|
||||||
|
'resourceTemplateId': 'VirtualStorage',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VirtualStorage_1',
|
||||||
|
'vimLevelResourceType': 'OS::Cinder::Volume'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'additionalParams': {
|
||||||
|
'key': 'value'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class TestOpenstack(base.BaseTestCase):
|
class TestOpenstack(base.BaseTestCase):
|
||||||
|
|
||||||
|
@ -2647,6 +2745,7 @@ class TestOpenstack(base.BaseTestCase):
|
||||||
objects.register_all()
|
objects.register_all()
|
||||||
self.driver = openstack.Openstack()
|
self.driver = openstack.Openstack()
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
CONF.v2_vnfm.default_graceful_termination_timeout = 0
|
||||||
|
|
||||||
cur_dir = os.path.dirname(__file__)
|
cur_dir = os.path.dirname(__file__)
|
||||||
sample_dir = os.path.join(cur_dir, "../..", "samples")
|
sample_dir = os.path.join(cur_dir, "../..", "samples")
|
||||||
|
@ -2811,3 +2910,353 @@ class TestOpenstack(base.BaseTestCase):
|
||||||
# check
|
# check
|
||||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_status')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'create_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_template')
|
||||||
|
def test_instantiate(self, mock_template, mock_parameters, mock_resources,
|
||||||
|
mock_update_stack, mock_create_stack, mock_status):
|
||||||
|
# prepare
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.INSTANTIATE
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
mock_status.return_value = (None, 'test')
|
||||||
|
mock_resources.return_value = _heat_reses_example
|
||||||
|
mock_parameters.return_value = _heat_get_parameters_example
|
||||||
|
mock_template.return_value = _heat_get_template_example
|
||||||
|
# execute
|
||||||
|
self.driver.instantiate(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
mock_create_stack.assert_called_once()
|
||||||
|
|
||||||
|
mock_status.return_value = ('Create_Failed', 'test')
|
||||||
|
# execute
|
||||||
|
self.driver.instantiate(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
mock_update_stack.assert_called_once()
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_status')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'delete_stack')
|
||||||
|
def test_instantiate_rollback(self, mock_delete_stack, mock_status):
|
||||||
|
# prepare
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.INSTANTIATE
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
mock_status.return_value = (None, 'test')
|
||||||
|
# execute
|
||||||
|
self.driver.instantiate_rollback(
|
||||||
|
req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
mock_delete_stack.assert_not_called()
|
||||||
|
|
||||||
|
mock_status.return_value = ('Create_Failed', 'test')
|
||||||
|
# execute
|
||||||
|
self.driver.instantiate_rollback(
|
||||||
|
req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
mock_delete_stack.assert_called_once()
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'delete_stack')
|
||||||
|
def test_terminate(self, mock_delete_stack):
|
||||||
|
# prepare
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
req = objects.TerminateVnfRequest(
|
||||||
|
terminationType='GRACEFUL', gracefulTerminationTimeout=0)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_inst_info_example))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.TERMINATE
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
# graceful
|
||||||
|
self.driver.terminate(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
self.assertEqual(1, mock_delete_stack.call_count)
|
||||||
|
|
||||||
|
# graceful with no time
|
||||||
|
req = objects.TerminateVnfRequest(terminationType='GRACEFUL')
|
||||||
|
self.driver.terminate(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
self.assertEqual(2, mock_delete_stack.call_count)
|
||||||
|
|
||||||
|
# forceful
|
||||||
|
req = objects.TerminateVnfRequest(terminationType='FORCEFUL')
|
||||||
|
self.driver.terminate(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
self.assertEqual(3, mock_delete_stack.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'mark_unhealthy')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_template')
|
||||||
|
def test_scale(self, mock_template, mock_unhealthy, mock_parameters,
|
||||||
|
mock_reses, mock_stack):
|
||||||
|
# prepare
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info_vnfc_updated))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.SCALE
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
mock_parameters.return_value = {'nfv': json.dumps(_heat_parameters)}
|
||||||
|
mock_template.return_value = _heat_get_template_example
|
||||||
|
|
||||||
|
# scale-out
|
||||||
|
req = objects.ScaleVnfRequest(
|
||||||
|
type='SCALE_OUT', aspectId='VDU1_scale', numberOfSteps=1)
|
||||||
|
mock_reses.return_value = _heat_reses_example
|
||||||
|
self.driver.scale(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
||||||
|
# scale-in
|
||||||
|
req = objects.ScaleVnfRequest(
|
||||||
|
type='SCALE_IN', aspectId='VDU1_scale', numberOfSteps=1)
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_grant_req_example)
|
||||||
|
mock_reses.return_value = _heat_reses_example
|
||||||
|
self.driver.scale(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
||||||
|
# error
|
||||||
|
req = objects.ScaleVnfRequest(
|
||||||
|
type='SCALE_IN', aspectId='VDU1_scale', numberOfSteps=1)
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_grant_req_example)
|
||||||
|
del inst.instantiatedVnfInfo.vnfcResourceInfo[1]['metadata'][
|
||||||
|
'parent_stack_id']
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.UnexpectedParentResourceDefinition, self.driver.scale,
|
||||||
|
req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'mark_unhealthy')
|
||||||
|
def test_scale_rollback(
|
||||||
|
self, mock_unhealthy, mock_parameters,
|
||||||
|
mock_reses, mock_stack):
|
||||||
|
# prepare
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info_vnfc_updated))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.SCALE
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
mock_parameters.return_value = {'nfv': json.dumps(_heat_parameters)}
|
||||||
|
|
||||||
|
# scale-out
|
||||||
|
req = objects.ScaleVnfRequest(
|
||||||
|
type='SCALE_OUT', aspectId='VDU1_scale', numberOfSteps=1)
|
||||||
|
mock_reses.return_value = _heat_reses_example
|
||||||
|
mock_reses.return_value[13]['physical_resource_id'] = (
|
||||||
|
'res_id_VDU1_1_new')
|
||||||
|
self.driver.scale_rollback(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
||||||
|
# error
|
||||||
|
del mock_reses.return_value[13]['parent_resource']
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.UnexpectedParentResourceDefinition,
|
||||||
|
self.driver.scale_rollback, req, inst,
|
||||||
|
grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_template')
|
||||||
|
def test_change_ext_conn(self, mock_template, mock_parameters,
|
||||||
|
mock_reses, mock_stack):
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info_change_ext_conn))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_EXT_CONN
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
req = objects.ChangeExtVnfConnectivityRequest.from_dict(
|
||||||
|
_change_ext_conn_req_example)
|
||||||
|
mock_parameters.return_value = {'nfv': json.dumps(_heat_parameters)}
|
||||||
|
mock_reses.return_value = _heat_reses_example_change_ext_conn
|
||||||
|
mock_template.return_value = _heat_get_template_example
|
||||||
|
self.driver.change_ext_conn(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_template')
|
||||||
|
def test_change_ext_conn_rollback(
|
||||||
|
self, mock_template, mock_parameters, mock_reses, mock_stack):
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info_change_ext_conn))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_EXT_CONN
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
req = objects.ChangeExtVnfConnectivityRequest.from_dict(
|
||||||
|
_change_ext_conn_req_example)
|
||||||
|
mock_parameters.return_value = {'nfv': json.dumps(_heat_parameters)}
|
||||||
|
mock_reses.return_value = _heat_reses_example_change_ext_conn
|
||||||
|
mock_template.return_value = _heat_get_template_example
|
||||||
|
self.driver.change_ext_conn_rollback(
|
||||||
|
req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||||
|
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'update_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'mark_unhealthy')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_resources')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'delete_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'create_stack')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_parameters')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_template')
|
||||||
|
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_files')
|
||||||
|
def test_heal(self, mock_files, mock_template,
|
||||||
|
mock_parameters, mock_create, mock_delete,
|
||||||
|
mock_reses, mock_unhealthy, mock_update):
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_instantiate_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
instantiatedVnfInfo=(
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info_vnfc_updated))
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.HEAL
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
mock_parameters.return_value = {'nfv': json.dumps(_heat_parameters)}
|
||||||
|
mock_template.return_value = _heat_get_template_example
|
||||||
|
|
||||||
|
# re-create
|
||||||
|
req = objects.HealVnfRequest(
|
||||||
|
additionalParams={
|
||||||
|
"all": True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
mock_reses.return_value = _heat_reses_example
|
||||||
|
self.driver.heal(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
||||||
|
# no re-create
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_grant_req_example)
|
||||||
|
req = objects.HealVnfRequest()
|
||||||
|
mock_reses.return_value = _heat_reses_example
|
||||||
|
self.driver.heal(req, inst, grant_req, grant, self.vnfd_1)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
|
@ -0,0 +1,763 @@
|
||||||
|
# Copyright (C) 2022 FUJITSU
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import os
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.api import api_version
|
||||||
|
from tacker.sol_refactored.infra_drivers.openstack import userdata_default
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
|
from tacker.sol_refactored.objects.v2 import fields
|
||||||
|
from tacker.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
||||||
|
# InstantiateVnfRequest example
|
||||||
|
_ext_vl_1 = {
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"resourceId": 'net0_id',
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP1_1": {
|
||||||
|
"cpProtocolData": [{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1}]}}]}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": ["10.10.0.101"]}]}}]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
_ext_vl_2 = {
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"resourceId": 'net1_id',
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
"subnetId": 'subnet1_id'}]}}]}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": ["10.10.1.101"],
|
||||||
|
"subnetId": 'subnet1_id'}]}}]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
_inst_req_example = {
|
||||||
|
"flavourId": "simple",
|
||||||
|
"instantiationLevelId": "instantiation_level_2",
|
||||||
|
"extVirtualLinks": [
|
||||||
|
_ext_vl_1,
|
||||||
|
_ext_vl_2
|
||||||
|
],
|
||||||
|
"extManagedVirtualLinks": [
|
||||||
|
{
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"vnfVirtualLinkDescId": "internalVL1",
|
||||||
|
"resourceId": 'net_mgmt_id'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"vimConnectionInfo": {
|
||||||
|
"vim1": {
|
||||||
|
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",
|
||||||
|
"vimId": uuidutils.generate_uuid(),
|
||||||
|
"interfaceInfo": {"endpoint": "http://localhost/identity/v3"},
|
||||||
|
"accessInfo": {
|
||||||
|
"username": "nfv_user",
|
||||||
|
"region": "RegionOne",
|
||||||
|
"password": "devstack",
|
||||||
|
"project": "nfv",
|
||||||
|
"projectDomain": "Default",
|
||||||
|
"userDomain": "Default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_scale_req_example = {
|
||||||
|
'type': 'SCALE_OUT',
|
||||||
|
'aspectId': 'VDU1_scale',
|
||||||
|
'numberOfSteps': 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_change_ext_conn_req_example = {
|
||||||
|
"extVirtualLinks": [
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_3",
|
||||||
|
"resourceId": "res_id_ext_vl_3",
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"20.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_4",
|
||||||
|
"resourceId": "res_id_id_ext_vl_4",
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
"subnetId": "res_id_subnet_4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"linkPortId": "link_port_id_VDU2_CP2_modified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "link_port_id_VDU2_CP2_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP2_modified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
_inst_info_example = {
|
||||||
|
"flavourId": "simple",
|
||||||
|
"vnfState": "STARTED",
|
||||||
|
'scaleStatus': [],
|
||||||
|
"extCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "90561570-264c-4472-b84f-1fff98513475",
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfigId": "VDU2_CP1_1",
|
||||||
|
"extLinkPortId": "ac27c99b-73c8-4e91-b730-90deade72af4",
|
||||||
|
"associatedVnfcCpId": "be955786-a0c7-4b61-8cd8-9bb8bcb1c6e3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f9f4b4b2-50e2-4c73-b89b-e0665e65ffbe",
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfigId": "VDU2_CP2_1",
|
||||||
|
"extLinkPortId": "12567a13-9fbd-4803-ad9f-d94ced266cd8",
|
||||||
|
"associatedVnfcCpId": "c54fa2fc-185a-49a7-bb89-f30f7c3be6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "05474d0b-a1f7-4be5-b57e-ef6873e1f3b6",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfigId": "VDU1_CP2_1",
|
||||||
|
"extLinkPortId": "aa6646da-2e59-4de9-9b72-c62e7c4d9142",
|
||||||
|
"associatedVnfcCpId": "fdbb289f-87c8-40d0-bf06-da07b41ba124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "42ede9a6-c2b8-4c0d-a337-26342ffb236c",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfigId": "VDU1_CP1_1",
|
||||||
|
"extLinkPortId": "efd0eb4e-4e55-4ac8-8b9b-403ec79faf2d",
|
||||||
|
"associatedVnfcCpId": "235f920c-8b49-4894-9c36-73f5a3b9f74d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4f0ab1ad-b7de-482f-a69b-1093c71d2ceb",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfigId": "VDU1_CP2_1",
|
||||||
|
"extLinkPortId": "a6c4c043-e082-4873-a871-02467af66224",
|
||||||
|
"associatedVnfcCpId": "e23d970d-9ea9-4c26-9d67-8f244383ea3c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7a7fa30f-a303-4856-bc8b-b836cb682892",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfigId": "VDU1_CP1_1",
|
||||||
|
"extLinkPortId": "f58df4d9-08ff-41b7-ab73-95ebfb8103c4",
|
||||||
|
"associatedVnfcCpId": "259c5895-7be6-4bed-8a94-221c41b3d08f"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extVirtualLinkInfo": [
|
||||||
|
{
|
||||||
|
"id": "137bdf0b-835c-43f0-b0d2-5c002599118a",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "6f97f400-2861-482a-ba78-65b652aaf8fc"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "ac27c99b-73c8-4e91-b730-90deade72af4",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "90561570-264c-4472-b84f-1fff98513475"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "efd0eb4e-4e55-4ac8-8b9b-403ec79faf2d",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_1_CP1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "42ede9a6-c2b8-4c0d-a337-26342ffb236c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f58df4d9-08ff-41b7-ab73-95ebfb8103c4",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_2_CP1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "7a7fa30f-a303-4856-bc8b-b836cb682892"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
'10.10.0.2'
|
||||||
|
],
|
||||||
|
"subnetId": 'test'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d8141a5a-6b6e-4dab-9bf5-158f23a617d7",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "02bc95e0-3d43-4d11-83b8-f7b15d8661a9"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "12567a13-9fbd-4803-ad9f-d94ced266cd8",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "f9f4b4b2-50e2-4c73-b89b-e0665e65ffbe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aa6646da-2e59-4de9-9b72-c62e7c4d9142",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_1_CP2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "05474d0b-a1f7-4be5-b57e-ef6873e1f3b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a6c4c043-e082-4873-a871-02467af66224",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_2_CP2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "4f0ab1ad-b7de-482f-a69b-1093c71d2ceb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
'10.10.0.3'
|
||||||
|
],
|
||||||
|
"subnetId": 'test'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
'10.10.0.4'
|
||||||
|
],
|
||||||
|
"subnetId": 'test'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extManagedVirtualLinkInfo": [
|
||||||
|
{
|
||||||
|
"id": "bad53df7-f1fa-482d-91b1-caec382aeec2",
|
||||||
|
"vnfVirtualLinkDescId": "internalVL1",
|
||||||
|
"networkResource": {
|
||||||
|
"resourceId": "56730009-169c-4f96-8141-828acf1ee067"
|
||||||
|
},
|
||||||
|
"vnfLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "74f387fe-6355-4af3-adc7-cdb507d5fa5f",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP3",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "5b0b336b-c207-4fa8-8b41-a5ad87d85cd0",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4064ec55-b862-4527-a911-8752d3aa765a",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_1_CP3",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "b0732fb7-a42a-4077-aebc-d22b67b64f13",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f3c9e62d-0f31-4a36-bd99-eecd8def0871",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_2_CP3",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "9c65f67e-feb2-447c-b0e7-a4f896185b4f",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vnfcResourceInfo": [
|
||||||
|
{
|
||||||
|
"id": "vnfc_res_info_id_VDU2",
|
||||||
|
"vduId": "VDU2",
|
||||||
|
"computeResource": {
|
||||||
|
"resourceId": "res_id_VDU2",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "be955786-a0c7-4b61-8cd8-9bb8bcb1c6e3",
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"vnfExtCpId": "90561570-264c-4472-b84f-1fff98513475"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c54fa2fc-185a-49a7-bb89-f30f7c3be6a4",
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"vnfExtCpId": "f9f4b4b2-50e2-4c73-b89b-e0665e65ffbe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5b0b336b-c207-4fa8-8b41-a5ad87d85cd0",
|
||||||
|
"cpdId": "VDU2_CP3",
|
||||||
|
"vnfLinkPortId": "74f387fe-6355-4af3-adc7-cdb507d5fa5f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2cb2b3a8-a7a0-41da-b3b8-4b82f576b090",
|
||||||
|
"cpdId": "VDU2_CP4",
|
||||||
|
"vnfLinkPortId": "8e01813f-35fc-4a35-8f64-0da08a45ea21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "39a7d895-3b19-4330-b6ec-ae3557ea9c01",
|
||||||
|
"cpdId": "VDU2_CP5",
|
||||||
|
"vnfLinkPortId": "4dd7cadd-b9a1-484f-b2f2-1ff50ef0d90f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "315a938a-b194-0c20-6398-ba92cce39c18",
|
||||||
|
"cpdId": "VDU2_CP6",
|
||||||
|
"vnfLinkPortId": "6dafdda1-db6c-492e-6dc2-4e5d323d6f98"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vnfc_res_info_id_VDU1_1",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"computeResource": {
|
||||||
|
"resourceId": "res_id_VDU1_1",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"storageResourceIds": ["2135b13c-e630-4700-8f8d-85b6e48f7871"],
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "235f920c-8b49-4894-9c36-73f5a3b9f74d",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"vnfExtCpId": "42ede9a6-c2b8-4c0d-a337-26342ffb236c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fdbb289f-87c8-40d0-bf06-da07b41ba124",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"vnfExtCpId": "05474d0b-a1f7-4be5-b57e-ef6873e1f3b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b0732fb7-a42a-4077-aebc-d22b67b64f13",
|
||||||
|
"cpdId": "VDU1_CP3",
|
||||||
|
"vnfLinkPortId": "4064ec55-b862-4527-a911-8752d3aa765a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a49f8fb8-6fd9-4e9f-a6dd-0d268e51c83c",
|
||||||
|
"cpdId": "VDU1_CP4",
|
||||||
|
"vnfLinkPortId": "1666a0f7-6a34-474e-87a2-07fb0c30ecdb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "33194d65-ecd6-48d9-8ef7-c15ce9fef46c",
|
||||||
|
"cpdId": "VDU1_CP5",
|
||||||
|
"vnfLinkPortId": "ace663cd-431b-402a-b2ae-d0824c996edb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vnfc_res_info_id_VDU1_2",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"computeResource": {
|
||||||
|
"resourceId": "res_id_VDU1_2",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"storageResourceIds": ["739f7012-7973-485b-b34f-b006bc336150"],
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "259c5895-7be6-4bed-8a94-221c41b3d08f",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
# when extLinkPorts of extVirtualLinks specified, there is
|
||||||
|
# no vnfExtCpId nor vnfLinkPortId.
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e23d970d-9ea9-4c26-9d67-8f244383ea3c",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"vnfExtCpId": "4f0ab1ad-b7de-482f-a69b-1093c71d2ceb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9c65f67e-feb2-447c-b0e7-a4f896185b4f",
|
||||||
|
"cpdId": "VDU1_CP3",
|
||||||
|
"vnfLinkPortId": "f3c9e62d-0f31-4a36-bd99-eecd8def0871"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0716ac20-612a-4ac2-8c87-d83be31dd4b5",
|
||||||
|
"cpdId": "VDU1_CP4",
|
||||||
|
"vnfLinkPortId": "bce3159b-caca-45b7-8bb7-88015e951e56"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c9112298-61eb-4bba-b285-ed3419593b1b",
|
||||||
|
"cpdId": "VDU1_CP5",
|
||||||
|
"vnfLinkPortId": "e0f98917-70ff-4f79-8747-9d7fc22827a4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vnfc_res_no_cp_info",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"computeResource": {
|
||||||
|
"resourceId": "res_id_VDU1_3",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vnfVirtualLinkResourceInfo": [
|
||||||
|
{
|
||||||
|
"id": "18bd0111-d5e1-4aa3-b2d8-5b89833c6351",
|
||||||
|
"vnfVirtualLinkDescId": "internalVL3",
|
||||||
|
"networkResource": {
|
||||||
|
"resourceId": "res_id_internalVL3",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Net"
|
||||||
|
},
|
||||||
|
"vnfLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "4dd7cadd-b9a1-484f-b2f2-1ff50ef0d90f",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP5",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "39a7d895-3b19-4330-b6ec-ae3557ea9c01",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ace663cd-431b-402a-b2ae-d0824c996edb",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_1_CP5",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "33194d65-ecd6-48d9-8ef7-c15ce9fef46c",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e0f98917-70ff-4f79-8747-9d7fc22827a4",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_2_CP5",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "c9112298-61eb-4bba-b285-ed3419593b1b",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "047aa313-b591-4529-aa98-cb8ce2b82e28",
|
||||||
|
"vnfVirtualLinkDescId": "internalVL2",
|
||||||
|
"networkResource": {
|
||||||
|
"resourceId": "res_id_internalVL2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Net"
|
||||||
|
},
|
||||||
|
"vnfLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "8e01813f-35fc-4a35-8f64-0da08a45ea21",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP4",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "2cb2b3a8-a7a0-41da-b3b8-4b82f576b090",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1666a0f7-6a34-474e-87a2-07fb0c30ecdb",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_1_CP4",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "a49f8fb8-6fd9-4e9f-a6dd-0d268e51c83c",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bce3159b-caca-45b7-8bb7-88015e951e56",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU1_2_CP4",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "0716ac20-612a-4ac2-8c87-d83be31dd4b5",
|
||||||
|
"cpInstanceType": "VNFC_CP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"virtualStorageResourceInfo": [
|
||||||
|
{
|
||||||
|
"id": "2135b13c-e630-4700-8f8d-85b6e48f7871",
|
||||||
|
"virtualStorageDescId": "VirtualStorage",
|
||||||
|
"storageResource": {
|
||||||
|
"resourceId": "res_id_VirtualStorage_1",
|
||||||
|
"vimLevelResourceType": "OS::Cinder::Volume"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "739f7012-7973-485b-b34f-b006bc336150",
|
||||||
|
"virtualStorageDescId": "VirtualStorage",
|
||||||
|
"storageResource": {
|
||||||
|
"resourceId": "res_id_VirtualStorage_2",
|
||||||
|
"vimLevelResourceType": "OS::Cinder::Volume"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vnfcInfo": [
|
||||||
|
{
|
||||||
|
"id": "VDU2-vnfc_res_info_id_VDU2",
|
||||||
|
"vduId": "VDU2",
|
||||||
|
"vnfcResourceInfoId": "vnfc_res_info_id_VDU2",
|
||||||
|
"vnfcState": "STARTED"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1-vnfc_res_info_id_VDU1_1",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"vnfcResourceInfoId": "vnfc_res_info_id_VDU1_1",
|
||||||
|
"vnfcState": "STARTED"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1-vnfc_res_info_id_VDU1_2",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"vnfcResourceInfoId": "vnfc_res_info_id_VDU1_2",
|
||||||
|
"vnfcState": "STARTED"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
_vnf_instance_example = {
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"vnfdId": SAMPLE_VNFD_ID,
|
||||||
|
"vnfProvider": "provider",
|
||||||
|
"vnfProductName": "product name",
|
||||||
|
"vnfSoftwareVersion": "software version",
|
||||||
|
"vnfdVersion": "vnfd version",
|
||||||
|
"instantiationState": "NOT_INSTANTIATED",
|
||||||
|
"vimConnectionInfo": _inst_req_example['vimConnectionInfo']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestUserdataDefault(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestUserdataDefault, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
self.context.api_version = api_version.APIVersion('2.0.0')
|
||||||
|
self.grant = {}
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "../..", "samples")
|
||||||
|
self.tmp_csar_dir = os.path.join(sample_dir, "sample1")
|
||||||
|
self.userdata_default = userdata_default.DefaultUserData()
|
||||||
|
|
||||||
|
def test_instantiate(self):
|
||||||
|
req = _inst_req_example
|
||||||
|
req['additionalParams'] = {"nfv": "req"}
|
||||||
|
inst = _vnf_instance_example
|
||||||
|
grant_req = {
|
||||||
|
"operation": fields.LcmOperationType.INSTANTIATE
|
||||||
|
}
|
||||||
|
self.grant['additionalParams'] = {"nfv": "grant"}
|
||||||
|
result = self.userdata_default.instantiate(
|
||||||
|
req, inst, grant_req, self.grant, self.tmp_csar_dir)
|
||||||
|
self.assertIsNotNone(result['template'])
|
||||||
|
self.assertIsNotNone(result['parameters'])
|
||||||
|
self.assertNotIn('req', result['parameters']['nfv'])
|
||||||
|
self.assertIn('grant', result['parameters']['nfv'])
|
||||||
|
self.assertIsNotNone(result['files'])
|
||||||
|
|
||||||
|
def test_scale(self):
|
||||||
|
req = _scale_req_example
|
||||||
|
inst = _vnf_instance_example
|
||||||
|
inst['instantiationState'] = 'INSTANTIATED'
|
||||||
|
inst['instantiatedVnfInfo'] = _inst_info_example
|
||||||
|
grant_req = {
|
||||||
|
"operation": fields.LcmOperationType.SCALE
|
||||||
|
}
|
||||||
|
result = self.userdata_default.scale(
|
||||||
|
req, inst, grant_req, self.grant, self.tmp_csar_dir)
|
||||||
|
self.assertIn('VDU1', result['parameters']['nfv']['VDU'])
|
||||||
|
|
||||||
|
def test_scale_rollback(self):
|
||||||
|
req = _scale_req_example
|
||||||
|
inst = _vnf_instance_example
|
||||||
|
inst['instantiationState'] = 'INSTANTIATED'
|
||||||
|
inst['instantiatedVnfInfo'] = _inst_info_example
|
||||||
|
grant_req = {
|
||||||
|
"operation": fields.LcmOperationType.SCALE
|
||||||
|
}
|
||||||
|
result = self.userdata_default.scale_rollback(
|
||||||
|
req, inst, grant_req, self.grant, self.tmp_csar_dir)
|
||||||
|
self.assertIn('VDU1', result['parameters']['nfv']['VDU'])
|
||||||
|
|
||||||
|
def test_change_ext_conn(self):
|
||||||
|
req = _change_ext_conn_req_example
|
||||||
|
inst = _vnf_instance_example
|
||||||
|
inst['instantiationState'] = 'INSTANTIATED'
|
||||||
|
inst['instantiatedVnfInfo'] = _inst_info_example
|
||||||
|
grant_req = {
|
||||||
|
"operation": fields.LcmOperationType.CHANGE_EXT_CONN
|
||||||
|
}
|
||||||
|
result = self.userdata_default.change_ext_conn(
|
||||||
|
req, inst, grant_req, self.grant, self.tmp_csar_dir)
|
||||||
|
self.assertIn('VDU1_CP2', result['parameters']['nfv']['CP'])
|
||||||
|
self.assertIn('VDU2_CP1', result['parameters']['nfv']['CP'])
|
||||||
|
self.assertIn('VDU2_CP2', result['parameters']['nfv']['CP'])
|
||||||
|
|
||||||
|
def test_change_ext_conn_rollback(self):
|
||||||
|
req = _change_ext_conn_req_example
|
||||||
|
inst = _vnf_instance_example
|
||||||
|
inst['instantiationState'] = 'INSTANTIATED'
|
||||||
|
inst['instantiatedVnfInfo'] = _inst_info_example
|
||||||
|
grant_req = {
|
||||||
|
"operation": fields.LcmOperationType.CHANGE_EXT_CONN
|
||||||
|
}
|
||||||
|
result = self.userdata_default.change_ext_conn_rollback(
|
||||||
|
req, inst, grant_req, self.grant, self.tmp_csar_dir)
|
||||||
|
self.assertIn('VDU1_CP2', result['parameters']['nfv']['CP'])
|
||||||
|
self.assertIn('VDU2_CP1', result['parameters']['nfv']['CP'])
|
||||||
|
self.assertIn('VDU2_CP2', result['parameters']['nfv']['CP'])
|
||||||
|
|
||||||
|
def test_heal(self):
|
||||||
|
result = self.userdata_default.heal(None, None, None, None, None)
|
||||||
|
self.assertEqual({}, result['parameters']['nfv'])
|
|
@ -0,0 +1,749 @@
|
||||||
|
# Copyright (C) 2022 FUJITSU
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from datetime import datetime
|
||||||
|
import os
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.objects import vnf_package
|
||||||
|
from tacker.objects import vnf_package_vnfd
|
||||||
|
from tacker.sol_refactored.api import api_version
|
||||||
|
from tacker.sol_refactored.common import config
|
||||||
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||||
|
from tacker.sol_refactored.common import lcm_op_occ_utils as lcmocc_utils
|
||||||
|
from tacker.sol_refactored.common import vnf_instance_utils as inst_utils
|
||||||
|
from tacker.sol_refactored.nfvo import glance_utils
|
||||||
|
from tacker.sol_refactored.nfvo import local_nfvo
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
|
from tacker.sol_refactored.objects.v2 import fields
|
||||||
|
from tacker.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
||||||
|
SAMPLE_VNFPKG_ID = "d04753f1-493e-17dc-e4a9-65f73b3ccc24"
|
||||||
|
_inst_grant_req_example = {
|
||||||
|
"vnfInstanceId": "2d004394-d0f0-406d-845a-2b148f91039a",
|
||||||
|
"vnfLcmOpOccId": "34da9ba7-6ab1-4d8d-a68a-68892e56642c",
|
||||||
|
"vnfdId": "b1bb0ce7-ebca-4fa7-95ed-4840d7000000",
|
||||||
|
"flavourId": "simple",
|
||||||
|
"operation": "INSTANTIATE",
|
||||||
|
"isAutomaticInvocation": False,
|
||||||
|
"instantiationLevelId": "instantiation_level_2",
|
||||||
|
"addResources": [{
|
||||||
|
"id": "6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP5-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP2-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP1-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP3-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP4-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "a411a968-c00b-4d46-8553-a37f3537391e",
|
||||||
|
"type": "VL",
|
||||||
|
"resourceTemplateId": "internalVL2"
|
||||||
|
}, {
|
||||||
|
"id": "f06ba7cf-f5af-4856-8d3a-56b331d1b9a5",
|
||||||
|
"type": "VL",
|
||||||
|
"resourceTemplateId": "internalVL3"
|
||||||
|
}],
|
||||||
|
"placementConstraints": [{
|
||||||
|
"affinityOrAntiAffinity": "ANTI_AFFINITY",
|
||||||
|
"scope": "NFVI_NODE",
|
||||||
|
"resource": [{
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "6396a2a1-7e36-49bd-8fff-2d46394a6b29"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "39e0af93-aba5-4a15-9231-cdaa4149738e"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "8a3ab83f-187c-4feb-b1b5-a6bf587130fa"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "3f2385fa-3f13-436d-b93a-47c62ef237e0"
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"_links": {
|
||||||
|
"vnfLcmOpOcc": {
|
||||||
|
"href": "http://127.0.0.1:9890/vnflcm/v2/vnf_lcm_op_occs/"
|
||||||
|
"34da9ba7-6ab1-4d8d-a68a-68892e56642c"
|
||||||
|
},
|
||||||
|
"vnfInstance": {
|
||||||
|
"href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/"
|
||||||
|
"2d004394-d0f0-406d-845a-2b148f91039a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_inst_req_example = {
|
||||||
|
"vimConnectionInfo": {
|
||||||
|
"vim1": {
|
||||||
|
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",
|
||||||
|
"vimId": uuidutils.generate_uuid(),
|
||||||
|
"interfaceInfo": {"endpoint": "http://localhost/identity/v3"},
|
||||||
|
"accessInfo": {
|
||||||
|
"username": "nfv_user",
|
||||||
|
"region": "RegionOne",
|
||||||
|
"password": "devstack",
|
||||||
|
"project": "nfv",
|
||||||
|
"projectDomain": "Default",
|
||||||
|
"userDomain": "Default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_change_vnfkg_grant_req_example = {
|
||||||
|
'vnfInstanceId': '5eb4b136-6dac-4af1-b880-4e5eea6ec358',
|
||||||
|
'vnfLcmOpOccId': '4ed07654-d459-4ae7-85c5-bed63c563646',
|
||||||
|
'vnfdId': '1440b128-be42-4eed-9c4b-7df4b59c35d2',
|
||||||
|
'dstVnfdId': 'b1bb0ce7-ebca-4fa7-95ed-4840d7000000',
|
||||||
|
'flavourId': 'simple',
|
||||||
|
'operation': 'CHANGE_VNFPKG',
|
||||||
|
'isAutomaticInvocation': False,
|
||||||
|
'addResources': [{
|
||||||
|
'id': 'aab5201a-7516-41d9-9bf3-6a2579df7004',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU2'
|
||||||
|
}, {
|
||||||
|
'id': '36027157-a86b-4294-95e8-4ebd4bd91abf',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1'
|
||||||
|
}, {
|
||||||
|
'id': 'VirtualStorage-36027157-a86b-4294-95e8-4ebd4bd91abf',
|
||||||
|
'type': 'STORAGE',
|
||||||
|
'resourceTemplateId': 'VirtualStorage'
|
||||||
|
}, {
|
||||||
|
'id': 'cf40bb5a-046d-4113-b69b-9e34878ba781',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1'
|
||||||
|
}, {
|
||||||
|
'id': 'VirtualStorage-cf40bb5a-046d-4113-b69b-9e34878ba781',
|
||||||
|
'type': 'STORAGE',
|
||||||
|
'resourceTemplateId': 'VirtualStorage'
|
||||||
|
}, {
|
||||||
|
'id': '7c093596-c98c-40a0-b2cb-f0c30ce6fb87',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1'
|
||||||
|
}],
|
||||||
|
'removeResources': [{
|
||||||
|
'id': '0c8c248d-69cd-4dde-8b75-9791a02899c8',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU2',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU2',
|
||||||
|
'vimLevelResourceType': 'OS::Nova::Server'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': '374dfdae-6add-4a96-a37f-95b8e1b3f79b',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_1',
|
||||||
|
'vimLevelResourceType': 'OS::Nova::Server'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VirtualStorage-374dfdae-6add-4a96-a37f-95b8e1b3f79b',
|
||||||
|
'type': 'STORAGE',
|
||||||
|
'resourceTemplateId': 'VirtualStorage',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VirtualStorage_1',
|
||||||
|
'vimLevelResourceType': 'OS::Cinder::Volume'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': '4e601248-185f-4405-91bb-ea579c1b866b',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_2',
|
||||||
|
'vimLevelResourceType': 'OS::Nova::Server'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'VirtualStorage-4e601248-185f-4405-91bb-ea579c1b866b',
|
||||||
|
'type': 'STORAGE',
|
||||||
|
'resourceTemplateId': 'VirtualStorage',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VirtualStorage_2',
|
||||||
|
'vimLevelResourceType': 'OS::Cinder::Volume'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': 'cd8bee39-a7b1-4652-8de4-56f5863c9157',
|
||||||
|
'type': 'COMPUTE',
|
||||||
|
'resourceTemplateId': 'VDU1',
|
||||||
|
'resource': {
|
||||||
|
'resourceId': 'res_id_VDU1_3',
|
||||||
|
'vimLevelResourceType': 'OS::Nova::Server'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'_links': {
|
||||||
|
'vnfLcmOpOcc': {
|
||||||
|
'href': 'http://127.0.0.1:9890/vnflcm/v2/vnf_lcm_op_occs/'
|
||||||
|
'4ed07654-d459-4ae7-85c5-bed63c563646'
|
||||||
|
},
|
||||||
|
'vnfInstance': {
|
||||||
|
'href': 'http://127.0.0.1:9890/vnflcm/v2/vnf_instances/'
|
||||||
|
'5eb4b136-6dac-4af1-b880-4e5eea6ec358'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_change_vnfpkg_example = {
|
||||||
|
"vnfdId": '61723406-6634-2fc0-060a-0b11104d2667',
|
||||||
|
"additionalParams": {
|
||||||
|
"upgrade_type": "RollingUpdate",
|
||||||
|
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
|
||||||
|
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
|
||||||
|
"vdu_params": [{
|
||||||
|
"vdu_id": "VDU1",
|
||||||
|
"old_vnfc_param": {
|
||||||
|
"cp_name": "CP1",
|
||||||
|
"username": "ubuntu",
|
||||||
|
"password": "ubuntu"},
|
||||||
|
"new_vnfc_param": {
|
||||||
|
"cp_name": "CP1",
|
||||||
|
"username": "ubuntu",
|
||||||
|
"password": "ubuntu"},
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
|
class TestLocalNfvo(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestLocalNfvo, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
CONF.vnf_package.vnf_package_csar_path = (
|
||||||
|
'/opt/stack/data/tacker/vnfpackage/')
|
||||||
|
self.context.api_version = api_version.APIVersion('2.0.0')
|
||||||
|
self.local_nfvo = local_nfvo.LocalNfvo()
|
||||||
|
|
||||||
|
def _get_vnfpkg_or_vnfd(
|
||||||
|
self, type, state=fields.PackageOnboardingStateType.ONBOARDED):
|
||||||
|
if type == 'vnfd':
|
||||||
|
return vnf_package_vnfd.VnfPackageVnfd(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
package_uuid=SAMPLE_VNFPKG_ID, vnfd_id=SAMPLE_VNFD_ID,
|
||||||
|
vnf_provider='provider', vnf_product_name='product',
|
||||||
|
vnf_software_version='2.0', vnfd_version='3.3.1')
|
||||||
|
else:
|
||||||
|
return vnf_package.VnfPackage(
|
||||||
|
id=SAMPLE_VNFPKG_ID,
|
||||||
|
onboarding_state=state,
|
||||||
|
operational_state=fields.PackageOperationalStateType.DISABLED)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'get_by_id')
|
||||||
|
def test_onboarded_show(self, mock_vnfpackage, mock_vnfd):
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_vnfpackage.return_value = self._get_vnfpkg_or_vnfd('vnfpkg')
|
||||||
|
result = self.local_nfvo.onboarded_show(self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual(SAMPLE_VNFPKG_ID, result.id)
|
||||||
|
self.assertEqual(SAMPLE_VNFD_ID, result.vnfdId)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'get_by_id')
|
||||||
|
def test_onboarded_show_vnfpackage_error(self, mock_vnfpackage, mock_vnfd):
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfdIdNotFound, self.local_nfvo.onboarded_show,
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'get_by_id')
|
||||||
|
def test_onboarded_show_error(self, mock_vnfpackage, mock_vnfd):
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_vnfpackage.return_value = self._get_vnfpkg_or_vnfd(
|
||||||
|
'vnfpkg', fields.PackageOnboardingStateType.CREATED)
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfdIdNotFound, self.local_nfvo.onboarded_show,
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(os.path, 'isdir')
|
||||||
|
def test_get_csar_dir(self, mock_isdir, mock_vnfd):
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_isdir.return_value = True
|
||||||
|
result = self.local_nfvo.get_csar_dir(self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual(
|
||||||
|
f'/opt/stack/data/tacker/vnfpackage/{SAMPLE_VNFPKG_ID}', result)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
def test_get_csar_dir_vnfd_error(self, mock_vnfd):
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfdIdNotFound, self.local_nfvo.get_csar_dir,
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(os.path, 'isdir')
|
||||||
|
def test_get_csar_dir_path_error(self, mock_isdir, mock_vnfd):
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_isdir.return_value = False
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.VnfdIdNotFound, self.local_nfvo.get_csar_dir,
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
def test_get_vnfd(self, mock_dir):
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
result = self.local_nfvo.get_vnfd(self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual(SAMPLE_VNFD_ID, result.vnfd_id)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(lcmocc_utils, 'get_lcmocc')
|
||||||
|
@mock.patch.object(glance_utils.GlanceClient, 'create_image')
|
||||||
|
def test_instantiate_grant(self, mock_image, mock_lcmocc, mock_dir):
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_inst_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(_inst_req_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
# only set used members in the method
|
||||||
|
operation=fields.LcmOperationType.INSTANTIATE,
|
||||||
|
operationParams=req)
|
||||||
|
mock_image.return_value = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
self.local_nfvo.instantiate_grant(self.context, grant_req, grant_res)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertIsNotNone(result['addResources'])
|
||||||
|
self.assertEqual(mock_image.return_value.id, result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, '_get_vim_info')
|
||||||
|
def test_instantiate_grant_no_vim_info(self, mock_vim_info, mock_dir):
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_inst_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
mock_vim_info.return_value = None
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.LocalNfvoGrantFailed, self.local_nfvo.instantiate_grant,
|
||||||
|
self.context, grant_req, grant_res)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(lcmocc_utils, 'get_lcmocc')
|
||||||
|
@mock.patch.object(glance_utils.GlanceClient, 'create_image')
|
||||||
|
def test_instantiate_grant_no_image(
|
||||||
|
self, mock_image, mock_lcmocc, mock_dir):
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_inst_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(_inst_req_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
# only set used members in the method
|
||||||
|
operation=fields.LcmOperationType.INSTANTIATE,
|
||||||
|
operationParams=req)
|
||||||
|
mock_image.return_value = Exception()
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.LocalNfvoGrantFailed, self.local_nfvo.instantiate_grant,
|
||||||
|
self.context, grant_req, grant_res)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(lcmocc_utils, 'get_lcmocc')
|
||||||
|
@mock.patch.object(glance_utils.GlanceClient, 'create_image')
|
||||||
|
@mock.patch.object(inst_utils, 'get_inst')
|
||||||
|
def test_change_vnfpkg_grant(self, mock_inst, mock_image,
|
||||||
|
mock_lcmocc, mock_dir):
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(
|
||||||
|
_change_vnfkg_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||||
|
_change_vnfpkg_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||||
|
operationParams=req)
|
||||||
|
mock_image.return_value = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
mock_inst.return_value = inst
|
||||||
|
self.local_nfvo.change_vnfpkg_grant(self.context, grant_req, grant_res)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertEqual(mock_image.return_value.id, result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, '_get_vim_info')
|
||||||
|
def test_change_vnfpkg_grant_no_vim_info(self, mock_vim_info, mock_dir):
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(
|
||||||
|
_change_vnfkg_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
mock_vim_info.return_value = None
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.LocalNfvoGrantFailed, self.local_nfvo.change_vnfpkg_grant,
|
||||||
|
self.context, grant_req, grant_res)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(lcmocc_utils, 'get_lcmocc')
|
||||||
|
@mock.patch.object(glance_utils.GlanceClient, 'create_image')
|
||||||
|
@mock.patch.object(inst_utils, 'get_inst')
|
||||||
|
def test_change_vnfpkg_grant_no_image(self, mock_inst, mock_image,
|
||||||
|
mock_lcmocc, mock_dir):
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(
|
||||||
|
_change_vnfkg_grant_req_example)
|
||||||
|
grant_res = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfInstanceId=grant_req.vnfInstanceId,
|
||||||
|
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||||
|
)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||||
|
_change_vnfpkg_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||||
|
operationParams=req)
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
mock_inst.return_value = inst
|
||||||
|
mock_image.return_value = Exception()
|
||||||
|
self.assertRaises(
|
||||||
|
sol_ex.LocalNfvoGrantFailed, self.local_nfvo.change_vnfpkg_grant,
|
||||||
|
self.context, grant_req, grant_res)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'get_csar_dir')
|
||||||
|
@mock.patch.object(lcmocc_utils, 'get_lcmocc')
|
||||||
|
@mock.patch.object(glance_utils.GlanceClient, 'create_image')
|
||||||
|
@mock.patch.object(inst_utils, 'get_inst')
|
||||||
|
def test_grant(self, mock_inst, mock_image, mock_lcmocc, mock_dir):
|
||||||
|
# instantiate
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_inst_grant_req_example)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(_inst_req_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
# only set used members in the method
|
||||||
|
operation=fields.LcmOperationType.INSTANTIATE,
|
||||||
|
operationParams=req)
|
||||||
|
mock_image.return_value = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
grant_res = self.local_nfvo.grant(self.context, grant_req)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertIsNotNone(result['addResources'])
|
||||||
|
self.assertEqual(mock_image.return_value.id, result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
# change_vnfpkg
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(
|
||||||
|
_change_vnfkg_grant_req_example)
|
||||||
|
cur_dir = os.path.dirname(__file__)
|
||||||
|
sample_dir = os.path.join(cur_dir, "..", "samples")
|
||||||
|
mock_dir.return_value = os.path.join(sample_dir, "sample1")
|
||||||
|
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||||
|
_change_vnfpkg_example)
|
||||||
|
mock_lcmocc.return_value = objects.VnfLcmOpOccV2(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||||
|
operationParams=req
|
||||||
|
)
|
||||||
|
mock_image.return_value = objects.GrantV1(
|
||||||
|
id=uuidutils.generate_uuid()
|
||||||
|
)
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
mock_inst.return_value = inst
|
||||||
|
grant_res = self.local_nfvo.grant(self.context, grant_req)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertEqual(mock_image.return_value.id, result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'save')
|
||||||
|
def test_recv_inst_create_notification(
|
||||||
|
self, mock_save, mock_vnfpackage, mock_vnfd):
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='NOT_INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_vnfpackage.return_value = self._get_vnfpkg_or_vnfd('vnfpkg')
|
||||||
|
self.local_nfvo.recv_inst_create_notification(self.context, inst)
|
||||||
|
|
||||||
|
@mock.patch.object(vnf_package_vnfd.VnfPackageVnfd, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'get_by_id')
|
||||||
|
@mock.patch.object(vnf_package.VnfPackage, 'save')
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_by_filter')
|
||||||
|
def test_recv_inst_delete_notification(
|
||||||
|
self, mock_inst, mock_save, mock_vnfpackage, mock_vnfd):
|
||||||
|
req = objects.InstantiateVnfRequest.from_dict(
|
||||||
|
_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req.vimConnectionInfo
|
||||||
|
)
|
||||||
|
mock_inst.return_value = None
|
||||||
|
mock_vnfd.return_value = self._get_vnfpkg_or_vnfd('vnfd')
|
||||||
|
mock_vnfpackage.return_value = self._get_vnfpkg_or_vnfd('vnfpkg')
|
||||||
|
self.local_nfvo.recv_inst_delete_notification(self.context, inst)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, '_glance_delete_images')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, '_update_vnf_pkg_usage_state')
|
||||||
|
def test_recv_lcmocc_notification(self, mock_delete_image, mock_update):
|
||||||
|
# terminate-processing
|
||||||
|
|
||||||
|
req_inst = objects.InstantiateVnfRequest.from_dict(_inst_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED',
|
||||||
|
vimConnectionInfo=req_inst.vimConnectionInfo,
|
||||||
|
)
|
||||||
|
req = objects.TerminateVnfRequest(terminationType='FORCEFUL')
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
operationState=fields.LcmOperationStateType.PROCESSING,
|
||||||
|
stateEnteredTime=datetime.utcnow(),
|
||||||
|
startTime=datetime.utcnow(),
|
||||||
|
vnfInstanceId=inst.id,
|
||||||
|
operation=fields.LcmOperationType.TERMINATE,
|
||||||
|
isAutomaticInvocation=False,
|
||||||
|
isCancelPending=False,
|
||||||
|
operationParams=req)
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
||||||
|
|
||||||
|
# terminate-failed_temp
|
||||||
|
lcmocc.operationState = fields.LcmOperationStateType.FAILED_TEMP
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
||||||
|
|
||||||
|
# terminate-completed
|
||||||
|
self.local_nfvo.inst_vim_info = {
|
||||||
|
inst.id: req_inst.vimConnectionInfo['vim1']
|
||||||
|
}
|
||||||
|
lcmocc.operationState = fields.LcmOperationStateType.COMPLETED
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
||||||
|
|
||||||
|
# change_vnfpkg-processing
|
||||||
|
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||||
|
_change_vnfpkg_example)
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
operationState=fields.LcmOperationStateType.PROCESSING,
|
||||||
|
stateEnteredTime=datetime.utcnow(),
|
||||||
|
startTime=datetime.utcnow(),
|
||||||
|
vnfInstanceId=inst.id,
|
||||||
|
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||||
|
isAutomaticInvocation=False,
|
||||||
|
isCancelPending=False,
|
||||||
|
operationParams=req)
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
||||||
|
|
||||||
|
# change_vnfpkg-failed_temp
|
||||||
|
lcmocc.operationState = fields.LcmOperationStateType.FAILED_TEMP
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
||||||
|
|
||||||
|
# change_vnfpkg-completed
|
||||||
|
self.local_nfvo.inst_vnfd_id = {inst.id: req.vnfdId}
|
||||||
|
lcmocc.operationState = fields.LcmOperationStateType.COMPLETED
|
||||||
|
self.local_nfvo.recv_lcmocc_notification(self.context, lcmocc, inst)
|
|
@ -0,0 +1,421 @@
|
||||||
|
# Copyright (C) 2022 FUJITSU
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
import requests
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from tacker import context
|
||||||
|
from tacker.sol_refactored.api import api_version
|
||||||
|
from tacker.sol_refactored.common import config
|
||||||
|
from tacker.sol_refactored.common import http_client
|
||||||
|
from tacker.sol_refactored.common import subscription_utils as subsc_utils
|
||||||
|
from tacker.sol_refactored.common import vnfd_utils
|
||||||
|
from tacker.sol_refactored.nfvo import local_nfvo
|
||||||
|
from tacker.sol_refactored.nfvo import nfvo_client
|
||||||
|
from tacker.sol_refactored import objects
|
||||||
|
from tacker.tests import base
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
||||||
|
_vnfpkg_body_example = {
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"vnfdId": SAMPLE_VNFD_ID,
|
||||||
|
"vnfProvider": "Company",
|
||||||
|
"vnfProductName": "Sample VNF",
|
||||||
|
"vnfSoftwareVersion": "1.0",
|
||||||
|
"vnfdVersion": "1.0",
|
||||||
|
"onboardingState": "ONBOARDED",
|
||||||
|
"operationalState": "ENABLED",
|
||||||
|
"usageState": "NOT_IN_USE"
|
||||||
|
}
|
||||||
|
_grant_res = {
|
||||||
|
'id': 'b94d05c9-eb45-4855-9132-20e1d3e7cecf',
|
||||||
|
'vnfInstanceId': '2d004394-d0f0-406d-845a-2b148f91039a',
|
||||||
|
'vnfLcmOpOccId': '34da9ba7-6ab1-4d8d-a68a-68892e56642c',
|
||||||
|
'zones': [{
|
||||||
|
'id': 'b4eba78c-e957-4e66-8bd7-14822f954413',
|
||||||
|
'zoneId': 'nova'
|
||||||
|
}],
|
||||||
|
'addResources': [{
|
||||||
|
'resourceDefinitionId': '6396a2a1-7e36-49bd-8fff-2d46394a6b29',
|
||||||
|
'zoneId': 'b4eba78c-e957-4e66-8bd7-14822f954413'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP1-6396a2a1-7e36-49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP2-6396a2a1-7e36-49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP3-6396a2a1-7e36-49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP5-6396a2a1-7e36-49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP4-6396a2a1-7e36-49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VirtualStorage-6396a2a1-7e36-'
|
||||||
|
'49bd-8fff-2d46394a6b29'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': '39e0af93-aba5-4a15-9231-cdaa4149738e',
|
||||||
|
'zoneId': 'b4eba78c-e957-4e66-8bd7-14822f954413'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP1-39e0af93-aba5-4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP2-39e0af93-aba5-4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP3-39e0af93-aba5-4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP5-39e0af93-aba5-4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP4-39e0af93-aba5-4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VirtualStorage-39e0af93-aba5-'
|
||||||
|
'4a15-9231-cdaa4149738e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': '8a3ab83f-187c-4feb-b1b5-a6bf587130fa',
|
||||||
|
'zoneId': 'b4eba78c-e957-4e66-8bd7-14822f954413'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP1-8a3ab83f-187c-4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP2-8a3ab83f-187c-4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP3-8a3ab83f-187c-4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP5-8a3ab83f-187c-4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU1_CP4-8a3ab83f-187c-4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VirtualStorage-8a3ab83f-187c-'
|
||||||
|
'4feb-b1b5-a6bf587130fa'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': '3f2385fa-3f13-436d-b93a-47c62ef237e0',
|
||||||
|
'zoneId': 'b4eba78c-e957-4e66-8bd7-14822f954413'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU2_CP5-3f2385fa-3f13-436d-b93a-47c62ef237e0'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU2_CP2-3f2385fa-3f13-436d-b93a-47c62ef237e0'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU2_CP1-3f2385fa-3f13-436d-b93a-47c62ef237e0'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU2_CP3-3f2385fa-3f13-436d-b93a-47c62ef237e0'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'VDU2_CP4-3f2385fa-3f13-436d-b93a-47c62ef237e0'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'a411a968-c00b-4d46-8553-a37f3537391e'
|
||||||
|
}, {
|
||||||
|
'resourceDefinitionId': 'f06ba7cf-f5af-4856-8d3a-56b331d1b9a5'
|
||||||
|
}],
|
||||||
|
'vimAssets': {
|
||||||
|
'softwareImages': [{
|
||||||
|
'vnfdSoftwareImageId': 'VDU2',
|
||||||
|
'vimSoftwareImageId': '44fd5841-ce98-4d54-a828-6ef51f941c8a'
|
||||||
|
}, {
|
||||||
|
'vnfdSoftwareImageId': 'VirtualStorage',
|
||||||
|
'vimSoftwareImageId': 'image-1.0.0-x86_64-disk'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_inst_grant_req_example = {
|
||||||
|
"vnfInstanceId": "2d004394-d0f0-406d-845a-2b148f91039a",
|
||||||
|
"vnfLcmOpOccId": "34da9ba7-6ab1-4d8d-a68a-68892e56642c",
|
||||||
|
"vnfdId": "b1bb0ce7-ebca-4fa7-95ed-4840d7000000",
|
||||||
|
"flavourId": "simple",
|
||||||
|
"operation": "INSTANTIATE",
|
||||||
|
"isAutomaticInvocation": False,
|
||||||
|
"instantiationLevelId": "instantiation_level_2",
|
||||||
|
"addResources": [{
|
||||||
|
"id": "6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-6396a2a1-7e36-49bd-8fff-2d46394a6b29",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-39e0af93-aba5-4a15-9231-cdaa4149738e",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP1-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP2-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP3-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP5-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU1_CP4-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU1_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "VirtualStorage-8a3ab83f-187c-4feb-b1b5-a6bf587130fa",
|
||||||
|
"type": "STORAGE",
|
||||||
|
"resourceTemplateId": "VirtualStorage"
|
||||||
|
}, {
|
||||||
|
"id": "3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "COMPUTE",
|
||||||
|
"resourceTemplateId": "VDU2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP5-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP5"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP2-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP2"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP1-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP1"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP3-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP3"
|
||||||
|
}, {
|
||||||
|
"id": "VDU2_CP4-3f2385fa-3f13-436d-b93a-47c62ef237e0",
|
||||||
|
"type": "LINKPORT",
|
||||||
|
"resourceTemplateId": "VDU2_CP4"
|
||||||
|
}, {
|
||||||
|
"id": "a411a968-c00b-4d46-8553-a37f3537391e",
|
||||||
|
"type": "VL",
|
||||||
|
"resourceTemplateId": "internalVL2"
|
||||||
|
}, {
|
||||||
|
"id": "f06ba7cf-f5af-4856-8d3a-56b331d1b9a5",
|
||||||
|
"type": "VL",
|
||||||
|
"resourceTemplateId": "internalVL3"
|
||||||
|
}],
|
||||||
|
"placementConstraints": [{
|
||||||
|
"affinityOrAntiAffinity": "ANTI_AFFINITY",
|
||||||
|
"scope": "NFVI_NODE",
|
||||||
|
"resource": [{
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "6396a2a1-7e36-49bd-8fff-2d46394a6b29"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "39e0af93-aba5-4a15-9231-cdaa4149738e"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "8a3ab83f-187c-4feb-b1b5-a6bf587130fa"
|
||||||
|
}, {
|
||||||
|
"idType": "GRANT",
|
||||||
|
"resourceId": "3f2385fa-3f13-436d-b93a-47c62ef237e0"
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"_links": {
|
||||||
|
"vnfLcmOpOcc": {
|
||||||
|
"href": "http://127.0.0.1:9890/vnflcm/v2/vnf_lcm_op_occs/"
|
||||||
|
"34da9ba7-6ab1-4d8d-a68a-68892e56642c"
|
||||||
|
},
|
||||||
|
"vnfInstance": {
|
||||||
|
"href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/"
|
||||||
|
"2d004394-d0f0-406d-845a-2b148f91039a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_lcmocc_inst_value = {
|
||||||
|
'id': 'test-1',
|
||||||
|
'vnfInstanceId': 'instance-1',
|
||||||
|
'operation': 'INSTANTIATE',
|
||||||
|
'operationState': 'COMPLETED',
|
||||||
|
'isAutomaticInvocation': False,
|
||||||
|
'startTime': '2021-01-23 13:41:03+00:00'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestNfvoClient(base.BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestNfvoClient, self).setUp()
|
||||||
|
objects.register_all()
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
CONF.vnf_package.vnf_package_csar_path = (
|
||||||
|
'/opt/stack/data/tacker/vnfpackage/')
|
||||||
|
self.context.api_version = api_version.APIVersion('2.0.0')
|
||||||
|
self.nfvo_client = nfvo_client.NfvoClient()
|
||||||
|
self.nfvo_client.endpoint = 'http://127.0.0.1:9990'
|
||||||
|
auth_handle = http_client.OAuth2AuthHandle(
|
||||||
|
self.nfvo_client.endpoint,
|
||||||
|
'http://127.0.0.1:9990/token',
|
||||||
|
'test',
|
||||||
|
'test'
|
||||||
|
)
|
||||||
|
self.nfvo_client.client = http_client.HttpClient(auth_handle)
|
||||||
|
self.nfvo_client.grant_api_version = '1.4.0'
|
||||||
|
self.nfvo_client.vnfpkgm_api_version = '2.1.0'
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'onboarded_show')
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_get_vnf_package_info_vnfd(
|
||||||
|
self, mock_request, mock_onboarded_show):
|
||||||
|
# local nfvo
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
mock_onboarded_show.return_value = vnfd_utils.Vnfd(
|
||||||
|
vnfd_id=SAMPLE_VNFD_ID)
|
||||||
|
result = self.nfvo_client.get_vnf_package_info_vnfd(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual(SAMPLE_VNFD_ID, result.vnfd_id)
|
||||||
|
|
||||||
|
# external nfvo
|
||||||
|
self.nfvo_client.is_local = False
|
||||||
|
mock_request.return_value = (requests.Response(), _vnfpkg_body_example)
|
||||||
|
result = self.nfvo_client.get_vnf_package_info_vnfd(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual(SAMPLE_VNFD_ID, result.vnfdId)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_onboarded_show_vnfd(self, mock_request):
|
||||||
|
# local nfvo
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
result = self.nfvo_client.onboarded_show_vnfd(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
# external nfvo
|
||||||
|
self.nfvo_client.is_local = False
|
||||||
|
mock_request.return_value = (requests.Response(), 'test')
|
||||||
|
result = self.nfvo_client.onboarded_show_vnfd(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual('test', result)
|
||||||
|
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_onboarded_package_content(self, mock_request):
|
||||||
|
# local nfvo
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
result = self.nfvo_client.onboarded_package_content(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
# external nfvo
|
||||||
|
self.nfvo_client.is_local = False
|
||||||
|
mock_request.return_value = (requests.Response(), 'test')
|
||||||
|
result = self.nfvo_client.onboarded_package_content(
|
||||||
|
self.context, SAMPLE_VNFD_ID)
|
||||||
|
self.assertEqual('test', result)
|
||||||
|
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'grant')
|
||||||
|
@mock.patch.object(http_client.HttpClient, 'do_request')
|
||||||
|
def test_grant(self, mock_request, mock_grant):
|
||||||
|
# local nfvo
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
mock_grant.return_value = objects.GrantV1.from_dict(_grant_res)
|
||||||
|
grant_req = objects.GrantRequestV1.from_dict(_inst_grant_req_example)
|
||||||
|
grant_res = self.nfvo_client.grant(self.context, grant_req)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertIsNotNone(result['addResources'])
|
||||||
|
self.assertEqual('44fd5841-ce98-4d54-a828-6ef51f941c8a', result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
# external nfvo
|
||||||
|
self.nfvo_client.is_local = False
|
||||||
|
mock_request.return_value = (requests.Response(), _grant_res)
|
||||||
|
grant_res = self.nfvo_client.grant(self.context, grant_req)
|
||||||
|
result = grant_res.to_dict()
|
||||||
|
self.assertIsNotNone(result['addResources'])
|
||||||
|
self.assertEqual('44fd5841-ce98-4d54-a828-6ef51f941c8a', result[
|
||||||
|
'vimAssets']['softwareImages'][0]['vimSoftwareImageId'])
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
@mock.patch.object(subsc_utils, 'send_notification')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'recv_inst_create_notification')
|
||||||
|
def test_send_inst_create_notification(
|
||||||
|
self, mock_recv, mock_send, mock_subscs):
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
self.nfvo_client.send_inst_create_notification(
|
||||||
|
self.context, inst, 'http://127.0.0.1:9890')
|
||||||
|
self.assertEqual(1, mock_recv.call_count)
|
||||||
|
self.assertEqual(1, mock_send.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
@mock.patch.object(subsc_utils, 'send_notification')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'recv_inst_delete_notification')
|
||||||
|
def test_send_inst_delete_notification(
|
||||||
|
self, mock_recv, mock_send, mock_subscs):
|
||||||
|
self.nfvo_client.is_local = True
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(id='subsc-1')]
|
||||||
|
self.nfvo_client.send_inst_delete_notification(
|
||||||
|
self.context, inst, 'http://127.0.0.1:9890')
|
||||||
|
self.assertEqual(1, mock_recv.call_count)
|
||||||
|
self.assertEqual(1, mock_send.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(objects.base.TackerPersistentObject, 'get_all')
|
||||||
|
@mock.patch.object(subsc_utils, 'send_notification')
|
||||||
|
@mock.patch.object(local_nfvo.LocalNfvo, 'recv_lcmocc_notification')
|
||||||
|
def test_send_lcmocc_notification(self, mock_recv, mock_send, mock_subscs):
|
||||||
|
inst = objects.VnfInstanceV2(id='test-instance')
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2.from_dict(_lcmocc_inst_value)
|
||||||
|
mock_subscs.return_value = [objects.LccnSubscriptionV2(
|
||||||
|
id='subsc-1', verbosity='FULL')]
|
||||||
|
self.nfvo_client.send_lcmocc_notification(
|
||||||
|
self.context, lcmocc, inst, 'http://127.0.0.1:9890')
|
||||||
|
self.assertEqual(1, mock_recv.call_count)
|
||||||
|
self.assertEqual(1, mock_send.call_count)
|
|
@ -0,0 +1,122 @@
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
description: 'Simple Base HOT for Sample VNF'
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
nfv:
|
||||||
|
type: json
|
||||||
|
|
||||||
|
resources:
|
||||||
|
VDU1_scale_group:
|
||||||
|
type: OS::Heat::AutoScalingGroup
|
||||||
|
properties:
|
||||||
|
min_size: 1
|
||||||
|
max_size: 3
|
||||||
|
desired_capacity: 1
|
||||||
|
resource:
|
||||||
|
type: VDU1.yaml
|
||||||
|
properties:
|
||||||
|
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||||
|
image: { get_param: [ nfv, VDU, VirtualStorage, vcImageId ] }
|
||||||
|
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
||||||
|
net2: { get_param: [ nfv, CP, VDU1_CP2, network ] }
|
||||||
|
subnet: { get_param: [nfv, CP, VDU1_CP2, fixed_ips, 0, subnet ]}
|
||||||
|
net3: { get_resource: internalVL1 }
|
||||||
|
net4: { get_resource: internalVL2 }
|
||||||
|
net5: { get_resource: internalVL3 }
|
||||||
|
net6: { get_param: { nfv, CP, VDU1_CP6, network } }
|
||||||
|
net7: { get_param: [ nfv, CP, VDU1_CP7 ] }
|
||||||
|
net8: { get_param: [ nfv_1, CP, VDU1_CP8, network ] }
|
||||||
|
affinity: { get_resource: nfvi_node_affinity }
|
||||||
|
|
||||||
|
VDU2:
|
||||||
|
type: OS::Nova::Server
|
||||||
|
properties:
|
||||||
|
flavor: { get_param: [ nfv, VDU, VDU2, computeFlavourId ] }
|
||||||
|
image: { get_param: [ nfv, VDU, VDU2, vcImageId] }
|
||||||
|
networks:
|
||||||
|
- port:
|
||||||
|
get_resource: VDU2_CP1
|
||||||
|
- port:
|
||||||
|
get_resource: VDU2_CP2
|
||||||
|
- port:
|
||||||
|
get_resource: VDU2_CP3
|
||||||
|
- port:
|
||||||
|
get_resource: VDU2_CP4
|
||||||
|
- port:
|
||||||
|
get_resource: VDU2_CP5
|
||||||
|
scheduler_hints:
|
||||||
|
group: {get_resource: nfvi_node_affinity }
|
||||||
|
|
||||||
|
# extVL with FixedIP
|
||||||
|
VDU2_CP1:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: { get_param: [ nfv, CP, VDU2_CP1, network ] }
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: { get_param: [nfv, CP, VDU2_CP1, fixed_ips, 0, ip_address]}
|
||||||
|
|
||||||
|
# extvVL with FixedIP and Subnet
|
||||||
|
VDU2_CP2:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
network: { get_param: [ nfv, CP, VDU2_CP2, network ] }
|
||||||
|
fixed_ips:
|
||||||
|
- ip_address: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, ip_address]}
|
||||||
|
subnet: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, subnet]}
|
||||||
|
|
||||||
|
VDU2_CP3:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
# replace the following line to VL's ID when extmanagedVLs are specified in instantiatevnfrequest
|
||||||
|
network: { get_resource: internalVL1 }
|
||||||
|
|
||||||
|
VDU2_CP4:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
# replace the following line to VL's ID when extmanagedVLs are specified in instantiatevnfrequest
|
||||||
|
network: { get_resource: internalVL2 }
|
||||||
|
|
||||||
|
VDU2_CP5:
|
||||||
|
type: OS::Neutron::Port
|
||||||
|
properties:
|
||||||
|
# replace the following line to VL's ID when extmanagedVLs are specified in instantiatevnfrequest
|
||||||
|
network: { get_resource: internalVL3 }
|
||||||
|
|
||||||
|
# delete the following lines when extmanagedVLs are specified in instantiatevnfrequest
|
||||||
|
internalVL1:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
internalVL2:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
internalVL3:
|
||||||
|
type: OS::Neutron::Net
|
||||||
|
|
||||||
|
|
||||||
|
internalVL1_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
ip_version: 4
|
||||||
|
network:
|
||||||
|
get_resource: internalVL1
|
||||||
|
cidr: 192.168.3.0/24
|
||||||
|
internalVL2_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
ip_version: 4
|
||||||
|
network:
|
||||||
|
get_resource: internalVL2
|
||||||
|
cidr: 192.168.4.0/24
|
||||||
|
internalVL3_subnet:
|
||||||
|
type: OS::Neutron::Subnet
|
||||||
|
properties:
|
||||||
|
ip_version: 4
|
||||||
|
network:
|
||||||
|
get_resource: internalVL3
|
||||||
|
cidr: 192.168.5.0/24
|
||||||
|
|
||||||
|
nfvi_node_affinity:
|
||||||
|
type: OS::Nova::ServerGroup
|
||||||
|
properties:
|
||||||
|
name: nfvi_node_affinity
|
||||||
|
policies: [ 'affinity' ]
|
||||||
|
|
||||||
|
outputs: {}
|
|
@ -11,18 +11,22 @@ resources:
|
||||||
properties:
|
properties:
|
||||||
min_size: 1
|
min_size: 1
|
||||||
max_size: 3
|
max_size: 3
|
||||||
desired_capacity: 1
|
desired_capacity: { get_param: [ nfv, VDU, VDU1, desired_capacity ] }
|
||||||
resource:
|
resource:
|
||||||
type: VDU1.yaml
|
type: VDU1.yaml
|
||||||
properties:
|
properties:
|
||||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||||
image: { get_param: [ nfv, VDU, VirtualStorage, vcImageId ] }
|
image: { get_param: [ nfv, VDU, VirtualStorage, vcImageId ] }
|
||||||
|
zone: { get_param: [ nfv, VDU, VDU1, locationConstraints] }
|
||||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
||||||
net2: { get_param: [ nfv, CP, VDU1_CP2, network ] }
|
net2: { get_param: [ nfv, CP, VDU1_CP2, network ] }
|
||||||
subnet: { get_param: [nfv, CP, VDU1_CP2, fixed_ips, 0, subnet ]}
|
subnet: { get_param: [nfv, CP, VDU1_CP2, fixed_ips, 0, subnet ]}
|
||||||
net3: { get_resource: internalVL1 }
|
net3: { get_resource: internalVL1 }
|
||||||
net4: { get_resource: internalVL2 }
|
net4: { get_resource: internalVL2 }
|
||||||
net5: { get_resource: internalVL3 }
|
net5: { get_resource: internalVL3 }
|
||||||
|
net6: { get_param: { nfv, CP, VDU1_CP6, network } }
|
||||||
|
net7: { get_param: [ nfv, CP, VDU1_CP7 ] }
|
||||||
|
net8: { get_param: [ nfv_1, CP, VDU1_CP8, network ] }
|
||||||
affinity: { get_resource: nfvi_node_affinity }
|
affinity: { get_resource: nfvi_node_affinity }
|
||||||
|
|
||||||
VDU2:
|
VDU2:
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||||
|
|
||||||
|
description: Simple deployment flavour for Sample VNF
|
||||||
|
|
||||||
|
imports:
|
||||||
|
- etsi_nfv_sol001_common_types.yaml
|
||||||
|
- etsi_nfv_sol001_vnfd_types.yaml
|
||||||
|
- v2_sample2_types.yaml
|
||||||
|
|
||||||
|
topology_template:
|
||||||
|
inputs:
|
||||||
|
descriptor_id:
|
||||||
|
type: string
|
||||||
|
descriptor_version:
|
||||||
|
type: string
|
||||||
|
provider:
|
||||||
|
type: string
|
||||||
|
product_name:
|
||||||
|
type: string
|
||||||
|
software_version:
|
||||||
|
type: string
|
||||||
|
vnfm_info:
|
||||||
|
type: list
|
||||||
|
entry_schema:
|
||||||
|
type: string
|
||||||
|
flavour_id:
|
||||||
|
type: string
|
||||||
|
flavour_description:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
substitution_mappings:
|
||||||
|
node_type: company.provider.VNF
|
||||||
|
properties:
|
||||||
|
flavour_id: error
|
||||||
|
requirements:
|
||||||
|
virtual_link_external1_1: [ VDU1_CP1, virtual_link ]
|
||||||
|
virtual_link_external1_2: [ VDU2_CP1, virtual_link ]
|
||||||
|
virtual_link_external2_1: [ VDU1_CP2, virtual_link ]
|
||||||
|
virtual_link_external2_2: [ VDU2_CP2, virtual_link ]
|
||||||
|
|
||||||
|
node_templates:
|
||||||
|
|
||||||
|
VDU1:
|
||||||
|
type: tosca.nodes.nfv.Vdu.Compute
|
||||||
|
properties:
|
||||||
|
name: VDU1
|
||||||
|
description: VDU1 compute node
|
||||||
|
vdu_profile:
|
||||||
|
min_number_of_instances: 1
|
||||||
|
max_number_of_instances: 3
|
||||||
|
capabilities:
|
||||||
|
virtual_compute:
|
||||||
|
properties:
|
||||||
|
requested_additional_capabilities:
|
||||||
|
properties:
|
||||||
|
requested_additional_capability_name: m1.tiny
|
||||||
|
support_mandatory: true
|
||||||
|
target_performance_parameters:
|
||||||
|
entry_schema: test
|
||||||
|
virtual_memory:
|
||||||
|
virtual_mem_size: 512 MB
|
||||||
|
virtual_cpu:
|
||||||
|
num_virtual_cpu: 1
|
||||||
|
virtual_local_storage:
|
||||||
|
- size_of_storage: 3 GB
|
||||||
|
requirements:
|
||||||
|
- virtual_storage: VirtualStorage
|
||||||
|
|
||||||
|
VNF:
|
||||||
|
type: company.provider.VNF
|
||||||
|
properties:
|
||||||
|
flavour_description: A simple flavour
|
||||||
|
interfaces:
|
||||||
|
Vnflcm:
|
||||||
|
instantiate_start:
|
||||||
|
implementation:
|
||||||
|
instantiate_end:
|
||||||
|
implementation: sample-script
|
||||||
|
terminate_start:
|
||||||
|
implementation: error-script
|
||||||
|
terminate_end:
|
||||||
|
implementation: sample-script
|
||||||
|
scale_start: [ ]
|
||||||
|
artifacts:
|
||||||
|
sample-script:
|
||||||
|
description: Sample script
|
||||||
|
type: tosca.artifacts.Implementation.Python
|
||||||
|
file:
|
||||||
|
error-script:
|
||||||
|
description: Sample script
|
||||||
|
type: tosca.artifacts.Implementation.Error
|
||||||
|
file: 'test/sample_script.sh'
|
||||||
|
|
||||||
|
VDU2:
|
||||||
|
type: tosca.nodes.nfv.Vdu.Compute
|
||||||
|
properties:
|
||||||
|
name: VDU1
|
||||||
|
description: VDU1 compute node
|
||||||
|
vdu_profile:
|
||||||
|
min_number_of_instances: 1
|
||||||
|
max_number_of_instances: 3
|
||||||
|
capabilities:
|
||||||
|
virtual_compute:
|
||||||
|
properties:
|
||||||
|
requested_additional_capabilities:
|
||||||
|
properties:
|
||||||
|
requested_additional_capability_name: m1.tiny
|
||||||
|
support_mandatory: true
|
||||||
|
target_performance_parameters:
|
||||||
|
entry_schema: test
|
||||||
|
virtual_memory:
|
||||||
|
virtual_mem_size: 512 MB
|
||||||
|
virtual_cpu:
|
||||||
|
num_virtual_cpu: 1
|
||||||
|
virtual_local_storage:
|
||||||
|
- size_of_storage: 3 GB
|
||||||
|
requirements:
|
||||||
|
- virtual_storage: VirtualStorage-2
|
||||||
|
|
||||||
|
VirtualStorage:
|
||||||
|
type: tosca.nodes.nfv.Vdu.VirtualBlockStorage
|
||||||
|
properties:
|
||||||
|
virtual_block_storage_data:
|
||||||
|
size_of_storage: 1gb GB
|
||||||
|
rdma_enabled: true
|
||||||
|
|
||||||
|
VirtualStorage-2:
|
||||||
|
type: tosca.nodes.nfv.Vdu.VirtualBlockStorage
|
||||||
|
properties:
|
||||||
|
virtual_block_storage_data:
|
||||||
|
size_of_storage: 1gb GB
|
||||||
|
rdma_enabled: true
|
||||||
|
sw_image_data:
|
||||||
|
name: image-1.0.0-x86_64-disk
|
||||||
|
version: '1.0.0'
|
||||||
|
checksum:
|
||||||
|
algorithm: sha-256
|
||||||
|
hash: a8dd75ecffd4cdd96072d60c2237b448e0c8b2bc94d57f10fdbc8c481d9005b8
|
||||||
|
container_format: bare
|
||||||
|
disk_format: qcow2
|
||||||
|
min_disk: 0 GB
|
||||||
|
min_ram: 256 MB
|
||||||
|
size: 12 GB
|
||||||
|
|
||||||
|
VDU1_CP1:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 0
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
|
||||||
|
VDU1_CP2:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 1
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
|
||||||
|
VDU1_CP3:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 2
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
- virtual_link: internalVL1
|
||||||
|
|
||||||
|
VDU1_CP4:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 3
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
- virtual_link: internalVL2
|
||||||
|
|
||||||
|
VDU1_CP5:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 4
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU1
|
||||||
|
- virtual_link: internalVL3
|
||||||
|
|
||||||
|
VDU2_CP1:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 0
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU2
|
||||||
|
|
||||||
|
VDU2_CP2:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 1
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU2
|
||||||
|
|
||||||
|
VDU2_CP3:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 2
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU2
|
||||||
|
- virtual_link: internalVL1
|
||||||
|
|
||||||
|
VDU2_CP4:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 3
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU2
|
||||||
|
- virtual_link: internalVL2
|
||||||
|
|
||||||
|
VDU2_CP5:
|
||||||
|
type: tosca.nodes.nfv.VduCp
|
||||||
|
properties:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
order: 4
|
||||||
|
requirements:
|
||||||
|
- virtual_binding: VDU2
|
||||||
|
- virtual_link: internalVL3
|
||||||
|
|
||||||
|
internalVL1:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
description: External Managed Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
virtual_link_protocol_data:
|
||||||
|
- associated_layer_protocol: ipv4
|
||||||
|
l3_protocol_data:
|
||||||
|
ip_version: ipv4
|
||||||
|
cidr: 192.168.3.0/24
|
||||||
|
|
||||||
|
internalVL2:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
description: External Managed Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
virtual_link_protocol_data:
|
||||||
|
- associated_layer_protocol: ipv4
|
||||||
|
l3_protocol_data:
|
||||||
|
ip_version: ipv4
|
||||||
|
cidr: 192.168.4.0/24
|
||||||
|
|
||||||
|
internalVL3:
|
||||||
|
type: tosca.nodes.nfv.VnfVirtualLink
|
||||||
|
properties:
|
||||||
|
connectivity_type:
|
||||||
|
layer_protocols: [ ipv4 ]
|
||||||
|
description: Internal Virtual link in the VNF
|
||||||
|
vl_profile:
|
||||||
|
max_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
min_bitrate_requirements:
|
||||||
|
root: 1048576
|
||||||
|
leaf: 1048576
|
||||||
|
virtual_link_protocol_data:
|
||||||
|
- associated_layer_protocol: ipv4
|
||||||
|
l3_protocol_data:
|
||||||
|
ip_version: ipv4
|
||||||
|
cidr: 192.168.5.0/24
|
||||||
|
|
||||||
|
groups:
|
||||||
|
affinityOrAntiAffinityGroup1:
|
||||||
|
type: tosca.groups.nfv.PlacementGroup
|
||||||
|
members: [ VDU1, VDU2 ]
|
||||||
|
|
||||||
|
policies:
|
||||||
|
policy_antiaffinity_group:
|
||||||
|
type: tosca.policies.nfv.AntiAffinityRule
|
||||||
|
targets: [ affinityOrAntiAffinityGroup1 ]
|
||||||
|
properties:
|
||||||
|
scope: nfvi_node
|
||||||
|
|
||||||
|
policy_affinity_group:
|
||||||
|
type: tosca.policies.nfv.AffinityRule
|
||||||
|
targets: [ affinityOrAntiAffinityGroup1 ]
|
||||||
|
properties:
|
||||||
|
scope: error
|
||||||
|
|
||||||
|
policy_affinity_group_2:
|
||||||
|
type: tosca.policies.nfv.AffinityRule
|
||||||
|
targets: [VDU3]
|
||||||
|
properties:
|
||||||
|
scope: zone
|
|
@ -2,3 +2,4 @@ TOSCA-Meta-File-Version: 1.0
|
||||||
CSAR-Version: 1.1
|
CSAR-Version: 1.1
|
||||||
Created-by: Onboarding portal
|
Created-by: Onboarding portal
|
||||||
Entry-Definitions: Definitions/v2_sample2_top.vnfd.yaml
|
Entry-Definitions: Definitions/v2_sample2_top.vnfd.yaml
|
||||||
|
ETSI-Entry-Manifest: manifest.mf
|
|
@ -0,0 +1,7 @@
|
||||||
|
Source: Scripts/install.sh
|
||||||
|
Algorithm: SHA-256
|
||||||
|
Hash: 27bbdb25d8f4ed6d07d6f6581b86515e8b2f0059b236ef7b6f50d6674b34f02a
|
||||||
|
|
||||||
|
Source: Files/kubernetes/deployment.yaml
|
||||||
|
Algorithm: SHA-256
|
||||||
|
Hash: e23cc3433835cea32ce790b4823313dc6d0744dce02e27b1b339c87ee993b8c2
|
Loading…
Reference in New Issue