Refactor change_vnfpkg v2 API
This patch refactors the implementation of change_vnfpkg v2 API. Because the original implementation of change_vnfpkg does not obey the rules that other operations obey, it makes hard to enhance the function that related to whole operations such as the HOT format change. This patch corrects it. This patch also changes some specifications of the API and fixes some bugs (described in bug #1981533). Specification changes: * image to volume translation (or vice versa) is not supported. Note that it did not work property by a bug. * parameters to the coordinate script are changed. * property name for images in the definition of AutoScalingGroup is changed. * unnecessary parameters of additionalParams, 'lcm-operation-coordinate-old-vnf-class' and 'lcm-operation-coordinate-new-vnf-class' are removed. * 'lcm-operation-coordinate-old-vnf' and 'lcm-operation-coordinate-new-vnf' in additionalParams are option now. Detail of bug fiexes are omitted. Note that the object of this patch is common part and openstack VIM part. k8s VIM part will be fixed by another patch. Closes-Bug: #1981533 Change-Id: I9f6d103d66e6904704ca467d68c4ebfbcbd8a1f8
This commit is contained in:
parent
b8c1f9daa2
commit
acb231d7e1
|
@ -13,7 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
|
||||
|
||||
|
@ -23,47 +22,6 @@ def get_vnfd(vnfd_id, csar_dir):
|
|||
return vnfd
|
||||
|
||||
|
||||
def get_vdu_info(grant, inst, vnfd):
|
||||
volume_name = ''
|
||||
volume_size = ''
|
||||
flavour_id = inst['instantiatedVnfInfo']['flavourId']
|
||||
vdu_nodes = vnfd.get_vdu_nodes(flavour_id)
|
||||
storage_nodes = vnfd.get_storage_nodes(flavour_id)
|
||||
vdu_info_dict = {}
|
||||
for name, node in vdu_nodes.items():
|
||||
flavor = get_param_flavor(name, flavour_id, vnfd, grant)
|
||||
image = get_param_image(name, flavour_id, vnfd, grant)
|
||||
vdu_storage_names = vnfd.get_vdu_storages(node)
|
||||
for vdu_storage_name in vdu_storage_names:
|
||||
if storage_nodes[vdu_storage_name].get(
|
||||
'properties', {}).get('sw_image_data'):
|
||||
image = get_param_image(vdu_storage_name, flavour_id, vnfd,
|
||||
grant)
|
||||
volume_name = vdu_storage_name
|
||||
volume_size = storage_nodes[vdu_storage_name].get(
|
||||
'properties', {}).get(
|
||||
'virtual_block_storage_data', '').get(
|
||||
'size_of_storage', ''
|
||||
)
|
||||
volume_size = volume_size.rstrip(' GB')
|
||||
if not volume_size.isdigit():
|
||||
raise sol_ex.VmRunningFailed(
|
||||
error_info='The volume size set in VNFD is invalid.')
|
||||
break
|
||||
|
||||
vdu_info_dict[name] = {
|
||||
"flavor": flavor,
|
||||
"image": image
|
||||
}
|
||||
|
||||
if volume_name:
|
||||
vdu_info_dict[name]['volume_info'] = {
|
||||
"volume_name": volume_name,
|
||||
"volume_size": volume_size
|
||||
}
|
||||
return vdu_info_dict
|
||||
|
||||
|
||||
def init_nfv_dict(hot_template):
|
||||
get_params = []
|
||||
|
||||
|
|
|
@ -131,10 +131,6 @@ class VnfInstanceIsNotInstantiated(SolHttpError409):
|
|||
message = _("VnfInstance %(inst_id)s isn't instantiated.")
|
||||
|
||||
|
||||
class VnfInstanceIsNotChanged(SolHttpError409):
|
||||
message = _("VnfInstance %(inst_id)s isn't changed.")
|
||||
|
||||
|
||||
class LccnSubscriptionNotFound(SolHttpError404):
|
||||
message = _("LccnSubscription %(subsc_id)s not found.")
|
||||
|
||||
|
@ -260,15 +256,6 @@ class ConductorProcessingError(SolException):
|
|||
message = _("Failure due to conductor processing error.")
|
||||
|
||||
|
||||
class InvalidVolumeSize(SolHttpError400):
|
||||
message = _("The volume size set in VNFD is invalid.")
|
||||
|
||||
|
||||
class VduIdNotFound(SolHttpError404):
|
||||
message = _("This vdu_id '%(vdu_id)s' does not exist"
|
||||
" in current VnfInstance.")
|
||||
|
||||
|
||||
class SshIpNotFoundException(SolHttpError404):
|
||||
message = _("Ssh ip not found.")
|
||||
|
||||
|
|
|
@ -147,6 +147,31 @@ def _make_affected_vnfc(vnfc, change_type, strgs):
|
|||
return affected_vnfc
|
||||
|
||||
|
||||
def _make_affected_vnfc_modified(vnfc, vnfc_saved):
|
||||
affected_vnfc = objects.AffectedVnfcV2(
|
||||
id=vnfc.id,
|
||||
vduId=vnfc.vduId,
|
||||
changeType='MODIFIED',
|
||||
computeResource=vnfc.computeResource
|
||||
)
|
||||
affected_vnfc.metadata = vnfc.metadata
|
||||
# NOTE: cps may not be affected.
|
||||
if vnfc.obj_attr_is_set('vnfcCpInfo'):
|
||||
cp_ids = [cp.id for cp in vnfc.vnfcCpInfo]
|
||||
affected_vnfc.affectedVnfcCpIds = cp_ids
|
||||
if vnfc.obj_attr_is_set('storageResourceIds'):
|
||||
added_str_ids = (set(vnfc.storageResourceIds) -
|
||||
set(vnfc_saved.storageResourceIds))
|
||||
removed_str_ids = (set(vnfc_saved.storageResourceIds) -
|
||||
set(vnfc.storageResourceIds))
|
||||
if added_str_ids:
|
||||
affected_vnfc.addedStorageResourceIds = list(added_str_ids)
|
||||
if removed_str_ids:
|
||||
affected_vnfc.removedStorageResourceIds = list(removed_str_ids)
|
||||
|
||||
return affected_vnfc
|
||||
|
||||
|
||||
def _make_affected_vl(vl, change_type):
|
||||
affected_vl = objects.AffectedVirtualLinkV2(
|
||||
id=vl.id,
|
||||
|
@ -383,15 +408,7 @@ def update_lcmocc(lcmocc, inst_saved, inst):
|
|||
for strg in inst_info.virtualStorageResourceInfo
|
||||
if strg.id in added_strgs]
|
||||
|
||||
removed_vnfcs, added_vnfcs, common_objs = _calc_diff('vnfcResourceInfo')
|
||||
updated_vnfcs = []
|
||||
if lcmocc.operation == fields.LcmOperationType.CHANGE_VNFPKG:
|
||||
updated_vnfcs = [
|
||||
obj.id for obj in inst_info.vnfcResourceInfo
|
||||
if obj.metadata.get('current_vnfd_id') != inst_saved.vnfdId
|
||||
and obj.id in common_objs and
|
||||
obj.metadata.get('current_vnfd_id') is not None]
|
||||
|
||||
removed_vnfcs, added_vnfcs, common_vnfcs = _calc_diff('vnfcResourceInfo')
|
||||
affected_vnfcs = []
|
||||
if removed_vnfcs:
|
||||
affected_vnfcs += [
|
||||
|
@ -405,11 +422,18 @@ def update_lcmocc(lcmocc, inst_saved, inst):
|
|||
for vnfc in inst_info.vnfcResourceInfo
|
||||
if vnfc.id in added_vnfcs
|
||||
]
|
||||
if lcmocc.operation == fields.LcmOperationType.CHANGE_VNFPKG:
|
||||
def _get_vnfc(vnfc_id, inst_info):
|
||||
for vnfc in inst_info.vnfcResourceInfo:
|
||||
if vnfc.id == vnfc_id:
|
||||
return vnfc
|
||||
|
||||
if updated_vnfcs:
|
||||
affected_vnfcs += [_make_affected_vnfc(vnfc, 'MODIFIED', added_strgs)
|
||||
for vnfc in inst_info.vnfcResourceInfo
|
||||
if vnfc.id in updated_vnfcs]
|
||||
for obj_id in common_vnfcs:
|
||||
vnfc = _get_vnfc(obj_id, inst_info)
|
||||
vnfc_saved = _get_vnfc(obj_id, inst_saved.instantiatedVnfInfo)
|
||||
if vnfc.metadata != vnfc_saved.metadata:
|
||||
affected_vnfcs.append(
|
||||
_make_affected_vnfc_modified(vnfc, vnfc_saved))
|
||||
|
||||
removed_vls, added_vls, common_vls = _calc_diff(
|
||||
'vnfVirtualLinkResourceInfo')
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from tacker.common import log
|
||||
from tacker import context as tacker_context
|
||||
|
@ -93,7 +92,7 @@ class ConductorV2(object):
|
|||
inst = inst_utils.get_inst(context, lcmocc.vnfInstanceId)
|
||||
|
||||
# NOTE: error cannot happen to here basically.
|
||||
# if an error occurred lcmocc.opetationState remains STARTING.
|
||||
# if an error occurred lcmocc.operationState remains STARTING.
|
||||
# see the log of the tacker-conductor to investigate the cause
|
||||
# of error.
|
||||
|
||||
|
@ -250,24 +249,8 @@ class ConductorV2(object):
|
|||
context, lcmocc)
|
||||
self.vnflcm_driver.post_grant(context, lcmocc, inst, grant_req,
|
||||
grant, vnfd)
|
||||
if lcmocc.operation == fields.LcmOperationType.CHANGE_VNFPKG:
|
||||
inst_lcmocc = lcmocc_utils.get_inst_lcmocc(context, inst)
|
||||
inst_grant_req = objects.GrantRequestV1(
|
||||
vnfInstanceId=inst.id,
|
||||
vnfLcmOpOccId=inst_lcmocc.id,
|
||||
operation=inst_lcmocc.operation,
|
||||
isAutomaticInvocation=lcmocc.isAutomaticInvocation
|
||||
)
|
||||
inst_grant = objects.GrantV1(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vnfInstanceId=inst_grant_req.vnfInstanceId,
|
||||
vnfLcmOpOccId=inst_grant_req.vnfLcmOpOccId
|
||||
)
|
||||
self.vnflcm_driver.rollback(
|
||||
context, lcmocc, inst, inst_grant_req, inst_grant, vnfd)
|
||||
else:
|
||||
self.vnflcm_driver.rollback(context, lcmocc, inst, grant_req,
|
||||
grant, vnfd)
|
||||
self.vnflcm_driver.rollback(context, lcmocc, inst, grant_req,
|
||||
grant, vnfd)
|
||||
|
||||
lcmocc.operationState = fields.LcmOperationStateType.ROLLED_BACK
|
||||
with context.session.begin(subtransactions=True):
|
||||
|
|
|
@ -68,13 +68,10 @@ class VnfLcmDriverV2(object):
|
|||
grant_req = objects.GrantRequestV1(
|
||||
vnfInstanceId=inst.id,
|
||||
vnfLcmOpOccId=lcmocc.id,
|
||||
vnfdId=inst.vnfdId,
|
||||
operation=lcmocc.operation,
|
||||
isAutomaticInvocation=lcmocc.isAutomaticInvocation
|
||||
)
|
||||
if lcmocc.operation == v2fields.LcmOperationType.CHANGE_VNFPKG:
|
||||
grant_req.vnfdId = lcmocc.operationParams.get('vnfdId')
|
||||
else:
|
||||
grant_req.vnfdId = inst.vnfdId
|
||||
grant_req._links = objects.GrantRequestV1_Links(
|
||||
vnfLcmOpOcc=objects.Link(
|
||||
href=lcmocc_utils.lcmocc_href(lcmocc.id, self.endpoint)),
|
||||
|
@ -966,67 +963,68 @@ class VnfLcmDriverV2(object):
|
|||
# only support openstack at the moment
|
||||
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||
|
||||
def change_ext_conn_rollback(self, context, lcmocc, inst, grant_req,
|
||||
grant, vnfd):
|
||||
req = lcmocc.operationParams
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||
driver = openstack.Openstack()
|
||||
driver.change_ext_conn_rollback(req, inst, grant_req, grant, vnfd)
|
||||
else:
|
||||
# only support openstack at the moment
|
||||
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||
|
||||
def change_vnfpkg_grant(self, grant_req, req, inst, vnfd):
|
||||
inst_info = inst.instantiatedVnfInfo
|
||||
grant_req.flavourId = inst_info.flavourId
|
||||
if req.additionalParams.get('vdu_params'):
|
||||
target_vdu_ids = [
|
||||
vdu_param.get(
|
||||
'vdu_id') for vdu_param in req.additionalParams.get(
|
||||
'vdu_params')]
|
||||
grant_req.dstVnfdId = req.vnfdId
|
||||
# NOTE: flavourId is not necessary according to the SOL003 spec.
|
||||
# It is for local_nfvo to handle images.
|
||||
grant_req.flavourId = inst.instantiatedVnfInfo.flavourId
|
||||
|
||||
if req.additionalParams['upgrade_type'] == 'RollingUpdate':
|
||||
self._change_vnfpkg_grant_rolling_update(
|
||||
grant_req, req, inst, vnfd)
|
||||
else:
|
||||
if inst_info.obj_attr_is_set('vnfcResourceInfo'):
|
||||
target_vdu_ids = [inst_vnc.vduId for inst_vnc in
|
||||
inst_info.vnfcResourceInfo]
|
||||
|
||||
if req.additionalParams.get('upgrade_type') == 'RollingUpdate':
|
||||
update_reses = []
|
||||
add_reses = []
|
||||
remove_reses = []
|
||||
if inst_info.obj_attr_is_set('vnfcResourceInfo'):
|
||||
for inst_vnc in inst_info.vnfcResourceInfo:
|
||||
if inst_vnc.vduId in target_vdu_ids:
|
||||
vdu_res_id = uuidutils.generate_uuid()
|
||||
res_def = objects.ResourceDefinitionV1(
|
||||
id=vdu_res_id,
|
||||
type='COMPUTE',
|
||||
resourceTemplateId=inst_vnc.vduId)
|
||||
update_reses.append(res_def)
|
||||
nodes = vnfd.get_vdu_nodes(inst_info.flavourId)
|
||||
vdu_storage_names = vnfd.get_vdu_storages(
|
||||
nodes[inst_vnc.vduId])
|
||||
for vdu_storage_name in vdu_storage_names:
|
||||
res_def = objects.ResourceDefinitionV1(
|
||||
id=_make_combination_id(
|
||||
vdu_storage_name, vdu_res_id),
|
||||
type='STORAGE',
|
||||
resourceTemplateId=vdu_storage_name)
|
||||
add_reses.append(res_def)
|
||||
if inst_vnc.obj_attr_is_set('storageResourceIds'):
|
||||
inst_stor_info = (
|
||||
inst_info.virtualStorageResourceInfo)
|
||||
for str_info in inst_stor_info:
|
||||
if str_info.id in inst_vnc.storageResourceIds:
|
||||
res_def = objects.ResourceDefinitionV1(
|
||||
id=uuidutils.generate_uuid(),
|
||||
type='STORAGE',
|
||||
resourceTemplateId=(
|
||||
str_info.virtualStorageDescId),
|
||||
resource=str_info.storageResource)
|
||||
remove_reses.append(res_def)
|
||||
if update_reses:
|
||||
grant_req.updateResources = update_reses
|
||||
|
||||
if add_reses:
|
||||
grant_req.addResources = add_reses
|
||||
|
||||
if remove_reses:
|
||||
grant_req.removeResources = remove_reses
|
||||
else:
|
||||
# TODO(YiFeng): Blue-Green type will be supported in Zed release.
|
||||
# not reach here at the moment
|
||||
# Only support RollingUpdate at the moment.
|
||||
pass
|
||||
|
||||
def _change_vnfpkg_grant_rolling_update(self, grant_req, req, inst, vnfd):
|
||||
inst_info = inst.instantiatedVnfInfo
|
||||
if not inst_info.obj_attr_is_set('vnfcResourceInfo'):
|
||||
return
|
||||
|
||||
if req.additionalParams.get('vdu_params'):
|
||||
vdu_ids = [vdu_param['vdu_id']
|
||||
for vdu_param in req.additionalParams['vdu_params']]
|
||||
inst_vnfcs = [inst_vnfc
|
||||
for inst_vnfc in inst_info.vnfcResourceInfo
|
||||
if inst_vnfc.vduId in vdu_ids]
|
||||
else:
|
||||
inst_vnfcs = inst_info.vnfcResourceInfo
|
||||
|
||||
add_reses = []
|
||||
rm_reses = []
|
||||
for inst_vnfc in inst_vnfcs:
|
||||
rm_vdu_res_id = uuidutils.generate_uuid()
|
||||
add_vdu_res_id = uuidutils.generate_uuid()
|
||||
self._set_rm_add_reses(rm_reses, add_reses, 'COMPUTE',
|
||||
inst_vnfc.vduId, inst_vnfc.computeResource,
|
||||
rm_vdu_res_id, add_vdu_res_id)
|
||||
|
||||
if inst_vnfc.obj_attr_is_set('storageResourceIds'):
|
||||
for storage_id in inst_vnfc.storageResourceIds:
|
||||
inst_str = _get_obj_by_id(storage_id,
|
||||
inst_info.virtualStorageResourceInfo)
|
||||
str_name = inst_str.virtualStorageDescId
|
||||
self._set_rm_add_reses(rm_reses, add_reses, 'STORAGE',
|
||||
str_name, inst_str.storageResource,
|
||||
_make_combination_id(str_name, rm_vdu_res_id),
|
||||
_make_combination_id(str_name, add_vdu_res_id))
|
||||
|
||||
if add_reses:
|
||||
grant_req.addResources = add_reses
|
||||
if rm_reses:
|
||||
grant_req.removeResources = rm_reses
|
||||
|
||||
def _pre_check_for_change_vnfpkg(self, context, req, inst, vnfd):
|
||||
def _get_file_content(file_path):
|
||||
if ((urlparse(file_path).scheme == 'file') or
|
||||
|
@ -1093,16 +1091,14 @@ class VnfLcmDriverV2(object):
|
|||
|
||||
def change_vnfpkg_process(
|
||||
self, context, lcmocc, inst, grant_req, grant, vnfd):
|
||||
inst_saved = inst.obj_clone()
|
||||
req = lcmocc.operationParams
|
||||
if req.obj_attr_is_set('vimConnectionInfo'):
|
||||
self._merge_vim_connection_info(inst, req)
|
||||
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||
driver = openstack.Openstack()
|
||||
try:
|
||||
driver.change_vnfpkg(req, inst, grant_req, grant, vnfd)
|
||||
except Exception as ex:
|
||||
lcmocc_utils.update_lcmocc(lcmocc, inst_saved, inst)
|
||||
raise Exception from ex
|
||||
driver.change_vnfpkg(req, inst, grant_req, grant, vnfd)
|
||||
elif vim_info.vimType == 'kubernetes': # k8s
|
||||
target_k8s_files = self._pre_check_for_change_vnfpkg(
|
||||
context, req, inst, vnfd)
|
||||
|
@ -1110,32 +1106,19 @@ class VnfLcmDriverV2(object):
|
|||
update_req.additionalParams[
|
||||
'lcm-kubernetes-def-files'] = target_k8s_files
|
||||
driver = kubernetes.Kubernetes()
|
||||
try:
|
||||
driver.change_vnfpkg(update_req, inst, grant_req, grant, vnfd)
|
||||
except Exception as ex:
|
||||
lcmocc_utils.update_lcmocc(lcmocc, inst_saved, inst)
|
||||
raise Exception from ex
|
||||
driver.change_vnfpkg(update_req, inst, grant_req, grant, vnfd)
|
||||
else:
|
||||
# should not occur
|
||||
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||
|
||||
def change_ext_conn_rollback(self, context, lcmocc, inst, grant_req,
|
||||
grant, vnfd):
|
||||
req = lcmocc.operationParams
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||
driver = openstack.Openstack()
|
||||
driver.change_ext_conn_rollback(req, inst, grant_req, grant, vnfd)
|
||||
else:
|
||||
# only support openstack at the moment
|
||||
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||
inst.vnfdId = grant_req.dstVnfdId
|
||||
|
||||
def change_vnfpkg_rollback(
|
||||
self, context, lcmocc, inst, grant_req, grant, vnfd):
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
req = lcmocc.operationParams
|
||||
driver = openstack.Openstack()
|
||||
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||
driver = openstack.Openstack()
|
||||
driver.change_vnfpkg_rollback(
|
||||
req, inst, grant_req, grant, vnfd, lcmocc)
|
||||
elif vim_info.vimType == 'kubernetes': # k8s
|
||||
|
|
|
@ -383,6 +383,43 @@ class VnfLcmControllerV2(sol_wsgi.SolAPIController):
|
|||
|
||||
return sol_wsgi.SolResponse(202, None, location=location)
|
||||
|
||||
def _check_vdu_params(self, inst, vdu_params, vim_type, new_script,
|
||||
old_script):
|
||||
inst_vdu_ids = []
|
||||
if inst.instantiatedVnfInfo.obj_attr_is_set('vnfcResourceInfo'):
|
||||
inst_vdu_ids = [inst_vnfc.vduId
|
||||
for inst_vnfc in inst.instantiatedVnfInfo.vnfcResourceInfo]
|
||||
|
||||
for vdu_param in vdu_params:
|
||||
if 'vdu_id' not in vdu_param:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="If you set vdu_params in additionalParams, you"
|
||||
"must set vdu_id for each element.")
|
||||
if vdu_param['vdu_id'] not in inst_vdu_ids:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="vdu_id '%s' does not exist." % vdu_param['vdu_id'])
|
||||
|
||||
def _check_vnfc_param(attr):
|
||||
for key in ['cp_name', 'username', 'password']:
|
||||
if key not in vdu_param[attr]:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail=f"If you set {attr} in "
|
||||
f"vdu_param, you must set"
|
||||
f" 'cp_name', 'username' and"
|
||||
f" 'password'")
|
||||
|
||||
if vim_type == 'ETSINFV.OPENSTACK_KEYSTONE.V_3' and new_script:
|
||||
if 'new_vnfc_param' not in vdu_param:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="'new_vnfc_param' must exist in vdu_param")
|
||||
_check_vnfc_param('new_vnfc_param')
|
||||
|
||||
if vim_type == 'ETSINFV.OPENSTACK_KEYSTONE.V_3' and old_script:
|
||||
if 'old_vnfc_param' not in vdu_param:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="'old_vnfc_param' must exist in vdu_param")
|
||||
_check_vnfc_param('old_vnfc_param')
|
||||
|
||||
@validator.schema(schema.ChangeCurrentVnfPkgRequest_V200, '2.0.0')
|
||||
@coordinate.lock_vnf_instance('{id}')
|
||||
def change_vnfpkg(self, request, id, body):
|
||||
|
@ -408,24 +445,16 @@ class VnfLcmControllerV2(sol_wsgi.SolAPIController):
|
|||
upgrade_type = additional_params.get('upgrade_type', '')
|
||||
if upgrade_type != 'RollingUpdate':
|
||||
raise sol_ex.NotSupportUpgradeType(upgrade_type=upgrade_type)
|
||||
if additional_params.get('vdu_params'):
|
||||
vdu_ids = [vdu.get('vdu_id') for vdu in
|
||||
additional_params.get('vdu_params')]
|
||||
if None in vdu_ids:
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="If you set vdu_params in additionalParams, you"
|
||||
"must set vduId for each element.")
|
||||
for vdu in additional_params.get('vdu_params'):
|
||||
for attr in ['old_vnfc_param', 'new_vnfc_param']:
|
||||
if vdu.get(attr):
|
||||
vdu_keys = vdu.get(attr).keys()
|
||||
if set(vdu_keys).difference(set(
|
||||
['cp_name', 'username', 'password'])):
|
||||
raise sol_ex.SolValidationError(
|
||||
detail=f"If you set {attr} in "
|
||||
f"additionalParams, you must set"
|
||||
f" 'cp_name', 'username' and"
|
||||
f" 'password'")
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
vdu_params = additional_params.get('vdu_params')
|
||||
if (vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3' and
|
||||
vdu_params is None):
|
||||
raise sol_ex.SolValidationError(
|
||||
detail="'vdu_params' must exist in additionalParams")
|
||||
if vdu_params:
|
||||
self._check_vdu_params(inst, vdu_params, vim_info.vimType,
|
||||
additional_params.get('lcm-operation-coordinate-new-vnf'),
|
||||
additional_params.get('lcm-operation-coordinate-old-vnf'))
|
||||
|
||||
lcmocc = self._new_lcmocc(id, v2fields.LcmOperationType.CHANGE_VNFPKG,
|
||||
body)
|
||||
|
@ -461,7 +490,7 @@ class VnfLcmControllerV2(sol_wsgi.SolAPIController):
|
|||
if 'BASIC' in auth.authType:
|
||||
basic_req = auth_req.get('paramsBasic')
|
||||
if basic_req is None:
|
||||
msg = "ParmasBasic must be specified."
|
||||
msg = "ParamsBasic must be specified."
|
||||
raise sol_ex.InvalidSubscription(sol_detail=msg)
|
||||
auth.paramsBasic = (
|
||||
objects.SubscriptionAuthentication_ParamsBasic(
|
||||
|
|
|
@ -282,20 +282,15 @@ class Kubernetes(object):
|
|||
self, req, inst, grant_req, grant, vnfd,
|
||||
operation, namespace, new_deploy_reses):
|
||||
coordinate_vnf = None
|
||||
coordinate_vnf_class = None
|
||||
if req.obj_attr_is_set('additionalParams'):
|
||||
if operation == 'CHANGE_VNFPKG':
|
||||
coordinate_vnf = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-new-vnf')
|
||||
coordinate_vnf_class = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-new-vnf-class')
|
||||
else:
|
||||
coordinate_vnf = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-old-vnf')
|
||||
coordinate_vnf_class = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-old-vnf-class')
|
||||
|
||||
if coordinate_vnf and coordinate_vnf_class:
|
||||
if coordinate_vnf:
|
||||
tmp_csar_dir = vnfd.make_tmp_csar_dir()
|
||||
script_dict = {
|
||||
"request": req.to_dict(),
|
||||
|
|
|
@ -134,20 +134,14 @@ class HeatClient(object):
|
|||
raise sol_ex.StackOperationFailed
|
||||
return body
|
||||
|
||||
def get_resource_info(self, nested_stack_id, resource_name):
|
||||
path = f"stacks/{nested_stack_id}/resources/{resource_name}"
|
||||
def get_resource_info(self, stack_id, resource_name):
|
||||
path = f"stacks/{stack_id}/resources/{resource_name}"
|
||||
resp, body = self.client.do_request(path, "GET",
|
||||
expected_status=[200, 404])
|
||||
if resp.status_code == 404:
|
||||
return None
|
||||
return body['resource']
|
||||
|
||||
def get_resource_list(self, stack_id):
|
||||
path = f"stacks/{stack_id}/resources"
|
||||
resp, body = self.client.do_request(path, "GET",
|
||||
expected_status=[200, 404])
|
||||
return body
|
||||
|
||||
def get_parameters(self, stack_name):
|
||||
path = f"stacks/{stack_name}"
|
||||
resp, body = self.client.do_request(path, "GET",
|
||||
|
@ -211,34 +205,9 @@ def get_resource_stack_id(heat_res):
|
|||
return "{}/{}".format(items[-2], items[-1])
|
||||
|
||||
|
||||
def get_parent_nested_id(res):
|
||||
for link in res.get('links', []):
|
||||
if link['rel'] == 'nested':
|
||||
items = link['href'].split('/')
|
||||
return "{}/{}".format(items[-2], items[-1])
|
||||
|
||||
|
||||
def get_parent_resource(heat_res, heat_reses):
|
||||
parent = heat_res.get('parent_resource')
|
||||
if parent:
|
||||
for res in heat_reses:
|
||||
if res['resource_name'] == parent:
|
||||
return res
|
||||
|
||||
|
||||
def get_group_stack_id(heat_reses, vdu_id):
|
||||
parent_resources = [heat_res for heat_res in heat_reses
|
||||
if heat_res.get('resource_name') == vdu_id]
|
||||
if parent_resources:
|
||||
parent_resource = parent_resources[0].get('parent_resource')
|
||||
else:
|
||||
raise sol_ex.VduIdNotFound(vdu_id=vdu_id)
|
||||
group_resource_name = [heat_res for heat_res in
|
||||
heat_reses if
|
||||
heat_res.get('resource_name') ==
|
||||
parent_resource][0].get('parent_resource')
|
||||
group_stack_id = [heat_res for heat_res in
|
||||
heat_reses if
|
||||
heat_res.get('resource_name') ==
|
||||
group_resource_name][0].get('physical_resource_id')
|
||||
return group_stack_id
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
|
||||
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import pickle
|
||||
|
@ -24,15 +23,12 @@ from dateutil import parser
|
|||
import eventlet
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
import yaml
|
||||
|
||||
from tacker.sol_refactored.common import cinder_utils
|
||||
from tacker.sol_refactored.common import config
|
||||
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.infra_drivers.openstack import heat_utils
|
||||
from tacker.sol_refactored.infra_drivers.openstack import userdata_default
|
||||
from tacker.sol_refactored.nfvo import glance_utils
|
||||
from tacker.sol_refactored import objects
|
||||
from tacker.sol_refactored.objects.v2 import fields as v2fields
|
||||
|
||||
|
@ -90,12 +86,9 @@ class Openstack(object):
|
|||
else:
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# get stack resource
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
|
||||
# make instantiated_vnf_info
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_reses)
|
||||
heat_client)
|
||||
|
||||
def instantiate_rollback(self, req, inst, grant_req, grant, vnfd):
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
|
@ -157,12 +150,9 @@ class Openstack(object):
|
|||
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# get stack resource
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
|
||||
# make instantiated_vnf_info
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_reses)
|
||||
heat_client)
|
||||
|
||||
def scale_rollback(self, req, inst, grant_req, grant, vnfd):
|
||||
# NOTE: rollback is supported for scale out only
|
||||
|
@ -207,12 +197,9 @@ class Openstack(object):
|
|||
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# get stack resource
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
|
||||
# make instantiated_vnf_info
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_reses)
|
||||
heat_client)
|
||||
|
||||
def change_ext_conn_rollback(self, req, inst, grant_req, grant, vnfd):
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
|
@ -225,9 +212,8 @@ class Openstack(object):
|
|||
|
||||
# NOTE: it is necessary to re-create instantiatedVnfInfo because
|
||||
# ports may be changed.
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_reses)
|
||||
heat_client)
|
||||
|
||||
def heal(self, req, inst, grant_req, grant, vnfd):
|
||||
# make HOT
|
||||
|
@ -289,267 +275,180 @@ class Openstack(object):
|
|||
# update stack
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# get stack resource
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
# make instantiated_vnf_info
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_client)
|
||||
|
||||
def change_vnfpkg(self, req, inst, grant_req, grant, vnfd):
|
||||
# make HOT
|
||||
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
||||
LOG.debug("stack fields: %s", fields)
|
||||
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
heat_client = heat_utils.HeatClient(vim_info)
|
||||
|
||||
if req.additionalParams['upgrade_type'] == 'RollingUpdate':
|
||||
self._change_vnfpkg_rolling_update(req, inst, grant_req, grant,
|
||||
vnfd, fields, heat_client, False)
|
||||
else:
|
||||
# not reach here
|
||||
pass
|
||||
|
||||
# update stack
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# make instantiated_vnf_info
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_reses)
|
||||
heat_client)
|
||||
|
||||
def change_vnfpkg(self, req, inst, grant_req, grant, vnfd):
|
||||
group_vdu_ids = []
|
||||
if req.additionalParams.get('upgrade_type') == 'RollingUpdate':
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
heat_client = heat_utils.HeatClient(vim_info)
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
stack_id = heat_client.get_stack_resource(
|
||||
stack_name)['stack']["id"]
|
||||
vdu_infos = self._get_vdu_info(vnfd, grant, inst)
|
||||
new_res_ids = {}
|
||||
for vdu_param in req.additionalParams.get('vdu_params'):
|
||||
vdu_id = vdu_param.get('vdu_id')
|
||||
new_res_ids[vdu_id] = []
|
||||
body = heat_client.get_resource_info(
|
||||
f"{stack_name}/{stack_id}", vdu_id)
|
||||
if uuidutils.is_uuid_like(
|
||||
vdu_infos[vdu_id]['image']):
|
||||
vdu_image_id_flag = True
|
||||
else:
|
||||
vdu_image_id_flag = False
|
||||
# The previous processing is to obtain the VM information under
|
||||
# the current stack according to vduId, excluding the resources
|
||||
# under nested. When the status_code is 404, it means that
|
||||
# there is no VM under the stack, and the VM is created by
|
||||
# `OS::Heat::AutoScalingGroup` by default.
|
||||
if body is None:
|
||||
# handle VM under `OS::Heat::AutoScalingGroup`
|
||||
# In this case, the VM does not support changing from
|
||||
# image creation to volume creation, or changing from
|
||||
# volume creation to image creation. Because it cannot
|
||||
# change VDU.yaml under nested directory.
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
group_stack_id = heat_utils.get_group_stack_id(
|
||||
heat_reses, vdu_id)
|
||||
templates = heat_client.get_template(
|
||||
group_stack_id)
|
||||
reses = heat_client.get_resource_list(
|
||||
group_stack_id)['resources']
|
||||
def _change_vnfpkg_rolling_update(self, req, inst, grant_req, grant,
|
||||
vnfd, fields, heat_client, is_rollback):
|
||||
if not grant_req.obj_attr_is_set('removeResources'):
|
||||
return
|
||||
|
||||
# update VM one by one
|
||||
for res in reses:
|
||||
templates['resources'][res.get('resource_name')][
|
||||
'properties']['image'] = vdu_infos[
|
||||
vdu_id].get('image')
|
||||
templates['resources'][res.get('resource_name')][
|
||||
'properties']['flavor'] = vdu_infos[
|
||||
vdu_id].get('flavor')
|
||||
fields = {
|
||||
"stack_id": group_stack_id,
|
||||
"template": templates
|
||||
}
|
||||
try:
|
||||
heat_client.update_stack(
|
||||
group_stack_id, fields)
|
||||
except sol_ex.StackOperationFailed:
|
||||
self._handle_exception(
|
||||
res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name, get_res_flag=True)
|
||||
self._get_new_res_info(
|
||||
res.get('resource_name'),
|
||||
new_res_ids[vdu_id],
|
||||
heat_utils.get_parent_nested_id(res),
|
||||
vdu_infos[vdu_id], vdu_id,
|
||||
heat_client)
|
||||
vnfc_res_ids = [res_def.resource.resourceId
|
||||
for res_def in grant_req.removeResources
|
||||
if res_def.type == 'COMPUTE']
|
||||
vnfcs = [vnfc
|
||||
for vnfc in inst.instantiatedVnfInfo.vnfcResourceInfo
|
||||
if vnfc.computeResource.resourceId in vnfc_res_ids]
|
||||
|
||||
# execute coordinate_vnf_script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd,
|
||||
heat_utils.get_parent_nested_id(res),
|
||||
heat_client, vdu_param, vim_info,
|
||||
vdu_image_id_flag)
|
||||
except (sol_ex.SshIpNotFoundException,
|
||||
sol_ex.CoordinateVNFExecutionFailed) as ex:
|
||||
self._handle_exception(
|
||||
res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name, ex=ex)
|
||||
group_vdu_ids.append(vdu_id)
|
||||
else:
|
||||
# handle single VM
|
||||
res = {
|
||||
"resource_name": stack_name,
|
||||
"physical_resource_id": stack_id,
|
||||
}
|
||||
new_template = vnfd.get_base_hot(
|
||||
inst.instantiatedVnfInfo.flavourId)['template']
|
||||
heat_parameter = self._update_vnf_template_and_parameter(
|
||||
stack_id, vdu_infos, vdu_id, heat_client, new_template)
|
||||
fields = {
|
||||
"stack_id": stack_id,
|
||||
"parameters": {"nfv": heat_parameter.get('nfv')},
|
||||
"template": yaml.safe_dump(
|
||||
heat_parameter.get('templates')),
|
||||
}
|
||||
try:
|
||||
heat_client.update_stack(stack_id, fields, wait=True)
|
||||
except sol_ex.StackOperationFailed:
|
||||
self._handle_exception(
|
||||
res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name, get_res_flag=True)
|
||||
self._get_new_res_info(
|
||||
stack_name,
|
||||
new_res_ids[vdu_id],
|
||||
f'{stack_name}/{stack_id}',
|
||||
vdu_infos[vdu_id], vdu_id,
|
||||
heat_client)
|
||||
templates = {}
|
||||
|
||||
# execute coordinate_vnf_script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd,
|
||||
f"{stack_name}/{stack_id}",
|
||||
heat_client, vdu_param, vim_info,
|
||||
vdu_image_id_flag,
|
||||
operation='change_vnfpkg')
|
||||
except (sol_ex.SshIpNotFoundException,
|
||||
sol_ex.CoordinateVNFExecutionFailed) as ex:
|
||||
self._handle_exception(
|
||||
res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name, ex=ex)
|
||||
def _get_template(parent_stack_id):
|
||||
if parent_stack_id not in templates:
|
||||
templates[parent_stack_id] = heat_client.get_template(
|
||||
parent_stack_id)
|
||||
return templates[parent_stack_id]
|
||||
|
||||
# Because external parameters are not updated after the image
|
||||
# of the nested-VM is updated, scale will create the original
|
||||
# VM again, so the overall update needs to be performed
|
||||
# at the end.
|
||||
fields = self._get_entire_stack_fields(
|
||||
heat_client, stack_id, group_vdu_ids, vdu_infos)
|
||||
try:
|
||||
heat_client.update_stack(stack_id, fields)
|
||||
except sol_ex.StackOperationFailed:
|
||||
self._handle_exception(
|
||||
res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name)
|
||||
self._update_vnf_instantiated_info(
|
||||
req, new_res_ids, inst, vnfd,
|
||||
heat_client, stack_name)
|
||||
inst.vnfdId = req.vnfdId
|
||||
vdu_dict = fields['parameters']['nfv']['VDU']
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
|
||||
for vnfc in vnfcs:
|
||||
if 'parent_stack_id' in vnfc.metadata:
|
||||
# it means the VM is created by OS::Heat::AutoScalingGroup
|
||||
parent_stack_id = vnfc.metadata['parent_stack_id']
|
||||
template = _get_template(parent_stack_id)
|
||||
parent_name = vnfc.metadata['parent_resource_name']
|
||||
props = template['resources'][parent_name]['properties']
|
||||
# replace 'flavor' and 'image-{vdu name}' in properties
|
||||
props['flavor'] = vdu_dict[vnfc.vduId]['computeFlavourId']
|
||||
for key in props.keys():
|
||||
if key.startswith('image-'):
|
||||
vdu_name = key.replace('image-', '')
|
||||
props[key] = vdu_dict[vdu_name]['vcImageId']
|
||||
vdu_fields = {
|
||||
"stack_id": parent_stack_id,
|
||||
"template": template
|
||||
}
|
||||
LOG.debug("stack fields: %s", vdu_fields)
|
||||
heat_client.update_stack(parent_stack_id, vdu_fields)
|
||||
else:
|
||||
# handle single VM
|
||||
# pickup 'vcImageId' and 'computeFlavourId'
|
||||
params = {}
|
||||
if vdu_dict[vnfc.vduId].get('computeFlavourId'):
|
||||
params[vnfc.vduId] = {'computeFlavourId':
|
||||
vdu_dict[vnfc.vduId]['computeFlavourId']}
|
||||
vdu_names = [vnfc.vduId]
|
||||
if vnfc.obj_attr_is_set('storageResourceIds'):
|
||||
storage_infos = (
|
||||
inst.instantiatedVnfInfo.virtualStorageResourceInfo)
|
||||
vdu_names += [
|
||||
storage_info.virtualStorageDescId
|
||||
for storage_info in storage_infos
|
||||
if storage_info.id in vnfc.storageResourceIds
|
||||
]
|
||||
for vdu_name in vdu_names:
|
||||
image = vdu_dict.get(vdu_name, {}).get('vcImageId')
|
||||
if image:
|
||||
params.setdefault(vdu_name, {})
|
||||
params[vdu_name]['vcImageId'] = image
|
||||
update_nfv_dict = {'nfv': {'VDU': params}}
|
||||
update_fields = {'parameters': update_nfv_dict}
|
||||
|
||||
update_fields = self._update_nfv_dict(heat_client, stack_name,
|
||||
update_fields)
|
||||
LOG.debug("stack fields: %s", update_fields)
|
||||
heat_client.update_stack(stack_name, update_fields)
|
||||
|
||||
# execute coordinate_vnf_script
|
||||
self._execute_coordinate_vnf_script(req, vnfd, vnfc, heat_client,
|
||||
is_rollback)
|
||||
|
||||
def _get_ssh_ip(self, stack_id, cp_name, heat_client):
|
||||
# NOTE: It is assumed that if the user want to use floating_ip,
|
||||
# he must specify the resource name of 'OS::Neutron::FloatingIP'
|
||||
# resource as cp_name (ex. VDU1_FloatingIp).
|
||||
cp_info = heat_client.get_resource_info(stack_id, cp_name)
|
||||
if cp_info.get('attributes', {}).get('floating_ip_address'):
|
||||
return cp_info['attributes']['floating_ip_address']
|
||||
elif cp_info.get('attributes', {}).get('fixed_ips'):
|
||||
return cp_info['attributes']['fixed_ips'][0].get('ip_address')
|
||||
|
||||
def _execute_coordinate_vnf_script(self, req, vnfd, vnfc, heat_client,
|
||||
is_rollback):
|
||||
if is_rollback:
|
||||
script = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-old-vnf')
|
||||
else:
|
||||
# TODO(YiFeng): Blue-Green type will be supported in Zed release.
|
||||
raise sol_ex.NotSupportUpgradeType(
|
||||
upgrade_type=req.additionalParams.get('upgrade_type'))
|
||||
script = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-new-vnf')
|
||||
if not script:
|
||||
return
|
||||
|
||||
def change_vnfpkg_rollback(
|
||||
self, req, inst, grant_req, grant, vnfd, lcmocc):
|
||||
group_vdu_ids = []
|
||||
if req.additionalParams.get('upgrade_type') == 'RollingUpdate':
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
heat_client = heat_utils.HeatClient(vim_info)
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
stack_id = heat_client.get_stack_resource(
|
||||
stack_name)['stack']["id"]
|
||||
vdu_infos = self._get_vdu_info(vnfd, grant, inst)
|
||||
new_res_ids = {}
|
||||
templates = {}
|
||||
affected_vnfcs = [affected_vnfc for affected_vnfc in
|
||||
lcmocc.resourceChanges.affectedVnfcs if
|
||||
affected_vnfc.changeType in {'ADDED', 'MODIFIED'}]
|
||||
for lcmocc_vnf in affected_vnfcs:
|
||||
if new_res_ids.get(lcmocc_vnf.vduId) is None:
|
||||
new_res_ids[lcmocc_vnf.vduId] = []
|
||||
image = vdu_infos[lcmocc_vnf.vduId]['image']
|
||||
if uuidutils.is_uuid_like(image):
|
||||
vdu_image_id_flag = True
|
||||
else:
|
||||
vdu_image_id_flag = False
|
||||
if lcmocc_vnf.metadata.get(
|
||||
'current_vnfd_id') is not inst.vnfdId:
|
||||
parent_resource_name = lcmocc_vnf.metadata.get(
|
||||
'parent_resource_name')
|
||||
if parent_resource_name:
|
||||
vdu_stack_id = lcmocc_vnf.metadata.get(
|
||||
'stack_id')
|
||||
if not templates.get(lcmocc_vnf.vduId):
|
||||
templates[lcmocc_vnf.vduId] = {}
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
group_stack_id = heat_utils.get_group_stack_id(
|
||||
heat_reses, lcmocc_vnf.vduId)
|
||||
template = heat_client.get_template(
|
||||
group_stack_id)
|
||||
templates[lcmocc_vnf.vduId] = template
|
||||
template['resources'][parent_resource_name][
|
||||
'properties']['image'] = vdu_infos[
|
||||
lcmocc_vnf.vduId].get('image')
|
||||
template['resources'][parent_resource_name][
|
||||
'properties']['flavor'] = vdu_infos[
|
||||
lcmocc_vnf.vduId].get('flavor')
|
||||
fields = {
|
||||
"stack_id": group_stack_id,
|
||||
"template": template
|
||||
}
|
||||
heat_client.update_stack(
|
||||
group_stack_id, fields, wait=True)
|
||||
self._get_new_res_info(
|
||||
parent_resource_name,
|
||||
new_res_ids[lcmocc_vnf.vduId], vdu_stack_id,
|
||||
vdu_infos[lcmocc_vnf.vduId],
|
||||
lcmocc_vnf.vduId, heat_client)
|
||||
vdu_param = [vdu_param for vdu_param in
|
||||
req.get('additionalParams').get(
|
||||
'vdu_params')
|
||||
if vdu_param.get('vdu_id')
|
||||
== lcmocc_vnf.vduId][0]
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd,
|
||||
vdu_stack_id,
|
||||
heat_client, vdu_param, vim_info,
|
||||
vdu_image_id_flag,
|
||||
operation="change_vnfpkg_rollback")
|
||||
group_vdu_ids.append(lcmocc_vnf.vduId)
|
||||
else:
|
||||
vdu_stack_id = lcmocc_vnf.metadata.get('stack_id')
|
||||
new_template = vnfd.get_base_hot(
|
||||
inst.instantiatedVnfInfo.flavourId)['template']
|
||||
heat_parameter = (
|
||||
self._update_vnf_template_and_parameter(
|
||||
stack_id, vdu_infos,
|
||||
lcmocc_vnf.vduId, heat_client, new_template))
|
||||
fields = {
|
||||
"stack_id": stack_id,
|
||||
"parameters": {"nfv": heat_parameter.get('nfv')},
|
||||
"template": yaml.safe_dump(
|
||||
heat_parameter.get('templates')),
|
||||
}
|
||||
heat_client.update_stack(stack_id,
|
||||
fields, wait=True)
|
||||
self._get_new_res_info(
|
||||
stack_name, new_res_ids[lcmocc_vnf.vduId],
|
||||
vdu_stack_id, vdu_infos[lcmocc_vnf.vduId],
|
||||
lcmocc_vnf.vduId, heat_client)
|
||||
vdu_param = [vdu_param for vdu_param in
|
||||
req.get('additionalParams').get(
|
||||
'vdu_params')
|
||||
if vdu_param.get('vdu_id')
|
||||
== lcmocc_vnf.vduId][0]
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd, vdu_stack_id,
|
||||
heat_client, vdu_param, vim_info,
|
||||
vdu_image_id_flag,
|
||||
operation="change_vnfpkg_rollback")
|
||||
fields = self._get_entire_stack_fields(
|
||||
heat_client, stack_id, group_vdu_ids, vdu_infos)
|
||||
heat_client.update_stack(stack_id, fields, wait=True)
|
||||
self._update_vnf_instantiated_info(
|
||||
req, new_res_ids, inst, vnfd,
|
||||
heat_client, stack_name, operation='change_vnfpkg_rollback')
|
||||
for vdu_param in req.additionalParams['vdu_params']:
|
||||
if vnfc.vduId == vdu_param['vdu_id']:
|
||||
break
|
||||
if is_rollback:
|
||||
vnfc_param = vdu_param['old_vnfc_param']
|
||||
else:
|
||||
# TODO(YiFeng): Blue-Green type will be supported in Zed release.
|
||||
raise sol_ex.NotSupportUpgradeType(
|
||||
upgrade_type=req.additionalParams.get('upgrade_type'))
|
||||
vnfc_param = vdu_param['new_vnfc_param']
|
||||
|
||||
ssh_ip = self._get_ssh_ip(vnfc.metadata['stack_id'],
|
||||
vnfc_param['cp_name'], heat_client)
|
||||
if not ssh_ip:
|
||||
raise sol_ex.SshIpNotFoundException()
|
||||
|
||||
vnfc_param['ssh_ip'] = ssh_ip
|
||||
vnfc_param['is_rollback'] = is_rollback
|
||||
|
||||
tmp_csar_dir = vnfd.make_tmp_csar_dir()
|
||||
script_path = os.path.join(tmp_csar_dir, script)
|
||||
out = subprocess.run(["python3", script_path],
|
||||
input=pickle.dumps(vnfc_param),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
vnfd.remove_tmp_csar_dir(tmp_csar_dir)
|
||||
if out.returncode != 0:
|
||||
LOG.error(out)
|
||||
raise sol_ex.CoordinateVNFExecutionFailed()
|
||||
|
||||
def change_vnfpkg_rollback(self, req, inst, grant_req, grant, vnfd,
|
||||
lcmocc):
|
||||
fields = userdata_default.DefaultUserData.change_vnfpkg_rollback(
|
||||
req, inst, grant_req, grant, vnfd.csar_dir)
|
||||
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
heat_client = heat_utils.HeatClient(vim_info)
|
||||
|
||||
if req.additionalParams['upgrade_type'] == 'RollingUpdate':
|
||||
self._change_vnfpkg_rolling_update(req, inst, grant_req, grant,
|
||||
vnfd, fields, heat_client, True)
|
||||
else:
|
||||
# not reach here
|
||||
pass
|
||||
|
||||
# stack update
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
|
||||
# NOTE: it is necessary to re-create instantiatedVnfInfo because
|
||||
# some resources may be changed.
|
||||
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||
heat_client)
|
||||
|
||||
def _make_hot(self, req, inst, grant_req, grant, vnfd):
|
||||
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
||||
|
@ -631,60 +530,6 @@ class Openstack(object):
|
|||
obj.maxAddress = range_data.maxAddress
|
||||
return obj
|
||||
|
||||
def _execute_coordinate_vnf_script(
|
||||
self, req, inst, grant_req, grant,
|
||||
vnfd, nested_stack_id, heat_client, vdu_param,
|
||||
vim_info, vdu_image_id_flag, operation='change_vnfpkg'):
|
||||
coordinate_vnf = None
|
||||
coordinate_vnf_class = None
|
||||
if req.obj_attr_is_set('additionalParams'):
|
||||
if operation == 'change_vnfpkg':
|
||||
coordinate_vnf = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-new-vnf')
|
||||
coordinate_vnf_class = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-new-vnf-class')
|
||||
else:
|
||||
coordinate_vnf = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-old-vnf')
|
||||
coordinate_vnf_class = req.additionalParams.get(
|
||||
'lcm-operation-coordinate-old-vnf-class')
|
||||
|
||||
if coordinate_vnf and coordinate_vnf_class:
|
||||
if operation == 'change_vnfpkg':
|
||||
ssh_ip = self._get_ssh_ip(nested_stack_id,
|
||||
vdu_param.get('new_vnfc_param'),
|
||||
heat_client)
|
||||
else:
|
||||
ssh_ip = self._get_ssh_ip(nested_stack_id,
|
||||
vdu_param.get('old_vnfc_param'),
|
||||
heat_client)
|
||||
if not ssh_ip:
|
||||
raise sol_ex.SshIpNotFoundException
|
||||
image, flavor = self._get_current_vdu_image_and_flavor(
|
||||
nested_stack_id, vdu_param.get('vdu_id'),
|
||||
heat_client, vim_info, vdu_image_id_flag)
|
||||
tmp_csar_dir = vnfd.make_tmp_csar_dir()
|
||||
script_dict = {
|
||||
"request": req.to_dict(),
|
||||
"vnf_instance": inst.to_dict(),
|
||||
"grant_request": grant_req.to_dict(),
|
||||
"grant_response": grant.to_dict(),
|
||||
"tmp_csar_dir": tmp_csar_dir,
|
||||
"vdu_info": {
|
||||
"ssh_ip": ssh_ip,
|
||||
"new_image": image,
|
||||
"new_flavor": flavor,
|
||||
"vdu_param": vdu_param
|
||||
}
|
||||
}
|
||||
script_path = os.path.join(tmp_csar_dir, coordinate_vnf)
|
||||
out = subprocess.run(["python3", script_path],
|
||||
input=pickle.dumps(script_dict),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if out.returncode != 0:
|
||||
LOG.error(out)
|
||||
raise sol_ex.CoordinateVNFExecutionFailed
|
||||
|
||||
def _proto_data_to_info(self, proto_data):
|
||||
# make CpProtocolInfo (5.5.3.9b) from CpProtocolData (4.4.1.10b)
|
||||
proto_info = objects.CpProtocolInfoV2(
|
||||
|
@ -776,285 +621,6 @@ class Openstack(object):
|
|||
|
||||
return ext_vl
|
||||
|
||||
def _get_vdu_info(self, vnfd, grant, inst):
|
||||
flavour_id = inst.instantiatedVnfInfo.flavourId
|
||||
vdu_nodes = vnfd.get_vdu_nodes(flavour_id)
|
||||
storage_nodes = vnfd.get_storage_nodes(flavour_id)
|
||||
vdu_info_dict = {}
|
||||
for name, node in vdu_nodes.items():
|
||||
flavor = self._get_param_flavor(vnfd, name, flavour_id, grant)
|
||||
image = self._get_param_image(vnfd, name, flavour_id, grant)
|
||||
vdu_storage_names = vnfd.get_vdu_storages(node)
|
||||
volume_name = ''
|
||||
volume_size = ''
|
||||
for vdu_storage_name in vdu_storage_names:
|
||||
if storage_nodes[vdu_storage_name].get(
|
||||
'properties').get('sw_image_data'):
|
||||
image = self._get_param_image(
|
||||
vnfd, vdu_storage_name, flavour_id, grant)
|
||||
volume_name = vdu_storage_name
|
||||
volume_size = storage_nodes[vdu_storage_name].get(
|
||||
'properties', {}).get(
|
||||
'virtual_block_storage_data', '').get(
|
||||
'size_of_storage', ''
|
||||
)
|
||||
volume_size = volume_size.rstrip(' GB')
|
||||
if not volume_size.isdigit():
|
||||
raise sol_ex.InvalidVolumeSize
|
||||
break
|
||||
|
||||
vdu_info_dict[name] = {
|
||||
"flavor": flavor,
|
||||
"image": image
|
||||
}
|
||||
|
||||
if volume_name:
|
||||
vdu_info_dict[name]['volume_info'] = {
|
||||
"volume_name": volume_name,
|
||||
"volume_size": volume_size
|
||||
}
|
||||
return vdu_info_dict
|
||||
|
||||
def _get_param_flavor(self, vnfd, vdu_name, flavour_id, grant):
|
||||
# try to get from grant
|
||||
if grant.obj_attr_is_set('vimAssets'):
|
||||
assets = grant.vimAssets
|
||||
if assets.obj_attr_is_set('computeResourceFlavours'):
|
||||
flavours = assets.computeResourceFlavours
|
||||
for flavour in flavours:
|
||||
if flavour.vnfdVirtualComputeDescId == vdu_name:
|
||||
return flavour.vimFlavourId
|
||||
# if specified in VNFD, use it
|
||||
# NOTE: if not found. parameter is set to None.
|
||||
# may be error when stack create
|
||||
return vnfd.get_compute_flavor(flavour_id, vdu_name)
|
||||
|
||||
def _get_param_image(self, vnfd, vdu_name, flavour_id, grant):
|
||||
# try to get from grant
|
||||
if grant.obj_attr_is_set('vimAssets'):
|
||||
assets = grant.vimAssets
|
||||
if assets.obj_attr_is_set('softwareImages'):
|
||||
images = assets.softwareImages
|
||||
for image in images:
|
||||
if image.vnfdSoftwareImageId == vdu_name:
|
||||
return image.vimSoftwareImageId
|
||||
|
||||
# if specified in VNFD, use it
|
||||
# NOTE: if not found. parameter is set to None.
|
||||
# may be error when stack create
|
||||
sw_images = vnfd.get_sw_image(flavour_id)
|
||||
for name, image in sw_images.items():
|
||||
if name == vdu_name:
|
||||
return image
|
||||
|
||||
return None
|
||||
|
||||
def _get_current_vdu_image_and_flavor(
|
||||
self, nested_stack_id, resource_name,
|
||||
heat_client, vim_info, vdu_image_id_flag):
|
||||
vdu_info = heat_client.get_resource_info(
|
||||
nested_stack_id, resource_name)
|
||||
if vdu_info.get('attributes').get('image'):
|
||||
image = vdu_info.get('attributes').get('image').get('id')
|
||||
if not vdu_image_id_flag:
|
||||
glance_client = glance_utils.GlanceClient(vim_info)
|
||||
image = glance_client.get_image(image).name
|
||||
|
||||
else:
|
||||
volume_ids = [volume.get('id') for volume in vdu_info.get(
|
||||
'attributes').get('os-extended-volumes:volumes_attached')]
|
||||
cinder_client = cinder_utils.CinderClient(vim_info)
|
||||
if vdu_image_id_flag:
|
||||
image = [cinder_client.get_volume(
|
||||
volume_id).volume_image_metadata.get('image_id')
|
||||
for volume_id in volume_ids if cinder_client.get_volume(
|
||||
volume_id).volume_image_metadata][0]
|
||||
else:
|
||||
image = [cinder_client.get_volume(
|
||||
volume_id).volume_image_metadata.get('image_name')
|
||||
for volume_id in volume_ids if cinder_client.get_volume(
|
||||
volume_id).volume_image_metadata][0]
|
||||
flavor_name = vdu_info.get('attributes').get('flavor').get(
|
||||
'original_name')
|
||||
|
||||
return image, flavor_name
|
||||
|
||||
def _get_new_res_info(self, parent_resource_name, vdu_infos,
|
||||
stack_id, vnfd_info, vdu_id, heat_client):
|
||||
new_res_infos = {
|
||||
"stack_id": stack_id,
|
||||
"parent_resource_name": parent_resource_name
|
||||
}
|
||||
nested_reses = heat_client.get_resource_list(
|
||||
stack_id.split('/')[1])['resources']
|
||||
for nested_res in nested_reses:
|
||||
if nested_res.get(
|
||||
'resource_type') == 'OS::Nova::Server' and nested_res.get(
|
||||
'resource_name') == vdu_id:
|
||||
new_res_infos["vdu_id"] = nested_res.get(
|
||||
'physical_resource_id')
|
||||
elif nested_res.get(
|
||||
'resource_type'
|
||||
) == 'OS::Cinder::Volume' and nested_res.get(
|
||||
'resource_name') == vnfd_info.get(
|
||||
'volume_info').get('volume_name'):
|
||||
new_res_infos['volume_info'] = {
|
||||
"volume_name": nested_res.get('resource_name'),
|
||||
"volume_id": nested_res.get('physical_resource_id')
|
||||
}
|
||||
vdu_infos.append(new_res_infos)
|
||||
|
||||
def _get_ssh_ip(self, nested_stack_id, vnfc_param, heat_client):
|
||||
cp_name = vnfc_param.get('cp_name')
|
||||
cp_info = heat_client.get_resource_info(nested_stack_id, cp_name)
|
||||
if cp_info.get('attributes').get('floating_ip_address'):
|
||||
ssh_ip = cp_info.get('attributes').get('floating_ip_address')
|
||||
else:
|
||||
ssh_ip = cp_info.get('attributes').get('fixed_ips')[0].get(
|
||||
'ip_address')
|
||||
return ssh_ip
|
||||
|
||||
def _update_vnf_instantiated_info(
|
||||
self, req, new_res_ids, inst, vnfd, heat_client, stack_name,
|
||||
operation='change_vnfpkg'):
|
||||
instantiated_vnf_info = inst.instantiatedVnfInfo
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
storage_reses = self._get_checked_reses(
|
||||
vnfd.get_storage_nodes(inst.instantiatedVnfInfo.flavourId),
|
||||
heat_utils.get_storage_reses(heat_reses))
|
||||
|
||||
# handle storage_info
|
||||
def _res_to_handle(res):
|
||||
return objects.ResourceHandle(
|
||||
resourceId=res['physical_resource_id'],
|
||||
vimLevelResourceType=res['resource_type'],
|
||||
vimConnectionId=vim_info.vimId)
|
||||
|
||||
storage_infos = [
|
||||
objects.VirtualStorageResourceInfoV2(
|
||||
id=res_id,
|
||||
virtualStorageDescId=res['resource_name'],
|
||||
storageResource=_res_to_handle(res)
|
||||
)
|
||||
for res_id, res in storage_reses.items()
|
||||
]
|
||||
|
||||
# handle vnfc_resource_info
|
||||
for vnfc_res in instantiated_vnf_info.vnfcResourceInfo:
|
||||
if new_res_ids.get(vnfc_res.vduId):
|
||||
new_res_info = [vnfc_info for vnfc_info
|
||||
in new_res_ids.get(vnfc_res.vduId)
|
||||
if vnfc_info['stack_id']
|
||||
== vnfc_res.metadata['stack_id']]
|
||||
if not new_res_info:
|
||||
continue
|
||||
new_res_info = new_res_info[0]
|
||||
current_vnfc = []
|
||||
if instantiated_vnf_info.obj_attr_is_set('vnfcInfo'):
|
||||
current_vnfc = [
|
||||
vnfc for vnfc in instantiated_vnf_info.vnfcInfo
|
||||
if vnfc.id == _make_combination_id(
|
||||
vnfc_res.vduId, vnfc_res.id)][0]
|
||||
vnfc_res.id = new_res_info.get('vdu_id')
|
||||
vnfc_res.computeResource.resourceId = new_res_info.get(
|
||||
'vdu_id')
|
||||
if current_vnfc:
|
||||
current_vnfc.id = _make_combination_id(
|
||||
vnfc_res.vduId, vnfc_res.id)
|
||||
current_vnfc.vnfcResourceInfoId = vnfc_res.id
|
||||
if operation == 'change_vnfpkg':
|
||||
vnfc_res.metadata['current_vnfd_id'] = req.vnfdId
|
||||
else:
|
||||
vnfc_res.metadata['current_vnfd_id'] = inst.vnfdId
|
||||
storage_ids = [
|
||||
storage_id for storage_id, storage_res in
|
||||
storage_reses.items()
|
||||
if (vnfc_res.vduId in storage_res.get(
|
||||
'required_by', []))]
|
||||
if vnfc_res.metadata.get('parent_resource_name') != stack_name:
|
||||
storage_ids = [
|
||||
storage_id for storage_id, storage_res in
|
||||
storage_reses.items()
|
||||
if (vnfc_res.vduId in storage_res.get(
|
||||
'required_by', []) and vnfc_res.metadata.get(
|
||||
'parent_resource_name') == storage_res.get(
|
||||
'parent_resource'))]
|
||||
if storage_ids:
|
||||
vnfc_res.storageResourceIds = storage_ids
|
||||
else:
|
||||
if vnfc_res.obj_attr_is_set('storageResourceIds'):
|
||||
del vnfc_res.storageResourceIds
|
||||
|
||||
if storage_infos:
|
||||
instantiated_vnf_info.virtualStorageResourceInfo = storage_infos
|
||||
else:
|
||||
if instantiated_vnf_info.obj_attr_is_set(
|
||||
'virtualStorageResourceInfo'):
|
||||
del instantiated_vnf_info.virtualStorageResourceInfo
|
||||
|
||||
def _update_vnf_template_and_parameter(
|
||||
self, stack_id, vdu_infos, vdu_id, heat_client, new_template):
|
||||
vdu_info = vdu_infos[vdu_id]
|
||||
volume_info = vdu_info.get('volume_info', {})
|
||||
base_templates = heat_client.get_template(stack_id)
|
||||
old_parameter = heat_client.get_parameters(stack_id)['nfv']
|
||||
new_parameter = json.loads(copy.deepcopy(old_parameter))
|
||||
|
||||
# old VM(created by volume) -> new VM(created by volume)
|
||||
if volume_info and 'image' not in base_templates[
|
||||
'resources'][vdu_id]['properties']:
|
||||
new_parameter['VDU'][vdu_id]['computeFlavourId'] = vdu_info.get(
|
||||
'flavor')
|
||||
new_parameter['VDU'][volume_info.get('volume_name')][
|
||||
'vcImageId'] = vdu_info.get('image')
|
||||
|
||||
# old VM(created by volume) -> new VM(created by image)
|
||||
elif vdu_info.get(
|
||||
'volume_info') is None and 'image' not in base_templates[
|
||||
'resources'][vdu_id]['properties']:
|
||||
# delete vdu's volume definition info
|
||||
if len(base_templates['resources'][vdu_id]['properties'][
|
||||
'block_device_mapping_v2']) > 1:
|
||||
old_volumes = [name for name, value in
|
||||
base_templates['resources'].items()
|
||||
if value['type'] == 'OS::Cinder::Volume'
|
||||
and value['properties']['image']]
|
||||
for volume in base_templates['resources'][
|
||||
vdu_id]['properties']['block_device_mapping_v2']:
|
||||
if volume['volume_id']['get_resource'] in old_volumes:
|
||||
target_volume_name = volume['volume_id'][
|
||||
'get_resource']
|
||||
else:
|
||||
target_volume_name = base_templates['resources'][
|
||||
vdu_id]['properties']['block_device_mapping_v2'][0][
|
||||
'volume_id']['get_resource']
|
||||
del new_parameter['VDU'][target_volume_name]
|
||||
new_parameter['VDU'][vdu_id]['computeFlavourId'] = vdu_info.get(
|
||||
'flavor')
|
||||
new_parameter['VDU'][vdu_id]['vcImageId'] = vdu_info.get('image')
|
||||
|
||||
# old VM(created by image) -> new VM(created by volume)
|
||||
elif volume_info and 'image' in base_templates[
|
||||
'resources'][vdu_id]['properties']:
|
||||
del new_parameter['VDU'][vdu_id]['vcImageId']
|
||||
new_parameter['VDU'][vdu_id]['computeFlavourId'] = vdu_info.get(
|
||||
'flavor')
|
||||
new_parameter['VDU'][volume_info.get('volume_name')] = {
|
||||
"vcImageId": vdu_infos[vdu_id].get('image')
|
||||
}
|
||||
# old VM(created by image) -> new VM(created by image)
|
||||
else:
|
||||
new_parameter['VDU'][vdu_id]['computeFlavourId'] = vdu_info.get(
|
||||
'flavor')
|
||||
new_parameter['VDU'][vdu_id]['vcImageId'] = vdu_info.get('image')
|
||||
|
||||
heat_parameter = {
|
||||
"templates": new_template,
|
||||
"nfv": new_parameter
|
||||
}
|
||||
return heat_parameter
|
||||
|
||||
def _make_ext_vl_info_from_req(self, req, grant, ext_cp_infos):
|
||||
# make extVirtualLinkInfo
|
||||
req_ext_vls = []
|
||||
|
@ -1322,8 +888,43 @@ class Openstack(object):
|
|||
|
||||
return metadata
|
||||
|
||||
def _update_vnfc_metadata(self, vnfc_res_infos, storage_infos,
|
||||
heat_client, nfv_dict):
|
||||
for vnfc_res_info in vnfc_res_infos:
|
||||
metadata = vnfc_res_info.metadata
|
||||
if 'parent_stack_id' in metadata:
|
||||
# VDU defined by AutoScalingGroup
|
||||
template = heat_client.get_template(
|
||||
metadata['parent_stack_id'])
|
||||
properties = (template['resources']
|
||||
[metadata['parent_resource_name']]
|
||||
['properties'])
|
||||
metadata['flavor'] = properties['flavor']
|
||||
for k, v in properties.items():
|
||||
if k.startswith('image-'):
|
||||
metadata[k] = v
|
||||
else:
|
||||
properties = nfv_dict['VDU'][vnfc_res_info.vduId]
|
||||
metadata['flavor'] = properties['computeFlavourId']
|
||||
vdu_names = [vnfc_res_info.vduId]
|
||||
if vnfc_res_info.obj_attr_is_set('storageResourceIds'):
|
||||
vdu_names += [
|
||||
storage_info.virtualStorageDescId
|
||||
for storage_info in storage_infos
|
||||
if storage_info.id in vnfc_res_info.storageResourceIds
|
||||
]
|
||||
for vdu_name in vdu_names:
|
||||
image = nfv_dict['VDU'].get(vdu_name, {}).get('vcImageId')
|
||||
if image:
|
||||
metadata[f'image-{vdu_name}'] = image
|
||||
|
||||
def _make_instantiated_vnf_info(self, req, inst, grant_req, grant, vnfd,
|
||||
heat_reses):
|
||||
heat_client):
|
||||
# get heat resources
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
nfv_dict = json.loads(heat_client.get_parameters(stack_name)['nfv'])
|
||||
|
||||
op = grant_req.operation
|
||||
if op == v2fields.LcmOperationType.INSTANTIATE:
|
||||
flavour_id = req.flavourId
|
||||
|
@ -1395,6 +996,9 @@ class Openstack(object):
|
|||
if cp_infos:
|
||||
vnfc_res_info.vnfcCpInfo = cp_infos
|
||||
|
||||
self._update_vnfc_metadata(vnfc_res_infos, storage_infos,
|
||||
heat_client, nfv_dict)
|
||||
|
||||
vnf_vl_res_infos = [
|
||||
objects.VnfVirtualLinkResourceInfoV2(
|
||||
id=res_id,
|
||||
|
@ -1539,47 +1143,3 @@ class Openstack(object):
|
|||
inst_vnf_info.vnfcInfo = vnfc_infos
|
||||
|
||||
inst.instantiatedVnfInfo = inst_vnf_info
|
||||
|
||||
def _handle_exception(
|
||||
self, res, new_res_ids, vdu_infos,
|
||||
vdu_id, heat_client, req, inst, vnfd,
|
||||
stack_name, ex=None, get_res_flag=False):
|
||||
if get_res_flag:
|
||||
if len(res.keys()) == 2:
|
||||
par_stack_id = '{}/{}'.format(
|
||||
res.get('resource_name'),
|
||||
res.get('physical_resource_id'))
|
||||
else:
|
||||
par_stack_id = heat_utils.get_parent_nested_id(res)
|
||||
self._get_new_res_info(
|
||||
res.get('resource_name'),
|
||||
new_res_ids[vdu_id],
|
||||
par_stack_id,
|
||||
vdu_infos[vdu_id], vdu_id,
|
||||
heat_client)
|
||||
self._update_vnf_instantiated_info(
|
||||
req, new_res_ids, inst,
|
||||
vnfd, heat_client, stack_name)
|
||||
if ex:
|
||||
raise ex
|
||||
raise sol_ex.StackOperationFailed
|
||||
|
||||
def _get_entire_stack_fields(self, heat_client, stack_id,
|
||||
group_vdu_ids, vdu_infos):
|
||||
parameter = json.loads(heat_client.get_parameters(stack_id)['nfv'])
|
||||
for group_vdu_id in group_vdu_ids:
|
||||
if not parameter['VDU'][group_vdu_id].get('vcImageId'):
|
||||
volume_info = vdu_infos[
|
||||
group_vdu_id].get('volume_info')
|
||||
parameter['VDU'][volume_info.get('volume_name')][
|
||||
'vcImageId'] = vdu_infos[group_vdu_id].get(
|
||||
'image')
|
||||
else:
|
||||
parameter['VDU'][group_vdu_id][
|
||||
'vcImageId'] = vdu_infos[group_vdu_id].get(
|
||||
'image')
|
||||
fields = {
|
||||
"stack_id": stack_id,
|
||||
"parameters": {"nfv": parameter}
|
||||
}
|
||||
return fields
|
||||
|
|
|
@ -249,3 +249,75 @@ class DefaultUserData(userdata_utils.AbstractUserData):
|
|||
fields = {'parameters': {'nfv': {}}}
|
||||
|
||||
return fields
|
||||
|
||||
@staticmethod
|
||||
def change_vnfpkg(req, inst, grant_req, grant, tmp_csar_dir):
|
||||
vnfd = common_script_utils.get_vnfd(grant_req['dstVnfdId'],
|
||||
tmp_csar_dir)
|
||||
flavour_id = inst['instantiatedVnfInfo']['flavourId']
|
||||
|
||||
hot_dict = vnfd.get_base_hot(flavour_id)
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
|
||||
vdus = nfv_dict.get('VDU', {})
|
||||
new_vdus = {}
|
||||
for vdu_name, vdu_value in vdus.items():
|
||||
if 'computeFlavourId' in vdu_value:
|
||||
flavor = common_script_utils.get_param_flavor(
|
||||
vdu_name, flavour_id, vnfd, grant)
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['computeFlavourId'] = flavor
|
||||
if 'vcImageId' in vdu_value:
|
||||
image = common_script_utils.get_param_image(
|
||||
vdu_name, flavour_id, vnfd, grant)
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['vcImageId'] = image
|
||||
|
||||
fields = {
|
||||
'parameters': {'nfv': {'VDU': new_vdus}}
|
||||
}
|
||||
|
||||
return fields
|
||||
|
||||
@staticmethod
|
||||
def change_vnfpkg_rollback(req, inst, grant_req, grant, tmp_csar_dir):
|
||||
images = {}
|
||||
flavors = {}
|
||||
for vnfc in inst.get('instantiatedVnfInfo', {}).get(
|
||||
'vnfcResourceInfo', []):
|
||||
vdu_name = vnfc['vduId']
|
||||
if vdu_name in flavors:
|
||||
continue
|
||||
for key, value in vnfc['metadata'].items():
|
||||
if key == 'flavor':
|
||||
flavors[vdu_name] = value
|
||||
elif key.startswith('image-'):
|
||||
image_vdu = key.replace('image-', '')
|
||||
images[image_vdu] = value
|
||||
|
||||
vnfd = common_script_utils.get_vnfd(inst['vnfdId'],
|
||||
tmp_csar_dir)
|
||||
flavour_id = inst['instantiatedVnfInfo']['flavourId']
|
||||
|
||||
hot_dict = vnfd.get_base_hot(flavour_id)
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
|
||||
vdus = nfv_dict.get('VDU', {})
|
||||
new_vdus = {}
|
||||
for vdu_name, vdu_value in vdus.items():
|
||||
if 'computeFlavourId' in vdu_value:
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['computeFlavourId'] = flavors.get(vdu_name)
|
||||
if 'vcImageId' in vdu_value:
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['vcImageId'] = images.get(vdu_name)
|
||||
|
||||
fields = {
|
||||
'parameters': {'nfv': {'VDU': new_vdus}}
|
||||
}
|
||||
|
||||
return fields
|
||||
|
|
|
@ -43,7 +43,7 @@ LOG = logging.getLogger(__name__)
|
|||
# NOTE:
|
||||
# It is NFVO implementation used when an external NFVO is not used.
|
||||
# It implements only functions necessary for vnflcm v2.
|
||||
# It uses original tacker vnfpkgm v1 for vnf package managemnet
|
||||
# It uses original tacker vnfpkgm v1 for vnf package management
|
||||
# and adds grant functions.
|
||||
|
||||
|
||||
|
@ -138,13 +138,49 @@ class LocalNfvo(object):
|
|||
|
||||
def _get_vim_info(self, context, grant_req):
|
||||
lcmocc = lcmocc_utils.get_lcmocc(context, grant_req.vnfLcmOpOccId)
|
||||
inst_req = lcmocc.operationParams
|
||||
if inst_req.obj_attr_is_set('vimConnectionInfo'):
|
||||
return inst_utils.select_vim_info(inst_req.vimConnectionInfo)
|
||||
req = lcmocc.operationParams
|
||||
if req.obj_attr_is_set('vimConnectionInfo'):
|
||||
return inst_utils.select_vim_info(req.vimConnectionInfo)
|
||||
elif grant_req.operation != v2_fields.LcmOperationType.INSTANTIATE:
|
||||
# should be found
|
||||
inst = inst_utils.get_inst(context, grant_req.vnfInstanceId)
|
||||
return inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
|
||||
# NOTE: exception is not raised.
|
||||
return vim_utils.get_default_vim(context)
|
||||
|
||||
def _handle_vim_assets(self, grant_req, grant_res, vnfd, sw_image_data,
|
||||
vim_info):
|
||||
vim_sw_images = []
|
||||
for res_id, sw_data in sw_image_data.items():
|
||||
if 'file' in sw_data:
|
||||
# if artifact is specified, create glance image.
|
||||
# it may fail. catch exception and raise 403(not granted)
|
||||
# if error occur.
|
||||
if vim_info is None:
|
||||
msg = "No vimConnectionInfo to create glance image"
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
|
||||
try:
|
||||
image = self._glance_create_image(vim_info, vnfd, sw_data,
|
||||
grant_req.vnfInstanceId)
|
||||
except Exception:
|
||||
msg = "glance image create failed"
|
||||
LOG.exception(msg)
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
else:
|
||||
# there is no artifact. suppose image already created.
|
||||
image = sw_data['name']
|
||||
vim_sw_image = objects.VimSoftwareImageV1(
|
||||
vnfdSoftwareImageId=res_id,
|
||||
vimSoftwareImageId=image)
|
||||
vim_sw_images.append(vim_sw_image)
|
||||
|
||||
if vim_sw_images:
|
||||
grant_res.vimAssets = objects.GrantV1_VimAssets(
|
||||
softwareImages=vim_sw_images
|
||||
)
|
||||
|
||||
def instantiate_grant(self, context, grant_req, grant_res):
|
||||
# handle ZoneInfo
|
||||
zone_list = config.CONF.v2_nfvo.test_grant_zone_list
|
||||
|
@ -178,83 +214,26 @@ class LocalNfvo(object):
|
|||
# if there is an artifact, create glance image.
|
||||
vnfd = self.get_vnfd(context, grant_req.vnfdId)
|
||||
sw_image_data = vnfd.get_sw_image_data(grant_req.flavourId)
|
||||
vim_sw_images = []
|
||||
for res_id, sw_data in sw_image_data.items():
|
||||
if 'file' in sw_data:
|
||||
# if artifact is specified, create glance image.
|
||||
# it may fail. catch exception and raise 403(not granted)
|
||||
# if error occur.
|
||||
|
||||
# get vim_info to access glance
|
||||
vim_info = self._get_vim_info(context, grant_req)
|
||||
if vim_info is None:
|
||||
msg = "No vimConnectionInfo to create glance image"
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
|
||||
try:
|
||||
image = self._glance_create_image(vim_info, vnfd, sw_data,
|
||||
grant_req.vnfInstanceId)
|
||||
except Exception:
|
||||
msg = "glance image create failed"
|
||||
LOG.exception(msg)
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
else:
|
||||
# there is no artifact. suppose image already created.
|
||||
image = sw_data['name']
|
||||
vim_sw_image = objects.VimSoftwareImageV1(
|
||||
vnfdSoftwareImageId=res_id,
|
||||
vimSoftwareImageId=image)
|
||||
vim_sw_images.append(vim_sw_image)
|
||||
if vim_sw_images:
|
||||
grant_res.vimAssets = objects.GrantV1_VimAssets(
|
||||
softwareImages=vim_sw_images
|
||||
)
|
||||
vim_info = self._get_vim_info(context, grant_req)
|
||||
self._handle_vim_assets(grant_req, grant_res, vnfd,
|
||||
sw_image_data, vim_info)
|
||||
|
||||
def change_vnfpkg_grant(self, context, grant_req, grant_res):
|
||||
attr_list = ['updateResources', 'addResources', 'removeResources']
|
||||
for attr in attr_list:
|
||||
if grant_req.obj_attr_is_set(attr):
|
||||
res_list = []
|
||||
for res_def in grant_req[attr]:
|
||||
g_info = objects.GrantInfoV1(res_def.id)
|
||||
res_list.append(g_info)
|
||||
grant_res[attr] = res_list
|
||||
vnfd = self.get_vnfd(context, grant_req.vnfdId)
|
||||
sw_image_data = vnfd.get_sw_image_data(grant_req.flavourId)
|
||||
target_vdu_ids = [res['resourceTemplateId'] for
|
||||
res in grant_req['updateResources']]
|
||||
vdu_nodes = {key: value for key, value in vnfd.get_vdu_nodes(
|
||||
grant_req.flavourId).items() if key in target_vdu_ids}
|
||||
target_storage_nodes = []
|
||||
for key, value in vdu_nodes.items():
|
||||
target_storage_nodes.extend(vnfd.get_vdu_storages(value))
|
||||
if not grant_req.obj_attr_is_set('addResources'):
|
||||
return
|
||||
|
||||
vim_sw_images = []
|
||||
for res_id, sw_data in sw_image_data.items():
|
||||
if 'file' in sw_data and (res_id in target_storage_nodes or
|
||||
res_id in target_vdu_ids):
|
||||
vim_info = self._get_vim_info(context, grant_req)
|
||||
if vim_info is None:
|
||||
msg = "No VimConnectionInfo to create glance image"
|
||||
LOG.exception(msg)
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
try:
|
||||
image = self._glance_create_image(
|
||||
vim_info, vnfd, sw_data, grant_req.vnfInstanceId)
|
||||
except Exception:
|
||||
msg = "glance image create failed"
|
||||
LOG.exception(msg)
|
||||
raise sol_ex.LocalNfvoGrantFailed(sol_detail=msg)
|
||||
else:
|
||||
image = sw_data['name']
|
||||
vim_sw_image = objects.VimSoftwareImageV1(
|
||||
vnfdSoftwareImageId=res_id,
|
||||
vimSoftwareImageId=image)
|
||||
vim_sw_images.append(vim_sw_image)
|
||||
if vim_sw_images:
|
||||
grant_res.vimAssets = objects.GrantV1_VimAssets(
|
||||
softwareImages=vim_sw_images
|
||||
)
|
||||
# handle vimAssets
|
||||
# if there is an artifact, create glance image.
|
||||
target_vdus = {res['resourceTemplateId']
|
||||
for res in grant_req['addResources']}
|
||||
vnfd = self.get_vnfd(context, grant_req.dstVnfdId)
|
||||
all_sw_image_data = vnfd.get_sw_image_data(grant_req.flavourId)
|
||||
sw_image_data = {res_id: sw_data
|
||||
for res_id, sw_data in all_sw_image_data.items()
|
||||
if res_id in target_vdus}
|
||||
vim_info = self._get_vim_info(context, grant_req)
|
||||
self._handle_vim_assets(grant_req, grant_res, vnfd,
|
||||
sw_image_data, vim_info)
|
||||
|
||||
def grant(self, context, grant_req):
|
||||
grant_res = objects.GrantV1(
|
||||
|
@ -263,11 +242,9 @@ class LocalNfvo(object):
|
|||
vnfLcmOpOccId=grant_req.vnfLcmOpOccId
|
||||
)
|
||||
|
||||
# NOTE: considered instantiate only at the moment.
|
||||
# terminate is granted with no grant_res constructed.
|
||||
# NOTE: considered instantiate and change_vnfpkg only at the moment.
|
||||
if grant_req.operation == v2_fields.LcmOperationType.INSTANTIATE:
|
||||
self.instantiate_grant(context, grant_req, grant_res)
|
||||
|
||||
elif grant_req.operation == v2_fields.LcmOperationType.CHANGE_VNFPKG:
|
||||
self.change_vnfpkg_grant(context, grant_req, grant_res)
|
||||
|
||||
|
|
|
@ -205,10 +205,8 @@ def change_vnfpkg_all_params(vnfd_id):
|
|||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf":
|
||||
"Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf":
|
||||
"Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"lcm-kubernetes-def-files": [
|
||||
"Files/new_kubernetes/new_deployment.yaml"],
|
||||
"vdu_params": [{
|
||||
|
@ -243,10 +241,8 @@ def change_vnfpkg_min(vnfd_id):
|
|||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf":
|
||||
"Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf":
|
||||
"Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,10 +272,8 @@ def change_vnfpkg_error(vnfd_id):
|
|||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf":
|
||||
"Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf":
|
||||
"Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"lcm-kubernetes-def-files": [
|
||||
"Files/new_kubernetes/error_deployment.yaml"]
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import ddt
|
||||
import os
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from tacker.tests.functional.sol_kubernetes_v2 import base_v2
|
||||
from tacker.tests.functional.sol_kubernetes_v2 import paramgen
|
||||
|
@ -50,6 +51,7 @@ class VnfLcmKubernetesErrorHandingTest(base_v2.BaseVnfLcmKubernetesV2Test):
|
|||
def setUp(self):
|
||||
super(VnfLcmKubernetesErrorHandingTest, self).setUp()
|
||||
|
||||
@unittest.skip("Until refactor CNF v2 API")
|
||||
def test_change_vnfpkg_failed_in_update_wait_and_rollback(self):
|
||||
"""Test LCM operations error handing
|
||||
|
||||
|
@ -182,6 +184,7 @@ class VnfLcmKubernetesErrorHandingTest(base_v2.BaseVnfLcmKubernetesV2Test):
|
|||
usage_state = self.get_vnf_package(self.vnf_pkg_2).get('usageState')
|
||||
self.assertEqual('NOT_IN_USE', usage_state)
|
||||
|
||||
@unittest.skip("Until refactor CNF v2 API")
|
||||
def test_change_vnfpkg_failed_and_retry(self):
|
||||
"""Test LCM operations error handing
|
||||
|
||||
|
|
|
@ -342,12 +342,16 @@ class GrantV2:
|
|||
|
||||
@staticmethod
|
||||
def make_change_vnfpkg_response_body(
|
||||
request_body):
|
||||
request_body, image_id_dict, flavour_id_dict):
|
||||
request_body = GrantV2.convert_body_to_dict(request_body)
|
||||
res = GrantV2._make_response_template(request_body)
|
||||
if 'addResources' in request_body.keys():
|
||||
res["addResources"] = GrantV2._make_add_resources(
|
||||
request_body['addResources'])
|
||||
res["vimAssets"] = GrantV2._make_vim_assets(
|
||||
request_body['addResources'],
|
||||
image_id_dict,
|
||||
flavour_id_dict)
|
||||
if 'removeResources' in request_body.keys():
|
||||
res["removeResources"] = GrantV2._make_remove_resources(
|
||||
request_body['removeResources'])
|
||||
|
|
|
@ -25,7 +25,7 @@ class VnfLcmWithNfvoSeparator(test_vnflcm_basic_common.CommonVnfLcmTest):
|
|||
self.basic_lcms_min_common_test(True)
|
||||
|
||||
def test_change_vnfpkg(self):
|
||||
self.change_vnfpkg_from_image_to_volume_common_test(True)
|
||||
self.change_vnfpkg_from_image_to_image_common_test(True)
|
||||
|
||||
def test_retry_rollback_scale_out(self):
|
||||
self.retry_rollback_scale_out_common_test(True)
|
||||
|
|
|
@ -73,196 +73,7 @@ class ChangeVnfPkgVnfLcmTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
|||
super(ChangeVnfPkgVnfLcmTest, self).setUp()
|
||||
|
||||
def test_change_vnfpkg_from_image_to_image(self):
|
||||
create_req = paramgen.change_vnfpkg_create(self.vnfd_id_1)
|
||||
resp, body = self.create_vnf_instance(create_req)
|
||||
expected_inst_attrs = [
|
||||
'id',
|
||||
'vnfInstanceName',
|
||||
'vnfInstanceDescription',
|
||||
'vnfdId',
|
||||
'vnfProvider',
|
||||
'vnfProductName',
|
||||
'vnfSoftwareVersion',
|
||||
'vnfdVersion',
|
||||
# 'vnfConfigurableProperties', # omitted
|
||||
# 'vimConnectionInfo', # omitted
|
||||
'instantiationState',
|
||||
# 'instantiatedVnfInfo', # omitted
|
||||
'metadata',
|
||||
# 'extensions', # omitted
|
||||
'_links'
|
||||
]
|
||||
self.assertEqual(201, resp.status_code)
|
||||
self.check_resp_headers_in_create(resp)
|
||||
self.check_resp_body(body, expected_inst_attrs)
|
||||
inst_id = body['id']
|
||||
|
||||
net_ids = self.get_network_ids(['net0', 'net1', 'net_mgmt'])
|
||||
subnet_ids = self.get_subnet_ids(['subnet0', 'subnet1'])
|
||||
instantiate_req = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, self.auth_url)
|
||||
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
additional_inst_attrs = [
|
||||
'vimConnectionInfo',
|
||||
'instantiatedVnfInfo'
|
||||
]
|
||||
expected_inst_attrs.extend(additional_inst_attrs)
|
||||
resp_1, body_1 = self.show_vnf_instance(inst_id)
|
||||
stack_name = "vnf-{}".format(inst_id)
|
||||
stack_id = self.heat_client.get_stack_resource(stack_name)['stack'][
|
||||
'id']
|
||||
image_id_1 = self.get_current_vdu_image(stack_id, stack_name, 'VDU2')
|
||||
old_vnfd_id = body_1['vnfdId']
|
||||
|
||||
self.assertEqual(200, resp_1.status_code)
|
||||
self.check_resp_headers_in_get(resp_1)
|
||||
self.check_resp_body(body_1, expected_inst_attrs)
|
||||
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(self.vnfd_id_2)
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
resp_2, body_2 = self.show_vnf_instance(inst_id)
|
||||
image_id_2 = self.get_current_vdu_image(stack_id, stack_name, 'VDU2')
|
||||
self.assertNotEqual(image_id_1, image_id_2)
|
||||
|
||||
self.assertEqual(200, resp_2.status_code)
|
||||
self.check_resp_headers_in_get(resp_2)
|
||||
self.check_resp_body(body_2, expected_inst_attrs)
|
||||
new_vnfd_id = [obj['metadata']['current_vnfd_id'] for obj in body_2[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo']][0]
|
||||
|
||||
self.assertNotEqual(old_vnfd_id, new_vnfd_id)
|
||||
|
||||
terminate_req = paramgen.terminate_vnf_min()
|
||||
resp, body = self.terminate_vnf_instance(inst_id, terminate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# wait a bit because there is a bit time lag between lcmocc DB
|
||||
# update and terminate completion.
|
||||
time.sleep(10)
|
||||
|
||||
resp, body = self.delete_vnf_instance(inst_id)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
self.check_resp_headers_in_delete(resp)
|
||||
|
||||
def test_change_vnfpkg_from_image_to_volume(self):
|
||||
self.change_vnfpkg_from_image_to_volume_common_test()
|
||||
|
||||
def test_change_vnfpkg_from_volume_to_image(self):
|
||||
create_req = paramgen.change_vnfpkg_create(self.vnfd_id_1)
|
||||
resp, body = self.create_vnf_instance(create_req)
|
||||
expected_inst_attrs = [
|
||||
'id',
|
||||
'vnfInstanceName',
|
||||
'vnfInstanceDescription',
|
||||
'vnfdId',
|
||||
'vnfProvider',
|
||||
'vnfProductName',
|
||||
'vnfSoftwareVersion',
|
||||
'vnfdVersion',
|
||||
# 'vnfConfigurableProperties', # omitted
|
||||
# 'vimConnectionInfo', # omitted
|
||||
'instantiationState',
|
||||
# 'instantiatedVnfInfo', # omitted
|
||||
'metadata',
|
||||
# 'extensions', # omitted
|
||||
'_links'
|
||||
]
|
||||
self.assertEqual(201, resp.status_code)
|
||||
self.check_resp_headers_in_create(resp)
|
||||
self.check_resp_body(body, expected_inst_attrs)
|
||||
inst_id = body['id']
|
||||
|
||||
net_ids = self.get_network_ids(['net0', 'net1', 'net_mgmt'])
|
||||
subnet_ids = self.get_subnet_ids(['subnet0', 'subnet1'])
|
||||
instantiate_req = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, self.auth_url, flavor_id='volume')
|
||||
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
additional_inst_attrs = [
|
||||
'vimConnectionInfo',
|
||||
'instantiatedVnfInfo'
|
||||
]
|
||||
expected_inst_attrs.extend(additional_inst_attrs)
|
||||
resp_1, body_1 = self.show_vnf_instance(inst_id)
|
||||
stack_name = "vnf-{}".format(inst_id)
|
||||
stack_id = self.heat_client.get_stack_resource(stack_name)['stack'][
|
||||
'id']
|
||||
image_id_1 = self.get_current_vdu_image(stack_id, stack_name, 'VDU2')
|
||||
storageResourceIds_1 = [
|
||||
obj.get('storageResourceIds') for obj in body_1[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo']
|
||||
if obj['vduId'] == 'VDU2']
|
||||
resource_ids_1 = [obj['id'] for obj in body_1[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo'] if obj[
|
||||
'vduId'] == 'VDU2'][0]
|
||||
self.assertIsNotNone(storageResourceIds_1)
|
||||
|
||||
self.assertEqual(200, resp_1.status_code)
|
||||
self.check_resp_headers_in_get(resp_1)
|
||||
self.check_resp_body(body_1, expected_inst_attrs)
|
||||
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(self.vnfd_id_2)
|
||||
del change_vnfpkg_req['additionalParams']['vdu_params'][0]
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
resp_2, body_2 = self.show_vnf_instance(inst_id)
|
||||
image_id_2 = self.get_current_vdu_image(stack_id, stack_name, 'VDU2')
|
||||
storageResourceIds_2 = [
|
||||
obj.get('storageResourceIds') for obj in body_2[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo']
|
||||
if obj['vduId'] == 'VDU2']
|
||||
resource_ids_2 = [obj['id'] for obj in body_2[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo'] if obj[
|
||||
'vduId'] == 'VDU2'][0]
|
||||
self.assertIsNone(storageResourceIds_2[0])
|
||||
self.assertNotEqual(image_id_1, image_id_2)
|
||||
self.assertNotEqual(resource_ids_1, resource_ids_2)
|
||||
|
||||
self.assertEqual(200, resp_2.status_code)
|
||||
self.check_resp_headers_in_get(resp_2)
|
||||
self.check_resp_body(body_2, expected_inst_attrs)
|
||||
|
||||
terminate_req = paramgen.terminate_vnf_min()
|
||||
resp, body = self.terminate_vnf_instance(inst_id, terminate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# wait a bit because there is a bit time lag between lcmocc DB
|
||||
# update and terminate completion.
|
||||
time.sleep(10)
|
||||
|
||||
resp, body = self.delete_vnf_instance(inst_id)
|
||||
self.assertEqual(204, resp.status_code)
|
||||
self.check_resp_headers_in_delete(resp)
|
||||
self.change_vnfpkg_from_image_to_image_common_test()
|
||||
|
||||
def test_change_vnfpkg_from_volume_to_volume(self):
|
||||
create_req = paramgen.change_vnfpkg_create(self.vnfd_id_1)
|
||||
|
@ -425,10 +236,7 @@ class ChangeVnfPkgVnfLcmTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
|||
self.wait_lcmocc_rolled_back(lcmocc_id)
|
||||
|
||||
resp_2, body_2 = self.show_vnf_instance(inst_id)
|
||||
new_vnfd_id = [
|
||||
obj['metadata'].get('current_vnfd_id') for obj in body_2[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo']
|
||||
if obj['metadata'].get('current_vnfd_id')][0]
|
||||
new_vnfd_id = body_2['vnfdId']
|
||||
self.assertEqual(old_vnfd_id, new_vnfd_id)
|
||||
|
||||
self.assertEqual(200, resp_2.status_code)
|
||||
|
@ -509,9 +317,6 @@ class ChangeVnfPkgVnfLcmTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
|||
change_vnfpkg_req['additionalParams'][
|
||||
'lcm-operation-coordinate-new-vnf'
|
||||
] = "./Scripts/error_coordinate_new_vnf.py"
|
||||
change_vnfpkg_req['additionalParams'][
|
||||
'lcm-operation-coordinate-new-vnf-class'
|
||||
] = "ErrorCoordinateNewVnf"
|
||||
del change_vnfpkg_req['additionalParams']['vdu_params'][0]
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
|
|
@ -331,14 +331,17 @@ class BaseSolV2Test(base.BaseTestCase):
|
|||
)
|
||||
glance_client = glance_utils.GlanceClient(vim)
|
||||
if num_vdu == 1:
|
||||
vdu = 'VDU2' if 'VDU2' in sw_data else 'VDU2-VirtualStorage'
|
||||
image = glance_client.create_image(
|
||||
sw_data['VDU2-VirtualStorage']['name'], **create_args)
|
||||
sw_data[vdu]['name'], **create_args)
|
||||
return image.id
|
||||
|
||||
vdu = 'VDU1' if 'VDU1' in sw_data else 'VDU1-VirtualStorage'
|
||||
image_1 = glance_client.create_image(
|
||||
sw_data['VDU1-VirtualStorage']['name'], **create_args)
|
||||
sw_data[vdu]['name'], **create_args)
|
||||
vdu = 'VDU2' if 'VDU2' in sw_data else 'VDU2-VirtualStorage'
|
||||
image_2 = glance_client.create_image(
|
||||
sw_data['VDU2-VirtualStorage']['name'], **create_args)
|
||||
sw_data[vdu]['name'], **create_args)
|
||||
return image_1.id, image_2.id
|
||||
|
||||
def glance_delete_image(self, vim_info, image_ids):
|
||||
|
|
|
@ -904,10 +904,8 @@ def change_vnfpkg(vnfd_id):
|
|||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf":
|
||||
"./Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf":
|
||||
"./Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [{
|
||||
"vdu_id": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1-VirtualStorage:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
|
@ -49,7 +49,7 @@ resources:
|
|||
VDU1-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1-VirtualStorage }
|
||||
size: 1
|
||||
volume_type: { get_param: volume_type }
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
image-VDU1-VirtualStorage: { get_param: [ nfv, VDU, VDU1-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 ] }
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net5:
|
||||
type: string
|
||||
|
@ -16,7 +16,7 @@ resources:
|
|||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
name: VDU1
|
||||
networks:
|
||||
- port:
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net5: { get_resource: internalVL3 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net5:
|
||||
type: string
|
||||
|
@ -16,7 +16,7 @@ resources:
|
|||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
name: VDU1
|
||||
networks:
|
||||
- port:
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net5: { get_resource: internalVL3 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1-VirtualStorage:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
|
@ -47,7 +47,7 @@ resources:
|
|||
VDU1-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1-VirtualStorage }
|
||||
size: 1
|
||||
volume_type: { get_resource: VDU1-VolumeType }
|
||||
VDU1-VolumeType:
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
image-VDU1-VirtualStorage: { get_param: [ nfv, VDU, VDU1-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 ] }
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
|
||||
VDU2:
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -15,7 +15,7 @@ resources:
|
|||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId] }
|
||||
image-VDU1-VirtualStorage: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
volume_type: { get_resource: VDU1-VolumeType }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1-VirtualStorage:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -30,6 +30,6 @@ resources:
|
|||
VDU1-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1-VirtualStorage }
|
||||
size: 4
|
||||
volume_type: { get_param: volume_type }
|
||||
|
|
|
@ -20,9 +20,7 @@ import time
|
|||
from oslo_log import log as logging
|
||||
import paramiko
|
||||
|
||||
from tacker.sol_refactored.common import common_script_utils
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CMD_TIMEOUT = 30
|
||||
|
@ -32,13 +30,8 @@ SSH_CONNECT_RETRY_COUNT = 4
|
|||
|
||||
class SampleNewCoordinateVNFScript(object):
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir, vdu_info):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
self.vdu_info = vdu_info
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def coordinate_vnf(self):
|
||||
# check ssh connect and os version
|
||||
|
@ -48,11 +41,9 @@ class SampleNewCoordinateVNFScript(object):
|
|||
Since the zuul's network cannot check this content, so
|
||||
we comment this part of code. If you want to check them
|
||||
in your local environment, please uncomment.
|
||||
# user = self.vdu_info.get('vdu_param').get(
|
||||
# 'new_vnfc_param').get('username')
|
||||
# password = self.vdu_info.get('vdu_param').get(
|
||||
# 'new_vnfc_param').get('password')
|
||||
# host = self.vdu_info.get("ssh_ip")
|
||||
# user = self.vnfc_param['username']
|
||||
# password = self.vnfc_param['password']
|
||||
# host = self.vnfc_param['ssh_ip']
|
||||
# commander = self._init_commander(
|
||||
# user, password, host, retry=SSH_CONNECT_RETRY_COUNT)
|
||||
# ssh_command = 'cat /etc/os-release | grep PRETTY_NAME'
|
||||
|
@ -60,20 +51,7 @@ class SampleNewCoordinateVNFScript(object):
|
|||
# os_version = result[0].replace('\n', '').split('=')[1]
|
||||
# LOG.info('The os version of this new VM is %s', os_version)
|
||||
"""
|
||||
# check image and flavour updated successfully
|
||||
vnfd = vnfd_utils.Vnfd(self.req.get('vnfdId'))
|
||||
vnfd.init_from_csar_dir(self.csar_dir)
|
||||
vdu_infos = common_script_utils.get_vdu_info(
|
||||
self.grant, self.inst, vnfd)
|
||||
|
||||
vdu_id = self.vdu_info.get('vdu_param').get('vdu_id')
|
||||
image = vdu_infos.get(vdu_id, {}).get('image')
|
||||
flavor = vdu_infos.get(vdu_id, {}).get('flavor')
|
||||
if self.vdu_info.get('new_image') != image or self.vdu_info.get(
|
||||
'new_flavor') != flavor:
|
||||
error = "The VM's image or flavour update failed'"
|
||||
LOG.error(error)
|
||||
raise sol_ex.VMRunningFailed(error)
|
||||
pass
|
||||
|
||||
def _init_commander(self, user, password, host, retry):
|
||||
while retry > 0:
|
||||
|
@ -119,16 +97,8 @@ class SampleNewCoordinateVNFScript(object):
|
|||
|
||||
def main():
|
||||
operation = "coordinate_vnf"
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
vdu_info = script_dict['vdu_info']
|
||||
script = SampleNewCoordinateVNFScript(
|
||||
req, inst, grant_req, grant,
|
||||
csar_dir, vdu_info)
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = SampleNewCoordinateVNFScript(vnfc_param)
|
||||
try:
|
||||
getattr(script, operation)()
|
||||
except Exception:
|
||||
|
|
|
@ -42,10 +42,3 @@ change_vnfpkg_req_from_image_to_image = paramgen.change_vnfpkg(vnfd_id)
|
|||
|
||||
with open("change_vnfpkg_req_from_image_to_image", "w", encoding='utf-8') as f:
|
||||
f.write(json.dumps(change_vnfpkg_req_from_image_to_image, indent=2))
|
||||
|
||||
# if your sample is change VM from volume to image
|
||||
change_vnfpkg_req_from_volume_to_image = paramgen.change_vnfpkg(vnfd_id)
|
||||
del change_vnfpkg_req_from_volume_to_image['additionalParams']['vdu_params'][0]
|
||||
|
||||
with open("change_vnfpkg_req_from_volume", "w", encoding='utf-8') as f:
|
||||
f.write(json.dumps(change_vnfpkg_req_from_volume_to_image, indent=2))
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
|
||||
VDU2:
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -15,7 +15,7 @@ resources:
|
|||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
image-VDU1-VirtualStorage: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
volume_type: { get_resource: VDU1-VolumeType }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1-VirtualStorage:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -30,6 +30,6 @@ resources:
|
|||
VDU1-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1-VirtualStorage }
|
||||
size: 4
|
||||
volume_type: { get_param: volume_type }
|
||||
|
|
|
@ -20,9 +20,7 @@ import time
|
|||
from oslo_log import log as logging
|
||||
import paramiko
|
||||
|
||||
from tacker.sol_refactored.common import common_script_utils
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CMD_TIMEOUT = 30
|
||||
|
@ -32,13 +30,8 @@ SSH_CONNECT_RETRY_COUNT = 4
|
|||
|
||||
class SampleNewCoordinateVNFScript(object):
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir, vdu_info):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
self.vdu_info = vdu_info
|
||||
def __init__(self, vnfc_param):
|
||||
self.req = vnfc_param
|
||||
|
||||
def coordinate_vnf(self):
|
||||
# check ssh connect and os version
|
||||
|
@ -48,11 +41,9 @@ class SampleNewCoordinateVNFScript(object):
|
|||
Since the zuul's network cannot check this content, so
|
||||
we comment this part of code. If you want to check them
|
||||
in your local environment, please uncomment.
|
||||
user = self.vdu_info.get('vdu_param').get(
|
||||
'new_vnfc_param').get('username')
|
||||
password = self.vdu_info.get('vdu_param').get(
|
||||
'new_vnfc_param').get('password')
|
||||
host = self.vdu_info.get("ssh_ip")
|
||||
user = self.vnfc_param['username']
|
||||
password = self.vnfc_param['password']
|
||||
host = self.vnfc_param['ssh_ip']
|
||||
commander = self._init_commander(
|
||||
user, password, host, retry=SSH_CONNECT_RETRY_COUNT)
|
||||
ssh_command = 'cat /etc/os-release | grep PRETTY_NAME'
|
||||
|
@ -60,20 +51,7 @@ class SampleNewCoordinateVNFScript(object):
|
|||
os_version = result[0].replace('\n', '').split('=')[1]
|
||||
LOG.info('The os version of this new VM is %s', os_version)
|
||||
"""
|
||||
# check image and flavour updated successfully
|
||||
vnfd = vnfd_utils.Vnfd(self.req.get('vnfdId'))
|
||||
vnfd.init_from_csar_dir(self.csar_dir)
|
||||
vdu_infos = common_script_utils.get_vdu_info(
|
||||
self.grant, self.inst, vnfd)
|
||||
|
||||
vdu_id = self.vdu_info.get('vdu_param').get('vdu_id')
|
||||
image = vdu_infos.get(vdu_id, {}).get('image')
|
||||
flavor = vdu_infos.get(vdu_id, {}).get('flavor')
|
||||
if self.vdu_info.get('new_image') != image or self.vdu_info.get(
|
||||
'new_flavor') != flavor:
|
||||
error = "The VM's image or flavour update failed'"
|
||||
LOG.error(error)
|
||||
raise sol_ex.VMRunningFailed(error)
|
||||
pass
|
||||
|
||||
def _init_commander(self, user, password, host, retry):
|
||||
while retry > 0:
|
||||
|
@ -119,16 +97,8 @@ class SampleNewCoordinateVNFScript(object):
|
|||
|
||||
def main():
|
||||
operation = "coordinate_vnf"
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
vdu_info = script_dict['vdu_info']
|
||||
script = SampleNewCoordinateVNFScript(
|
||||
req, inst, grant_req, grant,
|
||||
csar_dir, vdu_info)
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = SampleNewCoordinateVNFScript(vnfc_param)
|
||||
try:
|
||||
getattr(script, operation)()
|
||||
except Exception:
|
||||
|
|
|
@ -27,13 +27,8 @@ SSH_CONNECT_RETRY_COUNT = 4
|
|||
|
||||
class SampleErrorNewCoordinateVNFScript(object):
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir, vdu_info):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
self.vdu_info = vdu_info
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def coordinate_vnf(self):
|
||||
raise Exception("ErrorNewCoordinateVNFScript")
|
||||
|
@ -41,16 +36,8 @@ class SampleErrorNewCoordinateVNFScript(object):
|
|||
|
||||
def main():
|
||||
operation = "coordinate_vnf"
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
vdu_info = script_dict['vdu_info']
|
||||
script = SampleErrorNewCoordinateVNFScript(
|
||||
req, inst, grant_req, grant,
|
||||
csar_dir, vdu_info)
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = SampleErrorNewCoordinateVNFScript(vnfc_param)
|
||||
try:
|
||||
getattr(script, operation)()
|
||||
except Exception:
|
||||
|
|
|
@ -37,18 +37,16 @@ utils.make_zip(".", tmp_dir, vnfd_id, image_path)
|
|||
shutil.move(os.path.join(tmp_dir, zip_file_name), ".")
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
# if your sample is change VM from image to volume
|
||||
change_vnfpkg_req_from_image_to_volume = paramgen.change_vnfpkg(vnfd_id)
|
||||
del change_vnfpkg_req_from_image_to_volume['additionalParams']['vdu_params'][0]
|
||||
|
||||
with open("change_vnfpkg_req_from_image_to_volume", "w",
|
||||
encoding='utf-8') as f:
|
||||
f.write(json.dumps(change_vnfpkg_req_from_image_to_volume, indent=2))
|
||||
|
||||
# if your sample is change VM from volume to volume
|
||||
change_vnfpkg_req_from_volume_to_volume = paramgen.change_vnfpkg(vnfd_id)
|
||||
del change_vnfpkg_req_from_volume_to_volume[
|
||||
'additionalParams']['vdu_params'][0]
|
||||
|
||||
with open("change_vnfpkg_req_from_volume", "w", encoding='utf-8') as f:
|
||||
f.write(json.dumps(change_vnfpkg_req_from_volume_to_volume, indent=2))
|
||||
|
||||
change_vnfpkg_req_error_coodinate_vnf = paramgen.change_vnfpkg(vnfd_id)
|
||||
change_vnfpkg_req_error_coodinate_vnf['additionalParams'][
|
||||
'lcm-operation-coordinate-new-vnf'
|
||||
] = "./Scripts/error_coordinate_new_vnf.py"
|
||||
|
||||
with open("change_vnfpkg_req_error_coodinate_vnf", "w", encoding='utf-8') as f:
|
||||
f.write(json.dumps(change_vnfpkg_req_error_coodinate_vnf, indent=2))
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
|
||||
VDU2:
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -15,7 +15,7 @@ resources:
|
|||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
|
|
|
@ -20,9 +20,7 @@ import time
|
|||
from oslo_log import log as logging
|
||||
import paramiko
|
||||
|
||||
from tacker.sol_refactored.common import common_script_utils
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CMD_TIMEOUT = 30
|
||||
|
@ -32,13 +30,8 @@ SSH_CONNECT_RETRY_COUNT = 4
|
|||
|
||||
class SampleNewCoordinateVNFScript(object):
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir, vdu_info):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
self.vdu_info = vdu_info
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def coordinate_vnf(self):
|
||||
# check ssh connect and os version
|
||||
|
@ -48,11 +41,9 @@ class SampleNewCoordinateVNFScript(object):
|
|||
Since the zuul's network cannot check this content, so
|
||||
we comment this part of code. If you want to check them
|
||||
in your local environment, please uncomment.
|
||||
# user = self.vdu_info.get('vdu_param').get(
|
||||
# 'new_vnfc_param').get('username')
|
||||
# password = self.vdu_info.get('vdu_param').get(
|
||||
# 'new_vnfc_param').get('password')
|
||||
# host = self.vdu_info.get("ssh_ip"),
|
||||
# user = self.vnfc_param['username']
|
||||
# password = self.vnfc_param['password']
|
||||
# host = self.vnfc_param['ssh_ip']
|
||||
# commander = self._init_commander(
|
||||
# user, password, host, retry=SSH_CONNECT_RETRY_COUNT)
|
||||
# ssh_command = 'cat /etc/os-release | grep PRETTY_NAME'
|
||||
|
@ -60,20 +51,7 @@ class SampleNewCoordinateVNFScript(object):
|
|||
# os_version = result.get_stdout()[0].replace('\n', '').split('=')
|
||||
# LOG.info('The os version of this new VM is %s', os_version)
|
||||
"""
|
||||
# check image and flavour updated successfully
|
||||
vnfd = vnfd_utils.Vnfd(self.req.get('vnfdId'))
|
||||
vnfd.init_from_csar_dir(self.csar_dir)
|
||||
vdu_infos = common_script_utils.get_vdu_info(
|
||||
self.grant, self.inst, vnfd)
|
||||
|
||||
vdu_id = self.vdu_info.get('vdu_param').get('vdu_id')
|
||||
image = vdu_infos.get(vdu_id, {}).get('image')
|
||||
flavor = vdu_infos.get(vdu_id, {}).get('flavor')
|
||||
if self.vdu_info.get('new_image') != image or self.vdu_info.get(
|
||||
'new_flavor') != flavor:
|
||||
error = "The VM's image or flavour update failed'"
|
||||
LOG.error(error)
|
||||
raise sol_ex.VMRunningFailed(error)
|
||||
pass
|
||||
|
||||
def _init_commander(self, user, password, host, retry):
|
||||
while retry > 0:
|
||||
|
@ -119,16 +97,8 @@ class SampleNewCoordinateVNFScript(object):
|
|||
|
||||
def main():
|
||||
operation = "coordinate_vnf"
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
vdu_info = script_dict['vdu_info']
|
||||
script = SampleNewCoordinateVNFScript(
|
||||
req, inst, grant_req, grant,
|
||||
csar_dir, vdu_info)
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = SampleNewCoordinateVNFScript(vnfc_param)
|
||||
try:
|
||||
getattr(script, operation)()
|
||||
except Exception:
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
|
||||
VDU2:
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -15,7 +15,7 @@ resources:
|
|||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: base_hot_nested_VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
image-VDU1-VirtualStorage: { get_param: [ nfv, VDU, VDU1-VirtualStorage, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network] }
|
||||
volume_type: { get_resource: VDU1-VolumeType }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1-VirtualStorage:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
|
@ -30,6 +30,6 @@ resources:
|
|||
VDU1-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1-VirtualStorage }
|
||||
size: 4
|
||||
volume_type: { get_param: volume_type }
|
||||
|
|
|
@ -20,9 +20,7 @@ import time
|
|||
from oslo_log import log as logging
|
||||
import paramiko
|
||||
|
||||
from tacker.sol_refactored.common import common_script_utils
|
||||
from tacker.sol_refactored.common import exceptions as sol_ex
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CMD_TIMEOUT = 30
|
||||
|
@ -32,13 +30,8 @@ SSH_CONNECT_RETRY_COUNT = 4
|
|||
|
||||
class SampleOldCoordinateVNFScript(object):
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir, vdu_info):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
self.vdu_info = vdu_info
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def coordinate_vnf(self):
|
||||
# check ssh connect and os version
|
||||
|
@ -48,11 +41,9 @@ class SampleOldCoordinateVNFScript(object):
|
|||
Since the zuul's network cannot check this content, so
|
||||
we comment this part of code. If you want to check them
|
||||
in your local environment, please uncomment.
|
||||
# user = self.vdu_info.get('vdu_param').get(
|
||||
# 'old_vnfc_param').get('username')
|
||||
# password = self.vdu_info.get('vdu_param').get(
|
||||
# 'old_vnfc_param').get('password')
|
||||
# host = self.vdu_info.get("ssh_ip"),
|
||||
# user = self.vnfc_param['username']
|
||||
# password = self.vnfc_param['password']
|
||||
# host = self.vnfc_param['ssh_ip']
|
||||
# commander = self._init_commander(
|
||||
# user, password, host, retry=SSH_CONNECT_RETRY_COUNT)
|
||||
# ssh_command = 'cat /etc/os-release | grep PRETTY_NAME'
|
||||
|
@ -60,20 +51,7 @@ class SampleOldCoordinateVNFScript(object):
|
|||
# os_version = result.get_stdout()[0].replace('\n', '').split('=')
|
||||
# LOG.info('The os version of this new VM is %s', os_version)
|
||||
"""
|
||||
# check image and flavour updated successfully
|
||||
vnfd = vnfd_utils.Vnfd(self.req.get('vnfdId'))
|
||||
vnfd.init_from_csar_dir(self.csar_dir)
|
||||
vdu_infos = common_script_utils.get_vdu_info(
|
||||
self.grant, self.inst, vnfd)
|
||||
|
||||
vdu_id = self.vdu_info.get('vdu_param').get('vdu_id')
|
||||
image = vdu_infos.get(vdu_id, {}).get('image')
|
||||
flavor = vdu_infos.get(vdu_id, {}).get('flavor')
|
||||
if self.vdu_info.get('new_image') != image or self.vdu_info.get(
|
||||
'new_flavor') != flavor:
|
||||
error = "The VM's image or flavour update failed'"
|
||||
LOG.error(error)
|
||||
raise sol_ex.VMRunningFailed(error)
|
||||
pass
|
||||
|
||||
def _init_commander(self, user, password, host, retry):
|
||||
while retry > 0:
|
||||
|
@ -119,16 +97,8 @@ class SampleOldCoordinateVNFScript(object):
|
|||
|
||||
def main():
|
||||
operation = "coordinate_vnf"
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
vdu_info = script_dict['vdu_info']
|
||||
script = SampleOldCoordinateVNFScript(
|
||||
req, inst, grant_req, grant,
|
||||
csar_dir, vdu_info)
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = SampleOldCoordinateVNFScript(vnfc_param)
|
||||
try:
|
||||
getattr(script, operation)()
|
||||
except Exception:
|
||||
|
|
|
@ -47,14 +47,6 @@ subnet_ids = utils.get_subnet_ids(['subnet0'])
|
|||
instantiate_req_from_image_to_image = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, "http://localhost/identity/v3")
|
||||
|
||||
# if your sample is change VM from volume to image
|
||||
instantiate_req_from_volume_to_image = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, "http://localhost/identity/v3", flavor_id='volume')
|
||||
|
||||
# if your sample is change VM from image to volume
|
||||
instantiate_req_from_image_to_volume = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, "http://localhost/identity/v3")
|
||||
|
||||
# if your sample is change VM from volume to volume
|
||||
instantiate_req_from_volume_to_volume = paramgen.change_vnfpkg_instantiate(
|
||||
net_ids, subnet_ids, "http://localhost/identity/v3", flavor_id='volume')
|
||||
|
@ -72,12 +64,6 @@ with open("terminate_req", "w") as f:
|
|||
with open("instantiate_req_from_image_to_image", "w") as f:
|
||||
f.write(json.dumps(instantiate_req_from_image_to_image, indent=2))
|
||||
|
||||
with open("instantiate_req_from_volume_to_image", "w") as f:
|
||||
f.write(json.dumps(instantiate_req_from_volume_to_image, indent=2))
|
||||
|
||||
with open("instantiate_req_from_image_to_volume", "w") as f:
|
||||
f.write(json.dumps(instantiate_req_from_image_to_volume, indent=2))
|
||||
|
||||
with open("instantiate_req_from_volume_to_volume", "w") as f:
|
||||
f.write(json.dumps(instantiate_req_from_volume_to_volume, indent=2))
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ description: 'VDU1 HOT for Sample VNF'
|
|||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image:
|
||||
image-VDU1:
|
||||
type: string
|
||||
net5:
|
||||
type: string
|
||||
|
@ -16,7 +16,7 @@ resources:
|
|||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
image: { get_param: image }
|
||||
image: { get_param: image-VDU1 }
|
||||
name: VDU1
|
||||
networks:
|
||||
- port:
|
||||
|
|
|
@ -16,7 +16,7 @@ resources:
|
|||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net5: { get_resource: internalVL3 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
response_headers={"Content-Type": "application/json"},
|
||||
callback=lambda req_headers, req_body:
|
||||
fake_grant_v2.GrantV2.make_change_vnfpkg_response_body(
|
||||
req_body))
|
||||
req_body, glance_image, flavour_vdu_dict))
|
||||
else:
|
||||
raise Exception
|
||||
|
||||
|
@ -1612,8 +1612,8 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
resp, body = self.show_subscription(sub_id)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def change_vnfpkg_from_image_to_volume_common_test(self, is_nfvo=False):
|
||||
"""Test ChangeCurrentVNFPackage from image to volume
|
||||
def change_vnfpkg_from_image_to_image_common_test(self, is_nfvo=False):
|
||||
"""Test ChangeCurrentVNFPackage from image to image
|
||||
|
||||
* About attributes:
|
||||
All of the following cardinality attributes are set.
|
||||
|
@ -1641,15 +1641,15 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
"samples/test_instantiate_vnf_with_old_image_or_volume")
|
||||
zip_file_path_1, vnfd_id_1 = self.create_vnf_package(
|
||||
change_vnfpkg_from_image_to_image_path, nfvo=True)
|
||||
change_vnfpkg_from_image_to_volume_path = os.path.join(
|
||||
cur_dir, "samples/test_change_vnf_pkg_with_new_volume")
|
||||
change_vnfpkg_from_image_to_image_path_2 = os.path.join(
|
||||
cur_dir, "samples/test_change_vnf_pkg_with_new_image")
|
||||
image_dir = os.path.join(
|
||||
cur_dir, "../../etc/samples/etsi/nfv/common/Files/images")
|
||||
image_file = "cirros-0.5.2-x86_64-disk.img"
|
||||
image_path = os.path.abspath(os.path.join(image_dir, image_file))
|
||||
zip_file_path_3, vnfd_id_3 = self.create_vnf_package(
|
||||
change_vnfpkg_from_image_to_volume_path, image_path=image_path,
|
||||
nfvo=True)
|
||||
zip_file_path_2, vnfd_id_2 = self.create_vnf_package(
|
||||
change_vnfpkg_from_image_to_image_path_2,
|
||||
image_path=image_path, nfvo=True)
|
||||
package_dir = os.path.join(
|
||||
cur_dir,
|
||||
"samples/test_instantiate_vnf_with_old_image_or_volume")
|
||||
|
@ -1657,10 +1657,10 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
"contents/Definitions/change_vnf_pkg_old_image_df_simple.yaml")
|
||||
|
||||
change_package_dir = os.path.join(
|
||||
cur_dir, "samples/test_change_vnf_pkg_with_new_volume")
|
||||
cur_dir, "samples/test_change_vnf_pkg_with_new_image")
|
||||
change_vnfd_path = (
|
||||
"contents/Definitions/"
|
||||
"change_vnf_pkg_new_volume_df_simple.yaml")
|
||||
"change_vnf_pkg_new_image_df_simple.yaml")
|
||||
sw_data = fake_grant_v2.GrantV2.get_sw_data(
|
||||
change_package_dir, change_vnfd_path)
|
||||
glance_image = fake_grant_v2.GrantV2.get_sw_image(
|
||||
|
@ -1671,13 +1671,13 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
self._register_vnf_package_mock_response(
|
||||
vnfd_id_1, zip_file_path_1)
|
||||
create_req = paramgen.change_vnfpkg_create(vnfd_id_1)
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(vnfd_id_3)
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(vnfd_id_2)
|
||||
else:
|
||||
glance_image = None
|
||||
flavour_vdu_dict = None
|
||||
zone_name_list = None
|
||||
create_req = paramgen.change_vnfpkg_create(self.vnfd_id_1)
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(self.vnfd_id_3)
|
||||
change_vnfpkg_req = paramgen.change_vnfpkg(self.vnfd_id_2)
|
||||
|
||||
# 1. Create VNF instance
|
||||
resp, body = self.create_vnf_instance(create_req)
|
||||
|
@ -1734,19 +1734,18 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
self.assertEqual(200, resp_1.status_code)
|
||||
self.check_resp_headers_in_get(resp_1)
|
||||
self.check_resp_body(body_1, expected_inst_attrs)
|
||||
resource_ids_1 = [obj['id'] for obj in body_1[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo'] if obj[
|
||||
'vduId'] == 'VDU2'][0]
|
||||
|
||||
# 4. Change Current VNF Package
|
||||
if is_nfvo:
|
||||
self._register_vnf_package_mock_response(
|
||||
vnfd_id_3, zip_file_path_3)
|
||||
image_id = self.glance_create_image(
|
||||
vnfd_id_2, zip_file_path_2)
|
||||
g_image_id_1, g_image_id_2 = self.glance_create_image(
|
||||
instantiate_req.get("vimConnectionInfo").get("vim1"),
|
||||
image_path, sw_data, inst_id)
|
||||
self._set_grant_response(is_nfvo, 'CHANGE_VNFPKG')
|
||||
del change_vnfpkg_req['additionalParams']['vdu_params'][0]
|
||||
image_path, sw_data, inst_id, num_vdu=2)
|
||||
glance_image['VDU1'] = g_image_id_1
|
||||
glance_image['VDU2'] = g_image_id_2
|
||||
self._set_grant_response(is_nfvo, 'CHANGE_VNFPKG',
|
||||
glance_image=glance_image, flavour_vdu_dict=flavour_vdu_dict)
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
@ -1757,15 +1756,6 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
# 5. Show VNF instance
|
||||
resp_2, body_2 = self.show_vnf_instance(inst_id)
|
||||
image_id_2 = self.get_current_vdu_image(stack_id, stack_name, 'VDU2')
|
||||
storage_resource_ids = [obj.get('storageResourceIds')
|
||||
for obj in body_2['instantiatedVnfInfo'][
|
||||
'vnfcResourceInfo'] if obj[
|
||||
'vduId'] == 'VDU2']
|
||||
self.assertIsNotNone(storage_resource_ids)
|
||||
resource_ids_2 = [obj['id'] for obj in body_2[
|
||||
'instantiatedVnfInfo']['vnfcResourceInfo'] if obj[
|
||||
'vduId'] == 'VDU2'][0]
|
||||
self.assertNotEqual(resource_ids_1, resource_ids_2)
|
||||
self.assertNotEqual(image_id_1, image_id_2)
|
||||
|
||||
self.assertEqual(200, resp_2.status_code)
|
||||
|
@ -1794,7 +1784,7 @@ class CommonVnfLcmTest(base_v2.BaseSolV2Test):
|
|||
if is_nfvo:
|
||||
self.glance_delete_image(
|
||||
instantiate_req.get("vimConnectionInfo").get("vim1"),
|
||||
[image_id])
|
||||
[g_image_id_1, g_image_id_2])
|
||||
|
||||
def retry_rollback_scale_out_common_test(self, is_nfvo=False):
|
||||
"""Test retry and rollback scale out operations
|
||||
|
|
|
@ -256,7 +256,10 @@ _inst_info_example_1 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_1"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -293,7 +296,10 @@ _inst_info_example_1 = {
|
|||
"vnfLinkPortId": "res_id_VDU2_CP5"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU2": "image-VDU2"
|
||||
# other attributes omitted
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo": [
|
||||
|
@ -532,7 +538,10 @@ _inst_info_example_2 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_2"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_1",
|
||||
|
@ -572,7 +581,10 @@ _inst_info_example_2 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_1"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -609,7 +621,10 @@ _inst_info_example_2 = {
|
|||
"vnfLinkPortId": "res_id_VDU2_CP5"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU2": "image-VDU2"
|
||||
# other attributes omitted
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo": [
|
||||
|
@ -905,14 +920,14 @@ _inst_info_example_3 = {
|
|||
|
||||
# example_4 is for update_lcmocc test in case of heal. based on example_2.
|
||||
# * VDU1_1: update server only. VDU1_2: update both server and volume.
|
||||
# * ports of extMangagedVirtualLink are re-created.
|
||||
# * ports of extManagedVirtualLink are re-created.
|
||||
# NOTE: combination of the above sentences can not be happened really.
|
||||
# it is the data for unit test.
|
||||
_inst_info_example_4 = {
|
||||
# "flavourId", "vnfState", "scaleStatus", "maxScaleLevels" are omitted
|
||||
# "extCpInfo": omitted
|
||||
"extVirtualLinkInfo": _inst_info_example_2["extVirtualLinkInfo"],
|
||||
# network resource is not changed but ports are re-receated.
|
||||
# network resource is not changed but ports are re-created.
|
||||
# this is for check of SOL003 all=True case.
|
||||
|
||||
"extManagedVirtualLinkInfo": [
|
||||
|
@ -995,7 +1010,10 @@ _inst_info_example_4 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_2_new"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_1_new",
|
||||
|
@ -1035,7 +1053,10 @@ _inst_info_example_4 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_1_new"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -1072,7 +1093,10 @@ _inst_info_example_4 = {
|
|||
"vnfLinkPortId": "res_id_VDU2_CP5"
|
||||
}
|
||||
],
|
||||
# "metadata": omitted
|
||||
"metadata": {
|
||||
"image-VDU2": "image-VDU2"
|
||||
# other attributes omitted
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo":
|
||||
|
@ -1104,93 +1128,9 @@ _inst_info_example_4 = {
|
|||
_inst_info_example_5 = {
|
||||
# "flavourId", "vnfState", "scaleStatus", "maxScaleLevels" are omitted
|
||||
# "extCpInfo": omitted
|
||||
"extVirtualLinkInfo": [
|
||||
{
|
||||
"id": "bbf0932a-6142-4ea8-93cd-8059dba594a1",
|
||||
"resourceHandle": {
|
||||
"resourceId": "3529d333-dbcc-4d93-9b64-210647712569"
|
||||
},
|
||||
"extLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU2_CP1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU2_CP1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU2_CP1"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP1_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU1_CP1_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU1_CP1_1"
|
||||
}
|
||||
],
|
||||
# "currentVnfExtCpData": omitted
|
||||
},
|
||||
{
|
||||
"id": "790949df-c7b3-4926-a559-3895412f1dfe",
|
||||
"resourceHandle": {
|
||||
"resourceId": "367e5b3b-34dc-47f2-85b8-c39e3272893a"
|
||||
},
|
||||
"extLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU2_CP2",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU2_CP2",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU2_CP2"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP2_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU1_CP2_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU1_CP2_1"
|
||||
}
|
||||
],
|
||||
# "currentVnfExtCpData": omitted
|
||||
}
|
||||
],
|
||||
"extManagedVirtualLinkInfo": [
|
||||
{
|
||||
"id": "res_id_internalVL1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"networkResource": {
|
||||
"resourceId": "res_id_internalVL1"
|
||||
},
|
||||
"vnfLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU2_CP3",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU2_CP3",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU2_CP3-res_id_VDU2",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP3_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU1_CP3_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP3-res_id_VDU1_1",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extVirtualLinkInfo": _inst_info_example_1["extVirtualLinkInfo"],
|
||||
"extManagedVirtualLinkInfo":
|
||||
_inst_info_example_1["extManagedVirtualLinkInfo"],
|
||||
"vnfcResourceInfo": [
|
||||
{
|
||||
"id": "res_id_VDU1_1_update",
|
||||
|
@ -1200,9 +1140,6 @@ _inst_info_example_5 = {
|
|||
"resourceId": "res_id_VDU1_1_update",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"metadata": {
|
||||
"current_vnfd_id": 'new_vnfd_id'
|
||||
},
|
||||
"storageResourceIds": [
|
||||
"new_res_id_VirtualStorage_1"
|
||||
],
|
||||
|
@ -1233,6 +1170,10 @@ _inst_info_example_5 = {
|
|||
"vnfLinkPortId": "res_id_VDU1_CP5_1"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"image-VDU1-VirtualStorage": "image-VDU1-update"
|
||||
# other attributes omitted
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -1242,9 +1183,6 @@ _inst_info_example_5 = {
|
|||
"resourceId": "res_id_VDU2",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"metadata": {
|
||||
"current_vnfd_id": 'new_vnfd_id'
|
||||
},
|
||||
"vnfcCpInfo": [
|
||||
{
|
||||
"id": "VDU2_CP1-res_id_VDU2",
|
||||
|
@ -1272,72 +1210,14 @@ _inst_info_example_5 = {
|
|||
"vnfLinkPortId": "res_id_VDU2_CP5"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"image-VDU2": "image-VDU2-update"
|
||||
# other attributes omitted
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo": [
|
||||
{
|
||||
"id": "res_id_internalVL3",
|
||||
"vnfVirtualLinkDescId": "internalVL3",
|
||||
"networkResource": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_internalVL3",
|
||||
"vimLevelResourceType": "OS::Neutron::Net"
|
||||
},
|
||||
"vnfLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU2_CP5",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU2_CP5",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU2_CP5-res_id_VDU2",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP5_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU1_CP5_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP5-res_id_VDU1_1",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "res_id_internalVL2",
|
||||
"vnfVirtualLinkDescId": "internalVL2",
|
||||
"networkResource": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_internalVL2",
|
||||
"vimLevelResourceType": "OS::Neutron::Net"
|
||||
},
|
||||
"vnfLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU2_CP4",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU2_CP4",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU2_CP4-res_id_VDU2",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP4_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_connection_id",
|
||||
"resourceId": "res_id_VDU1_CP4_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP4-res_id_VDU1_1",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo":
|
||||
_inst_info_example_1["vnfVirtualLinkResourceInfo"],
|
||||
"virtualStorageResourceInfo": [
|
||||
{
|
||||
"id": "new_res_id_VirtualStorage_1",
|
||||
|
@ -1348,7 +1228,7 @@ _inst_info_example_5 = {
|
|||
"vimLevelResourceType": "OS::Cinder::Volume"
|
||||
}
|
||||
}
|
||||
],
|
||||
]
|
||||
}
|
||||
|
||||
# expected results
|
||||
|
@ -1372,7 +1252,8 @@ _expected_resource_changes_instantiate = {
|
|||
],
|
||||
"addedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_1"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -1389,7 +1270,8 @@ _expected_resource_changes_instantiate = {
|
|||
"VDU2_CP3-res_id_VDU2",
|
||||
"VDU2_CP4-res_id_VDU2",
|
||||
"VDU2_CP5-res_id_VDU2"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU2": "image-VDU2"}
|
||||
}
|
||||
],
|
||||
"affectedVirtualLinks": [
|
||||
|
@ -1510,7 +1392,8 @@ _expected_resource_changes_scale_out = {
|
|||
],
|
||||
"addedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_2"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
}
|
||||
],
|
||||
"affectedVirtualLinks": [
|
||||
|
@ -1608,7 +1491,8 @@ _expected_resource_changes_scale_in = {
|
|||
],
|
||||
"removedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_2"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
}
|
||||
],
|
||||
"affectedVirtualLinks": [
|
||||
|
@ -1706,7 +1590,8 @@ _expected_resource_changes_terminate = {
|
|||
],
|
||||
"removedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_1"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -1723,7 +1608,8 @@ _expected_resource_changes_terminate = {
|
|||
"VDU2_CP3-res_id_VDU2",
|
||||
"VDU2_CP4-res_id_VDU2",
|
||||
"VDU2_CP5-res_id_VDU2"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU2": "image-VDU2"}
|
||||
}
|
||||
],
|
||||
"affectedVirtualLinks": [
|
||||
|
@ -2017,7 +1903,8 @@ _expected_resource_changes_heal = {
|
|||
"VDU1_CP3-res_id_VDU1_1",
|
||||
"VDU1_CP4-res_id_VDU1_1",
|
||||
"VDU1_CP5-res_id_VDU1_1"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_1_new",
|
||||
|
@ -2034,7 +1921,8 @@ _expected_resource_changes_heal = {
|
|||
"VDU1_CP3-res_id_VDU1_1_new",
|
||||
"VDU1_CP4-res_id_VDU1_1_new",
|
||||
"VDU1_CP5-res_id_VDU1_1_new"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_2",
|
||||
|
@ -2054,7 +1942,8 @@ _expected_resource_changes_heal = {
|
|||
],
|
||||
"removedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_2"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_2_new",
|
||||
|
@ -2074,7 +1963,8 @@ _expected_resource_changes_heal = {
|
|||
],
|
||||
"addedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_2_new"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
],
|
||||
"affectedVirtualLinks": [
|
||||
|
@ -2130,6 +2020,7 @@ _expected_resource_changes_heal = {
|
|||
}
|
||||
]
|
||||
}
|
||||
|
||||
_expected_resource_changes_change_vnfpkg = {
|
||||
"affectedVnfcs": [
|
||||
{
|
||||
|
@ -2150,7 +2041,8 @@ _expected_resource_changes_change_vnfpkg = {
|
|||
],
|
||||
"removedStorageResourceIds": [
|
||||
"res_id_VirtualStorage_1"
|
||||
]
|
||||
],
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_1_update",
|
||||
|
@ -2171,9 +2063,7 @@ _expected_resource_changes_change_vnfpkg = {
|
|||
"addedStorageResourceIds": [
|
||||
"new_res_id_VirtualStorage_1"
|
||||
],
|
||||
'metadata': {
|
||||
'current_vnfd_id': 'new_vnfd_id'
|
||||
}
|
||||
"metadata": {"image-VDU1-VirtualStorage": "image-VDU1-update"}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2",
|
||||
|
@ -2191,9 +2081,7 @@ _expected_resource_changes_change_vnfpkg = {
|
|||
"VDU2_CP4-res_id_VDU2",
|
||||
"VDU2_CP5-res_id_VDU2"
|
||||
],
|
||||
'metadata': {
|
||||
'current_vnfd_id': 'new_vnfd_id'
|
||||
}
|
||||
"metadata": {"image-VDU2": "image-VDU2-update"}
|
||||
}
|
||||
],
|
||||
"affectedVirtualStorages": [
|
||||
|
|
|
@ -709,24 +709,37 @@ _modify_vnfc_info_example = {
|
|||
|
||||
# change_vnfpkg example
|
||||
_change_vnfpkg_example = {
|
||||
"vnfdId": '61723406-6634-2fc0-060a-0b11104d2667',
|
||||
"vnfdId": SAMPLE_VNFD_ID,
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"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"},
|
||||
}]
|
||||
"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"},
|
||||
},
|
||||
{
|
||||
"vdu_id": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
_change_cnf_vnfpkg_example = {
|
||||
|
@ -1826,12 +1839,12 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
|
|||
self.assertEqual(len(expected_res_ids[key][name]), len(ids))
|
||||
|
||||
@mock.patch.object(nfvo_client.NfvoClient, 'grant')
|
||||
def test_change_vnfpkg_grant_update_reses(self, mocked_grant):
|
||||
def test_change_vnfpkg_grant_rolling_update(self, mocked_grant):
|
||||
# prepare
|
||||
inst = objects.VnfInstanceV2(
|
||||
# required fields
|
||||
id=uuidutils.generate_uuid(),
|
||||
vnfdId=SAMPLE_VNFD_ID,
|
||||
vnfdId=uuidutils.generate_uuid(),
|
||||
vnfProvider='provider',
|
||||
vnfProductName='product name',
|
||||
vnfSoftwareVersion='software version',
|
||||
|
@ -1866,154 +1879,53 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
|
|||
expected_fixed_items = {
|
||||
'vnfInstanceId': inst.id,
|
||||
'vnfLcmOpOccId': lcmocc.id,
|
||||
'vnfdId': '61723406-6634-2fc0-060a-0b11104d2667',
|
||||
'vnfdId': inst.vnfdId,
|
||||
'operation': 'CHANGE_VNFPKG',
|
||||
'isAutomaticInvocation': False
|
||||
'isAutomaticInvocation': False,
|
||||
# change_vnfpkg specific
|
||||
'dstVnfdId': SAMPLE_VNFD_ID,
|
||||
'flavourId': inst.instantiatedVnfInfo.flavourId
|
||||
}
|
||||
for key, value in expected_fixed_items.items():
|
||||
self.assertEqual(value, grant_req[key])
|
||||
|
||||
update_reses = grant_req['updateResources']
|
||||
target_vdu_list = [
|
||||
vdu_param.get(
|
||||
'vdu_id') for vdu_param in req.additionalParams.get(
|
||||
'vdu_params')]
|
||||
for i in range(len(update_reses)):
|
||||
self.assertEqual('COMPUTE', update_reses[i]['type'])
|
||||
for target_vdu in target_vdu_list:
|
||||
self.assertEqual(target_vdu,
|
||||
update_reses[i]['resourceTemplateId'])
|
||||
|
||||
@mock.patch.object(nfvo_client.NfvoClient, 'grant')
|
||||
def test_change_vnfpkg_grant_add_reses(self, mocked_grant):
|
||||
# prepare
|
||||
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'
|
||||
)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
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)
|
||||
|
||||
mocked_grant.return_value = objects.GrantV1()
|
||||
|
||||
# run change_vnfpkg_grant
|
||||
grant_req, _ = self.driver.grant(
|
||||
self.context, lcmocc, inst, self.vnfd_1)
|
||||
|
||||
# check grant_req is constructed according to intention
|
||||
grant_req = grant_req.to_dict()
|
||||
expected_fixed_items = {
|
||||
'vnfInstanceId': inst.id,
|
||||
'vnfLcmOpOccId': lcmocc.id,
|
||||
'vnfdId': '61723406-6634-2fc0-060a-0b11104d2667',
|
||||
'operation': 'CHANGE_VNFPKG',
|
||||
'isAutomaticInvocation': False
|
||||
# check removeResources
|
||||
rm_reses = grant_req['removeResources']
|
||||
check_reses = {
|
||||
'COMPUTE': {'VDU1': [], 'VDU2': []},
|
||||
'STORAGE': {'VirtualStorage': []}
|
||||
}
|
||||
for key, value in expected_fixed_items.items():
|
||||
self.assertEqual(value, grant_req[key])
|
||||
|
||||
add_reses = grant_req['addResources']
|
||||
for inst_vnc in inst_info.vnfcResourceInfo:
|
||||
nodes = self.vnfd_1.get_vdu_nodes(inst_info.flavourId)
|
||||
vdu_storage_names = self.vnfd_1.get_vdu_storages(
|
||||
nodes[inst_vnc.vduId])
|
||||
for i in range(len(add_reses)):
|
||||
self.assertEqual('STORAGE', add_reses[i]['type'])
|
||||
for vdu_storage_name in vdu_storage_names:
|
||||
self.assertEqual(vdu_storage_name,
|
||||
add_reses[i]['resourceTemplateId'])
|
||||
|
||||
@mock.patch.object(nfvo_client.NfvoClient, 'grant')
|
||||
def test_change_vnfpkg_grant_remove_reses(self, mocked_grant):
|
||||
# prepare
|
||||
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'
|
||||
)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
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)
|
||||
|
||||
mocked_grant.return_value = objects.GrantV1()
|
||||
|
||||
# run change_vnfpkg_grant
|
||||
grant_req, _ = self.driver.grant(
|
||||
self.context, lcmocc, inst, self.vnfd_1)
|
||||
|
||||
# check grant_req is constructed according to intention
|
||||
grant_req = grant_req.to_dict()
|
||||
expected_fixed_items = {
|
||||
'vnfInstanceId': inst.id,
|
||||
'vnfLcmOpOccId': lcmocc.id,
|
||||
'vnfdId': '61723406-6634-2fc0-060a-0b11104d2667',
|
||||
'operation': 'CHANGE_VNFPKG',
|
||||
'isAutomaticInvocation': False
|
||||
}
|
||||
for key, value in expected_fixed_items.items():
|
||||
self.assertEqual(value, grant_req[key])
|
||||
|
||||
remove_reses = grant_req['removeResources']
|
||||
inst_stor_info = inst_info.virtualStorageResourceInfo
|
||||
check_reses = []
|
||||
for str_info in inst_stor_info:
|
||||
check_res = {
|
||||
'resourceId': str_info.storageResource.resourceId,
|
||||
'vimLevelResourceType':
|
||||
str_info.storageResource.vimLevelResourceType
|
||||
expected_res_ids = {
|
||||
'COMPUTE': {
|
||||
'VDU1': ['res_id_VDU1_1', 'res_id_VDU1_2'],
|
||||
'VDU2': ['res_id_VDU2']
|
||||
},
|
||||
'STORAGE': {
|
||||
'VirtualStorage': ['res_id_VirtualStorage_1',
|
||||
'res_id_VirtualStorage_2']
|
||||
}
|
||||
check_reses.append(check_res)
|
||||
for i in range(len(remove_reses)):
|
||||
self.assertEqual('STORAGE', remove_reses[i]['type'])
|
||||
self.assertEqual(str_info.virtualStorageDescId,
|
||||
remove_reses[i]['resourceTemplateId'])
|
||||
for j in range(len(check_reses)):
|
||||
for k in range(len(remove_reses)):
|
||||
if j == k:
|
||||
self.assertEqual(
|
||||
check_reses[j]['resourceId'],
|
||||
remove_reses[j]['resource']['resourceId'])
|
||||
self.assertEqual(
|
||||
check_reses[j]['vimLevelResourceType'],
|
||||
remove_reses[j]['resource']['vimLevelResourceType'])
|
||||
}
|
||||
for res in rm_reses:
|
||||
check_reses[res['type']][res['resourceTemplateId']].append(
|
||||
res['resource']['resourceId'])
|
||||
|
||||
for key, value in check_reses.items():
|
||||
for name, ids in value.items():
|
||||
self.assertEqual(expected_res_ids[key][name], ids)
|
||||
|
||||
# check addResources
|
||||
add_reses = grant_req['addResources']
|
||||
check_reses = {
|
||||
'COMPUTE': {'VDU1': [], 'VDU2': []},
|
||||
'STORAGE': {'VirtualStorage': []},
|
||||
}
|
||||
for res in add_reses:
|
||||
check_reses[res['type']][res['resourceTemplateId']].append(
|
||||
res['id'])
|
||||
|
||||
for key, value in check_reses.items():
|
||||
for name, ids in value.items():
|
||||
self.assertEqual(len(expected_res_ids[key][name]), len(ids))
|
||||
|
||||
@mock.patch.object(nfvo_client.NfvoClient, 'grant')
|
||||
def test_cnf_instantiate_grant(self, mocked_grant):
|
||||
|
@ -2169,7 +2081,8 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
|
|||
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||
_change_cnf_vnfpkg_example)
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||
dstVnfdId=_change_cnf_vnfpkg_example['vnfdId']
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
lcmocc = objects.VnfLcmOpOccV2(
|
||||
|
|
|
@ -273,7 +273,7 @@ class TestVnflcmV2(db_base.SqlTestCase):
|
|||
ex = self.assertRaises(sol_ex.InvalidSubscription,
|
||||
self.controller.subscription_create, request=self.request,
|
||||
body=body)
|
||||
self.assertEqual("ParmasBasic must be specified.", ex.detail)
|
||||
self.assertEqual("ParamsBasic must be specified.", ex.detail)
|
||||
|
||||
body = {
|
||||
"callbackUri": "http://127.0.0.1:6789/notification",
|
||||
|
|
|
@ -14,19 +14,15 @@
|
|||
# under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import subprocess
|
||||
|
||||
from datetime import datetime
|
||||
from oslo_utils import uuidutils
|
||||
from unittest import mock
|
||||
|
||||
from tacker import context
|
||||
from tacker.sol_refactored.common import vnfd_utils
|
||||
from tacker.sol_refactored.infra_drivers.openstack import heat_utils
|
||||
from tacker.sol_refactored.infra_drivers.openstack import openstack
|
||||
from tacker.sol_refactored.nfvo import glance_utils
|
||||
from tacker.sol_refactored import objects
|
||||
from tacker.sol_refactored.objects.v2 import fields
|
||||
from tacker.tests import base
|
||||
|
@ -857,6 +853,36 @@ _heat_reses_example = (
|
|||
_heat_reses_example_change_ext_conn = (
|
||||
_heat_reses_example_base + _heat_reses_example_cps_after)
|
||||
|
||||
# heat get_parameters example
|
||||
_nfv_dict = {
|
||||
"VDU": {
|
||||
"VDU1": {"computeFlavourId": "m1.tiny"},
|
||||
"VDU1-VirtualStorage": {"vcImageId": "image-VDU1"},
|
||||
"VDU2": {"vcImageId": "image-VDU2", "computeFlavourId": "m1.small"}
|
||||
}
|
||||
}
|
||||
_heat_get_parameters_example = {
|
||||
'nfv': json.dumps(_nfv_dict)
|
||||
}
|
||||
|
||||
# heat get_template example
|
||||
_heat_get_template_example = {
|
||||
"resources": {
|
||||
"myet4efobvvp": {
|
||||
"properties": {
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
},
|
||||
"bemybz4ugeso": {
|
||||
"properties": {
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# change vnfpkg before inst info
|
||||
_inst_info_example = {
|
||||
"flavourId": "simple",
|
||||
|
@ -1571,7 +1597,9 @@ _expected_inst_info = {
|
|||
"creation_time": "2021-12-10T01:03:49Z",
|
||||
"parent_stack_id": _stack_id_VDU1_scale,
|
||||
"parent_resource_name": "myet4efobvvp",
|
||||
"stack_id": _stack_id_VDU1_2
|
||||
"stack_id": _stack_id_VDU1_2,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1616,7 +1644,9 @@ _expected_inst_info = {
|
|||
"creation_time": "2021-12-10T00:41:43Z",
|
||||
"parent_stack_id": _stack_id_VDU1_scale,
|
||||
"parent_resource_name": "bemybz4ugeso",
|
||||
"stack_id": _stack_id_VDU1_1
|
||||
"stack_id": _stack_id_VDU1_1,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1657,7 +1687,9 @@ _expected_inst_info = {
|
|||
],
|
||||
"metadata": {
|
||||
"creation_time": "2021-12-10T00:40:46Z",
|
||||
"stack_id": _stack_id
|
||||
"stack_id": _stack_id,
|
||||
"flavor": "m1.small",
|
||||
"image-VDU2": "image-VDU2"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -2126,7 +2158,9 @@ _expected_inst_info_change_ext_conn = {
|
|||
"creation_time": "2021-12-10T01:03:49Z",
|
||||
"parent_stack_id": _stack_id_VDU1_scale,
|
||||
"parent_resource_name": "myet4efobvvp",
|
||||
"stack_id": _stack_id_VDU1_2
|
||||
"stack_id": _stack_id_VDU1_2,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -2171,7 +2205,9 @@ _expected_inst_info_change_ext_conn = {
|
|||
"creation_time": "2021-12-10T00:41:43Z",
|
||||
"parent_stack_id": _stack_id_VDU1_scale,
|
||||
"parent_resource_name": "bemybz4ugeso",
|
||||
"stack_id": _stack_id_VDU1_1
|
||||
"stack_id": _stack_id_VDU1_1,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-VirtualStorage": "image-VDU1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -2212,7 +2248,9 @@ _expected_inst_info_change_ext_conn = {
|
|||
],
|
||||
"metadata": {
|
||||
"creation_time": "2021-12-10T00:40:46Z",
|
||||
"stack_id": _stack_id
|
||||
"stack_id": _stack_id,
|
||||
"flavor": "m1.small",
|
||||
"image-VDU2": "image-VDU2"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -2684,6 +2722,7 @@ class TestOpenstack(base.BaseTestCase):
|
|||
req = objects.InstantiateVnfRequest.from_dict(
|
||||
_instantiate_req_example)
|
||||
inst = objects.VnfInstanceV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vimConnectionInfo=req.vimConnectionInfo
|
||||
)
|
||||
grant_req = objects.GrantRequestV1(
|
||||
|
@ -2691,9 +2730,15 @@ class TestOpenstack(base.BaseTestCase):
|
|||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
# prepare heat responses
|
||||
heat_client = mock.Mock()
|
||||
heat_client.get_resources.return_value = _heat_reses_example
|
||||
heat_client.get_parameters.return_value = _heat_get_parameters_example
|
||||
heat_client.get_template.return_value = _heat_get_template_example
|
||||
|
||||
# execute make_instantiated_vnf_info
|
||||
self.driver._make_instantiated_vnf_info(req, inst, grant_req, grant,
|
||||
self.vnfd_1, _heat_reses_example)
|
||||
self.vnfd_1, heat_client)
|
||||
|
||||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
|
@ -2709,6 +2754,7 @@ class TestOpenstack(base.BaseTestCase):
|
|||
_vim_connection_info_example)
|
||||
}
|
||||
inst = objects.VnfInstanceV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
instantiatedVnfInfo=inst_info,
|
||||
vimConnectionInfo=vim_info
|
||||
)
|
||||
|
@ -2717,9 +2763,15 @@ class TestOpenstack(base.BaseTestCase):
|
|||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
# prepare heat responses
|
||||
heat_client = mock.Mock()
|
||||
heat_client.get_resources.return_value = _heat_reses_example
|
||||
heat_client.get_parameters.return_value = _heat_get_parameters_example
|
||||
heat_client.get_template.return_value = _heat_get_template_example
|
||||
|
||||
# execute make_instantiated_vnf_info
|
||||
self.driver._make_instantiated_vnf_info(req, inst, grant_req, grant,
|
||||
self.vnfd_1, _heat_reses_example)
|
||||
self.vnfd_1, heat_client)
|
||||
|
||||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
|
@ -2736,6 +2788,7 @@ class TestOpenstack(base.BaseTestCase):
|
|||
_vim_connection_info_example)
|
||||
}
|
||||
inst = objects.VnfInstanceV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
instantiatedVnfInfo=inst_info,
|
||||
vimConnectionInfo=vim_info
|
||||
)
|
||||
|
@ -2744,402 +2797,17 @@ class TestOpenstack(base.BaseTestCase):
|
|||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
# prepare heat responses
|
||||
heat_client = mock.Mock()
|
||||
heat_client.get_resources.return_value = (
|
||||
_heat_reses_example_change_ext_conn)
|
||||
heat_client.get_parameters.return_value = _heat_get_parameters_example
|
||||
heat_client.get_template.return_value = _heat_get_template_example
|
||||
|
||||
# execute make_instantiated_vnf_info
|
||||
self.driver._make_instantiated_vnf_info(req, inst, grant_req, grant,
|
||||
self.vnfd_1, _heat_reses_example_change_ext_conn)
|
||||
self.vnfd_1, heat_client)
|
||||
|
||||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_parameters')
|
||||
@mock.patch.object(subprocess, 'run')
|
||||
@mock.patch.object(glance_utils.GlanceClient, 'get_image')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'update_stack')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_list')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_template')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resources')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_info')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_stack_resource')
|
||||
def test_change_vnfpkg_404(
|
||||
self, mocked_get_stack_resource, mocked_get_resource_info,
|
||||
mocked_get_resources, mocked_get_template,
|
||||
mocked_get_resource_list, mocked_update_stack,
|
||||
mocked_get_image, mocked_run, mocked_get_parameters):
|
||||
# prepare
|
||||
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||
_change_vnfpkg_example)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
vim_info = {
|
||||
"vim1": objects.VimConnectionInfo.from_dict(
|
||||
_vim_connection_info_for_change_vnfpkg)
|
||||
}
|
||||
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'
|
||||
)
|
||||
inst.vimConnectionInfo = vim_info
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
stack_body = {'stack': {'id': uuidutils.generate_uuid(),
|
||||
'name': 'test'}}
|
||||
stack_body_2 = {'stack': {
|
||||
'stack_name':
|
||||
'vnf-d8962b72-6dac-4eb5-a8c4-8c7a2abaefb7-VDU1_scale_group'}}
|
||||
mocked_get_stack_resource.side_effect = [stack_body, stack_body_2]
|
||||
|
||||
body_2 = {"attributes": {"floating_ip_address": "192.168.0.1"}}
|
||||
body_3 = {"attributes": {
|
||||
"image": {"id": "image-1.0.0-x86_64-disk"},
|
||||
"flavor": {"original_name": "m1.tiny"}
|
||||
}
|
||||
}
|
||||
mocked_get_resource_info.side_effect = [None,
|
||||
body_2, body_3]
|
||||
mocked_get_resources.side_effect = [mock_resource['resources'],
|
||||
_heat_reses_example]
|
||||
mocked_get_template.return_value = mock_resource_template
|
||||
mocked_get_resource_list.side_effect = [mock_resource_list,
|
||||
mock_resource_list_2]
|
||||
mocked_update_stack.return_value = mock.Mock()
|
||||
resp_image = requests.Response()
|
||||
resp_image.name = "image-1.0.0-x86_64-disk"
|
||||
mocked_get_image.return_value = resp_image
|
||||
out = requests.Response()
|
||||
out.returncode = 0
|
||||
mocked_run.return_value = out
|
||||
parameter = {
|
||||
'nfv': '{"VDU":{"VDU1":{"vcImageId":""},'
|
||||
'"VDU2":{"vcImageId":""},'
|
||||
'"VirtualStorage":{"vcImageId":""}}}'
|
||||
}
|
||||
mocked_get_parameters.return_value = parameter
|
||||
# execute change_vnfpkg
|
||||
self.driver.change_vnfpkg(req, inst, grant_req, grant,
|
||||
self.vnfd_1)
|
||||
|
||||
# check
|
||||
for vnfc_res in inst.instantiatedVnfInfo.vnfcResourceInfo:
|
||||
if vnfc_res.vduId == "VDU1":
|
||||
self.assertEqual(vnfc_res.id,
|
||||
'e79ebeaf-1b26-4ff9-9895-f4c78a8a39a6')
|
||||
self.assertEqual(vnfc_res.computeResource.resourceId,
|
||||
'e79ebeaf-1b26-4ff9-9895-f4c78a8a39a6')
|
||||
self.assertIn('current_vnfd_id', vnfc_res.metadata)
|
||||
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resources')
|
||||
@mock.patch.object(subprocess, 'run')
|
||||
@mock.patch.object(glance_utils.GlanceClient, 'get_image')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_list')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'update_stack')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_parameters')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_template')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_info')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_stack_resource')
|
||||
def test_change_vnfpkg_200(
|
||||
self, mocked_get_stack_resource, mocked_get_resource_info,
|
||||
mocked_get_template, mocked_get_parameters,
|
||||
mocked_update_stack, mocked_get_resource_list, mocked_get_image,
|
||||
mocked_run, mocked_get_resources):
|
||||
# prepare
|
||||
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||
_change_vnfpkg_example_2)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
vim_info = {
|
||||
"vim1": objects.VimConnectionInfo.from_dict(
|
||||
_vim_connection_info_for_change_vnfpkg)
|
||||
}
|
||||
inst = objects.VnfInstanceV2(
|
||||
# required fields
|
||||
id="d7aeba20-1b00-4bff-b050-6b42a262c84d",
|
||||
vnfdId=SAMPLE_VNFD_ID,
|
||||
vnfProvider='provider',
|
||||
vnfProductName='product name',
|
||||
vnfSoftwareVersion='software version',
|
||||
vnfdVersion='vnfd version',
|
||||
instantiationState='INSTANTIATED'
|
||||
)
|
||||
inst.vimConnectionInfo = vim_info
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
stack_body = {'stack': {'id': "d7aeba20-1b00-4bff-b050-6b42a262c84d",
|
||||
'name': 'test'}}
|
||||
stack_body_2 = {'stack': {
|
||||
'stack_name':
|
||||
'vnf-d8962b72-6dac-4eb5-a8c4-8c7a2abaefb7-VDU1_scale_group'}}
|
||||
mocked_get_stack_resource.side_effect = [stack_body, stack_body_2]
|
||||
|
||||
body = {"resource": "resource"}
|
||||
body_2 = {"attributes": {"floating_ip_address": "192.168.0.1"}}
|
||||
body_3 = {"attributes": {
|
||||
"image": {"id": "image-1.0.0-x86_64-disk"},
|
||||
"flavor": {"original_name": "m1.tiny"}
|
||||
}
|
||||
}
|
||||
mocked_get_resource_info.side_effect = [body['resource'], body_2,
|
||||
body_3]
|
||||
mocked_get_resources.side_effect = [mock_resource['resources'],
|
||||
_heat_reses_example]
|
||||
mocked_get_template.return_value = mock_resource_template_2
|
||||
mocked_get_resource_list.return_value = mock_resource_list_3
|
||||
mocked_update_stack.return_value = mock.Mock()
|
||||
resp_image = requests.Response()
|
||||
resp_image.name = "image-1.0.0-x86_64-disk"
|
||||
mocked_get_image.return_value = resp_image
|
||||
out = requests.Response()
|
||||
out.returncode = 0
|
||||
mocked_run.return_value = out
|
||||
parameter = {
|
||||
'nfv': '{"VDU":{"VDU1":{"vcImageId":""},'
|
||||
'"VDU2":{"vcImageId":""},'
|
||||
'"VirtualStorage":{"vcImageId":""}}}'
|
||||
}
|
||||
mocked_get_parameters.return_value = parameter
|
||||
# execute change_vnfpkg
|
||||
self.driver.change_vnfpkg(req, inst, grant_req, grant,
|
||||
self.vnfd_1)
|
||||
|
||||
# check
|
||||
for vnfc_res in inst.instantiatedVnfInfo.vnfcResourceInfo:
|
||||
if vnfc_res.vduId == "VDU2":
|
||||
self.assertEqual(vnfc_res.id,
|
||||
'res_id_VDU2_1')
|
||||
self.assertEqual(vnfc_res.computeResource.resourceId,
|
||||
'res_id_VDU2_1')
|
||||
self.assertIn('current_vnfd_id', vnfc_res.metadata)
|
||||
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_parameters')
|
||||
@mock.patch.object(subprocess, 'run')
|
||||
@mock.patch.object(glance_utils.GlanceClient, 'get_image')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_info')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_list')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'update_stack')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_template')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resources')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_stack_resource')
|
||||
def test_change_vnfpkg_rollback(
|
||||
self, mocked_get_stack_resource, mocked_get_resources,
|
||||
mocked_get_template, mocked_update_stack,
|
||||
mocked_get_resource_list, mocked_get_resource_info,
|
||||
mocked_get_image, mocked_run, mocked_get_parameters):
|
||||
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||
_change_vnfpkg_example)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
vim_info = {
|
||||
"vim1": objects.VimConnectionInfo.from_dict(
|
||||
_vim_connection_info_for_change_vnfpkg)
|
||||
}
|
||||
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'
|
||||
)
|
||||
inst.vimConnectionInfo = vim_info
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
affected_vnfcs = objects.AffectedVnfcV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vduId='VDU1',
|
||||
vnfdId=SAMPLE_VNFD_ID,
|
||||
changeType='ADDED',
|
||||
metadata={
|
||||
"creation_time": "2021-12-10T01:03:49Z",
|
||||
"stack_id": "vnf-d8962b72-6dac-4eb5-a8c4-8c7a2abaefb7-"
|
||||
"VDU1_scale_group-2zmsxtwtsj7n-"
|
||||
"fkwryhyv6qbr-qoemdwxw7o5c/"
|
||||
"d7aeba20-1b00-4bff-b050-6b42a262c84d",
|
||||
"parent_resource_name": "fkwryhyv6qbr"
|
||||
}
|
||||
)
|
||||
resource_change = objects.VnfLcmOpOccV2_ResourceChanges(
|
||||
affectedVnfcs=[affected_vnfcs]
|
||||
)
|
||||
|
||||
lcmocc = objects.VnfLcmOpOccV2(
|
||||
# required fields
|
||||
id=uuidutils.generate_uuid(),
|
||||
operationState=fields.LcmOperationStateType.FAILED_TEMP,
|
||||
stateEnteredTime=datetime.utcnow(),
|
||||
startTime=datetime.utcnow(),
|
||||
vnfInstanceId=inst.id,
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||
resourceChanges=resource_change,
|
||||
isAutomaticInvocation=False,
|
||||
isCancelPending=False,
|
||||
operationParams=req)
|
||||
|
||||
stack_body = {'stack': {'id': uuidutils.generate_uuid(),
|
||||
'name': 'test'}}
|
||||
stack_body_2 = {'stack': {
|
||||
'stack_name':
|
||||
'vnf-d8962b72-6dac-4eb5-a8c4-8c7a2abaefb7-VDU1_scale_group'}}
|
||||
mocked_get_stack_resource.side_effect = [stack_body, stack_body_2]
|
||||
|
||||
body = {"attributes": {"floating_ip_address": "192.168.0.1"}}
|
||||
body_2 = {"attributes": {
|
||||
"image": {"id": "image-1.0.0-x86_64-disk"},
|
||||
"flavor": {"original_name": "m1.tiny"}
|
||||
}
|
||||
}
|
||||
mocked_get_resource_info.side_effect = [body, body_2]
|
||||
mocked_get_resources.side_effect = [mock_resource['resources'],
|
||||
_heat_reses_example]
|
||||
mocked_get_template.return_value = mock_resource_template
|
||||
mocked_get_resource_list.return_value = mock_resource_list_2
|
||||
mocked_update_stack.return_value = mock.Mock()
|
||||
resp_image = requests.Response()
|
||||
resp_image.name = "image-1.0.0-x86_64-disk"
|
||||
mocked_get_image.return_value = resp_image
|
||||
out = requests.Response()
|
||||
out.returncode = 0
|
||||
mocked_run.return_value = out
|
||||
parameter = {
|
||||
'nfv': '{"VDU":{"VDU1":{"vcImageId":""},'
|
||||
'"VDU2":{"vcImageId":""},'
|
||||
'"VirtualStorage":{"vcImageId":""}}}'
|
||||
}
|
||||
mocked_get_parameters.return_value = parameter
|
||||
self.driver.change_vnfpkg_rollback(req, inst, grant_req, grant,
|
||||
self.vnfd_1, lcmocc)
|
||||
# check
|
||||
for vnfc_res in inst.instantiatedVnfInfo.vnfcResourceInfo:
|
||||
if vnfc_res.vduId == "VDU1":
|
||||
self.assertEqual(vnfc_res.id,
|
||||
'e79ebeaf-1b26-4ff9-9895-f4c78a8a39a6')
|
||||
self.assertEqual(vnfc_res.computeResource.resourceId,
|
||||
'e79ebeaf-1b26-4ff9-9895-f4c78a8a39a6')
|
||||
self.assertIn('current_vnfd_id', vnfc_res.metadata)
|
||||
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resources')
|
||||
@mock.patch.object(subprocess, 'run')
|
||||
@mock.patch.object(glance_utils.GlanceClient, 'get_image')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_info')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_resource_list')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'update_stack')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_parameters')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_template')
|
||||
@mock.patch.object(heat_utils.HeatClient, 'get_stack_resource')
|
||||
def test_change_vnfpkg_rollback_same(
|
||||
self, mocked_get_stack_resource, mocked_get_template,
|
||||
mocked_get_parameters, mocked_update_stack,
|
||||
mocked_get_resource_list, mocked_get_resource_info,
|
||||
mocked_get_image, mocked_run, mocked_get_resources):
|
||||
req = objects.ChangeCurrentVnfPkgRequest.from_dict(
|
||||
_change_vnfpkg_example_2)
|
||||
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||
_inst_info_example)
|
||||
vim_info = {
|
||||
"vim1": objects.VimConnectionInfo.from_dict(
|
||||
_vim_connection_info_for_change_vnfpkg)
|
||||
}
|
||||
inst = objects.VnfInstanceV2(
|
||||
# required fields
|
||||
id="d7aeba20-1b00-4bff-b050-6b42a262c84d",
|
||||
vnfdId=SAMPLE_VNFD_ID,
|
||||
vnfProvider='provider',
|
||||
vnfProductName='product name',
|
||||
vnfSoftwareVersion='software version',
|
||||
vnfdVersion='vnfd version',
|
||||
instantiationState='INSTANTIATED'
|
||||
)
|
||||
inst.vimConnectionInfo = vim_info
|
||||
inst.instantiatedVnfInfo = inst_info
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
affected_vnfcs = objects.AffectedVnfcV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vduId='VDU2',
|
||||
vnfdId=SAMPLE_VNFD_ID,
|
||||
changeType='MODIFIED',
|
||||
metadata={
|
||||
"creation_time": "2021-12-10T01:03:49Z",
|
||||
"stack_id": 'vnf-d7aeba20-1b00-4bff-b050-6b42a262c84d/'
|
||||
'd7aeba20-1b00-4bff-b050-6b42a262c84d'
|
||||
}
|
||||
)
|
||||
resource_change = objects.VnfLcmOpOccV2_ResourceChanges(
|
||||
affectedVnfcs=[affected_vnfcs]
|
||||
)
|
||||
|
||||
lcmocc = objects.VnfLcmOpOccV2(
|
||||
# required fields
|
||||
id=uuidutils.generate_uuid(),
|
||||
operationState=fields.LcmOperationStateType.FAILED_TEMP,
|
||||
stateEnteredTime=datetime.utcnow(),
|
||||
startTime=datetime.utcnow(),
|
||||
vnfInstanceId=inst.id,
|
||||
operation=fields.LcmOperationType.CHANGE_VNFPKG,
|
||||
resourceChanges=resource_change,
|
||||
isAutomaticInvocation=False,
|
||||
isCancelPending=False,
|
||||
operationParams=req)
|
||||
|
||||
stack_body = {'stack': {'id': 'd7aeba20-1b00-4bff-b050-6b42a262c84d',
|
||||
'name': 'test'}}
|
||||
stack_body_2 = {'stack': {
|
||||
'stack_name':
|
||||
'vnf-d7aeba20-1b00-4bff-b050-6b42a262c84d-VDU1_scale_group'}}
|
||||
mocked_get_stack_resource.side_effect = [stack_body, stack_body_2]
|
||||
|
||||
body = {"attributes": {"floating_ip_address": "192.168.0.1"}}
|
||||
body_2 = {"attributes": {
|
||||
"image": {
|
||||
"id": "image-1.0.0-x86_64-disk"},
|
||||
"flavor": {"original_name": "m1.tiny"}
|
||||
}
|
||||
}
|
||||
mocked_get_resource_info.side_effect = [body, body_2]
|
||||
mocked_get_resources.side_effect = [mock_resource['resources'],
|
||||
_heat_reses_example]
|
||||
mocked_get_template.return_value = mock_resource_template_3
|
||||
mocked_get_resource_list.return_value = mock_resource_list_3
|
||||
mocked_update_stack.return_value = mock.Mock()
|
||||
resp_image = requests.Response()
|
||||
resp_image.name = "image-1.0.0-x86_64-disk"
|
||||
mocked_get_image.return_value = resp_image
|
||||
out = requests.Response()
|
||||
out.returncode = 0
|
||||
mocked_run.return_value = out
|
||||
parameter = {
|
||||
'nfv': '{"VDU":{"VDU1":{"vcImageId":""},'
|
||||
'"VDU2":{"vcImageId":""},'
|
||||
'"VirtualStorage":{"vcImageId":""}}}'
|
||||
}
|
||||
mocked_get_parameters.return_value = parameter
|
||||
self.driver.change_vnfpkg_rollback(req, inst, grant_req, grant,
|
||||
self.vnfd_1, lcmocc)
|
||||
# check
|
||||
for vnfc_res in inst.instantiatedVnfInfo.vnfcResourceInfo:
|
||||
if vnfc_res.vduId == "VDU2":
|
||||
self.assertEqual(vnfc_res.id,
|
||||
'res_id_VDU2_1')
|
||||
self.assertEqual(vnfc_res.computeResource.resourceId,
|
||||
'res_id_VDU2_1')
|
||||
self.assertIn('current_vnfd_id', vnfc_res.metadata)
|
||||
|
|
Loading…
Reference in New Issue