Merge "Improve Unit Test for V2 API"
This commit is contained in:
commit
dbca617b98
|
@ -171,7 +171,7 @@ def match_inst_subsc_filter(inst_filter, inst):
|
|||
return False
|
||||
|
||||
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 True
|
||||
|
|
|
@ -77,7 +77,10 @@ class Vnfd(object):
|
|||
|
||||
def delete(self):
|
||||
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):
|
||||
if flavour_id in self.vnfd_flavours:
|
||||
|
@ -336,6 +339,8 @@ class Vnfd(object):
|
|||
|
||||
def get_interface_script(self, flavour_id, operation):
|
||||
vnfd = self.get_vnfd_flavour(flavour_id)
|
||||
if not vnfd:
|
||||
return
|
||||
nodes = (vnfd.get('topology_template', {})
|
||||
.get('node_templates', {}))
|
||||
for node in nodes.values():
|
||||
|
|
|
@ -39,7 +39,9 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
|
||||
expected_result = {
|
||||
'VDU': {
|
||||
'VDU1': {'computeFlavourId': None},
|
||||
'VDU1': {'computeFlavourId': None,
|
||||
'desired_capacity': None,
|
||||
'locationConstraints': None},
|
||||
'VirtualStorage': {'vcImageId': None},
|
||||
'VDU2': {'computeFlavourId': None, 'vcImageId': None}
|
||||
},
|
||||
|
@ -56,6 +58,9 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
}
|
||||
result = common_script_utils.init_nfv_dict(top_hot)
|
||||
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):
|
||||
flavor = 'm1.large'
|
||||
|
@ -79,6 +84,24 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
self.vnfd_1, grant)
|
||||
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):
|
||||
image_id = 'f30e149d-b3c7-497a-8b19-a092bc81e47b'
|
||||
grant = {
|
||||
|
@ -96,6 +119,33 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
self.vnfd_1, grant)
|
||||
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):
|
||||
grant_req = {
|
||||
'addResources': [
|
||||
|
@ -118,6 +168,75 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
result = common_script_utils.get_param_zone('VDU1', grant_req, grant)
|
||||
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):
|
||||
# test get_current_capacity at the same time
|
||||
grant_req = {
|
||||
|
@ -214,6 +333,81 @@ class TestCommontScriptUtils(base.BaseTestCase):
|
|||
result = common_script_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
||||
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):
|
||||
ext_cp = {
|
||||
"cpdId": "VDU2_CP2",
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
# 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.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import lcm_op_occ_utils as lcmocc_utils
|
||||
from tacker.sol_refactored import objects
|
||||
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):
|
||||
|
||||
|
@ -2312,3 +2339,149 @@ class TestLcmOpOccUtils(base.BaseTestCase):
|
|||
self.assertEqual(
|
||||
_expected_resource_changes_change_vnfpkg,
|
||||
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
|
||||
# License for the specific language governing permissions and limitations
|
||||
# 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 import objects
|
||||
from tacker.tests import base
|
||||
|
||||
|
||||
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):
|
||||
# patch is not dict.
|
||||
target = {"key1", "value1"}
|
||||
target = {"key1": "value1"}
|
||||
patch = "text"
|
||||
result = inst_utils.json_merge_patch(target, patch)
|
||||
self.assertEqual(patch, result)
|
||||
|
||||
# target is not dict.
|
||||
target = "text"
|
||||
patch = {"key1", "value1"}
|
||||
patch = {"key1": "value1"}
|
||||
result = inst_utils.json_merge_patch(target, patch)
|
||||
self.assertEqual(patch, result)
|
||||
|
||||
|
@ -65,3 +73,24 @@ class TestVnfInstanceUtils(base.BaseTestCase):
|
|||
}
|
||||
result = inst_utils.json_merge_patch(target, patch)
|
||||
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
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
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 vnfd_utils
|
||||
|
@ -22,6 +27,7 @@ from tacker.tests import base
|
|||
|
||||
SAMPLE_VNFD_ID = "b1bb0ce7-ebca-4fa7-95ed-4840d7000000"
|
||||
SAMPLE_FLAVOUR_ID = "simple"
|
||||
LOG = logging.getLogger()
|
||||
|
||||
|
||||
class TestVnfd(base.BaseTestCase):
|
||||
|
@ -179,3 +185,126 @@ class TestVnfd(base.BaseTestCase):
|
|||
result = self.vnfd_1.get_max_scale_level(SAMPLE_FLAVOUR_ID,
|
||||
'VDU1_scale')
|
||||
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.context = context.get_admin_context()
|
||||
|
||||
def _create_inst_and_lcmocc(self,
|
||||
op_state=fields.LcmOperationStateType.STARTING):
|
||||
def _create_inst_and_lcmocc(
|
||||
self, op_state=fields.LcmOperationStateType.STARTING,
|
||||
is_change_vnfpkg=False):
|
||||
inst = objects.VnfInstanceV2(
|
||||
# required fields
|
||||
id=uuidutils.generate_uuid(),
|
||||
|
@ -65,6 +66,9 @@ class TestConductorV2(db_base.SqlTestCase):
|
|||
isCancelPending=False,
|
||||
operationParams=req)
|
||||
|
||||
if is_change_vnfpkg:
|
||||
lcmocc.operation = fields.LcmOperationType.CHANGE_VNFPKG
|
||||
|
||||
inst.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)
|
||||
expected = ex.make_problem_details()
|
||||
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 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.infra_drivers.openstack import openstack
|
||||
from tacker.sol_refactored import objects
|
||||
|
@ -35,13 +37,6 @@ SAMPLE_FLAVOUR_ID = "simple"
|
|||
_vim_connection_info_example = {
|
||||
"vimId": "vim_id_1",
|
||||
"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"},
|
||||
"accessInfo": {
|
||||
"username": "nfv_user",
|
||||
|
@ -51,7 +46,6 @@ _vim_connection_info_for_change_vnfpkg = {
|
|||
"projectDomain": "Default",
|
||||
"userDomain": "Default"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_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):
|
||||
|
||||
|
@ -2647,6 +2745,7 @@ class TestOpenstack(base.BaseTestCase):
|
|||
objects.register_all()
|
||||
self.driver = openstack.Openstack()
|
||||
self.context = context.get_admin_context()
|
||||
CONF.v2_vnfm.default_graceful_termination_timeout = 0
|
||||
|
||||
cur_dir = os.path.dirname(__file__)
|
||||
sample_dir = os.path.join(cur_dir, "../..", "samples")
|
||||
|
@ -2811,3 +2910,353 @@ class TestOpenstack(base.BaseTestCase):
|
|||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
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:
|
||||
min_size: 1
|
||||
max_size: 3
|
||||
desired_capacity: 1
|
||||
desired_capacity: { get_param: [ nfv, VDU, VDU1, desired_capacity ] }
|
||||
resource:
|
||||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VirtualStorage, vcImageId ] }
|
||||
zone: { get_param: [ nfv, VDU, VDU1, locationConstraints] }
|
||||
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:
|
||||
|
|
|
@ -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
|
||||
Created-by: Onboarding portal
|
||||
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