615 lines
24 KiB
Python
615 lines
24 KiB
Python
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
from oslo_log import log as logging
|
|
from oslo_utils import uuidutils
|
|
|
|
from tacker.sol_refactored.common import exceptions as sol_ex
|
|
from tacker.sol_refactored.common import subscription_utils as subsc_utils
|
|
from tacker.sol_refactored.common import vnf_instance_utils as inst_utils
|
|
from tacker.sol_refactored import objects
|
|
from tacker.sol_refactored.objects.v2 import fields
|
|
|
|
|
|
LOG = logging.getLogger(__name__) # not used at the moment
|
|
|
|
|
|
def get_lcmocc(context, lcmocc_id):
|
|
lcmocc = objects.VnfLcmOpOccV2.get_by_id(context, lcmocc_id)
|
|
if lcmocc is None:
|
|
raise sol_ex.VnfLcmOpOccNotFound(lcmocc_id=lcmocc_id)
|
|
return lcmocc
|
|
|
|
|
|
def get_lcmocc_all(context, marker=None):
|
|
return objects.VnfLcmOpOccV2.get_all(context, marker)
|
|
|
|
|
|
def lcmocc_href(lcmocc_id, endpoint):
|
|
return "{}/vnflcm/v2/vnf_lcm_op_occs/{}".format(endpoint, lcmocc_id)
|
|
|
|
|
|
def lcmocc_task_href(lcmocc_id, task, endpoint):
|
|
return "{}/vnflcm/v2/vnf_lcm_op_occs/{}/{}".format(endpoint, lcmocc_id,
|
|
task)
|
|
|
|
|
|
def make_lcmocc_links(lcmocc, endpoint):
|
|
links = objects.VnfLcmOpOccV2_Links()
|
|
links.self = objects.Link(href=lcmocc_href(lcmocc.id, endpoint))
|
|
links.vnfInstance = objects.Link(
|
|
href=inst_utils.inst_href(lcmocc.vnfInstanceId, endpoint))
|
|
links.retry = objects.Link(
|
|
href=lcmocc_task_href(lcmocc.id, 'retry', endpoint))
|
|
links.rollback = objects.Link(
|
|
href=lcmocc_task_href(lcmocc.id, 'rollback', endpoint))
|
|
links.fail = objects.Link(
|
|
href=lcmocc_task_href(lcmocc.id, 'fail', endpoint))
|
|
# TODO(oda-g): add when implemented
|
|
# links.grant
|
|
# links.cancel
|
|
# links.vnfSnapshot
|
|
|
|
return links
|
|
|
|
|
|
def make_lcmocc_notif_data(subsc, lcmocc, endpoint):
|
|
notif_data = objects.VnfLcmOperationOccurrenceNotificationV2(
|
|
id=uuidutils.generate_uuid(),
|
|
notificationType="VnfLcmOperationOccurrenceNotification",
|
|
subscriptionId=subsc.id,
|
|
timeStamp=datetime.utcnow(),
|
|
operationState=lcmocc.operationState,
|
|
vnfInstanceId=lcmocc.vnfInstanceId,
|
|
operation=lcmocc.operation,
|
|
isAutomaticInvocation=lcmocc.isAutomaticInvocation,
|
|
verbosity=subsc.verbosity,
|
|
vnfLcmOpOccId=lcmocc.id,
|
|
_links=objects.LccnLinksV2(
|
|
vnfInstance=objects.NotificationLink(
|
|
href=inst_utils.inst_href(lcmocc.vnfInstanceId, endpoint)),
|
|
subscription=objects.NotificationLink(
|
|
href=subsc_utils.subsc_href(subsc.id, endpoint)),
|
|
vnfLcmOpOcc=objects.NotificationLink(
|
|
href=lcmocc_href(lcmocc.id, endpoint))
|
|
)
|
|
)
|
|
|
|
if ((lcmocc.operation == fields.LcmOperationType.MODIFY_INFO and
|
|
lcmocc.operationState == fields.LcmOperationStateType.PROCESSING) or
|
|
lcmocc.operationState == fields.LcmOperationStateType.STARTING):
|
|
notif_data.notificationStatus = 'START'
|
|
else:
|
|
notif_data.notificationStatus = 'RESULT'
|
|
|
|
if lcmocc.operationState in [fields.LcmOperationStateType.FAILED_TEMP,
|
|
fields.LcmOperationStateType.FAILED,
|
|
fields.LcmOperationStateType.ROLLED_BACK]:
|
|
# The existence of lcmocc.error is guaranteed.
|
|
notif_data.error = lcmocc.error
|
|
|
|
if notif_data.verbosity == fields.LcmOpOccNotificationVerbosityType.FULL:
|
|
if lcmocc.obj_attr_is_set('resourceChanges'):
|
|
attrs = ['affectedVnfcs',
|
|
'affectedVirtualLinks',
|
|
'affectedExtLinkPorts',
|
|
'affectedVirtualStorages']
|
|
for attr in attrs:
|
|
if lcmocc.resourceChanges.obj_attr_is_set(attr):
|
|
notif_data[attr] = lcmocc.resourceChanges[attr]
|
|
attrs = ['changedInfo',
|
|
'changedExtConnectivity',
|
|
'modificationsTriggeredByVnfPkgChange']
|
|
for attr in attrs:
|
|
if lcmocc.obj_attr_is_set(attr):
|
|
notif_data[attr] = lcmocc[attr]
|
|
|
|
return notif_data
|
|
|
|
|
|
def _make_affected_vnfc(vnfc, change_type, strgs):
|
|
affected_vnfc = objects.AffectedVnfcV2(
|
|
id=vnfc.id,
|
|
vduId=vnfc.vduId,
|
|
changeType=change_type,
|
|
computeResource=vnfc.computeResource
|
|
)
|
|
if vnfc.obj_attr_is_set('zoneId'):
|
|
affected_vnfc.zoneId = vnfc.zoneId
|
|
if vnfc.obj_attr_is_set('metadata'):
|
|
affected_vnfc.metadata = vnfc.metadata
|
|
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'):
|
|
# NOTE: in case of heal, volume may not be deleted/re-created.
|
|
if change_type == 'ADDED':
|
|
str_ids = [str_id for str_id in vnfc.storageResourceIds
|
|
if str_id in strgs]
|
|
if str_ids:
|
|
affected_vnfc.addedStorageResourceIds = str_ids
|
|
else: # 'REMOVED'
|
|
str_ids = [str_id for str_id in vnfc.storageResourceIds
|
|
if str_id in strgs]
|
|
if str_ids:
|
|
affected_vnfc.removedStorageResourceIds = str_ids
|
|
|
|
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,
|
|
vnfVirtualLinkDescId=vl.vnfVirtualLinkDescId,
|
|
changeType=change_type,
|
|
networkResource=vl.networkResource
|
|
)
|
|
if vl.obj_attr_is_set('vnfLinkPorts'):
|
|
affected_vl.vnfLinkPortIds = [port.id for port in vl.vnfLinkPorts]
|
|
|
|
return affected_vl
|
|
|
|
|
|
def _make_affected_vls_link_port_change(vls_saved, vls, common_vls):
|
|
affected_vls = []
|
|
|
|
for vl_id in common_vls:
|
|
old_ports = set()
|
|
new_ports = set()
|
|
for vl in vls_saved:
|
|
if vl.id == vl_id:
|
|
old_vl = vl
|
|
if vl.obj_attr_is_set('vnfLinkPorts'):
|
|
old_ports = {port.id for port in vl.vnfLinkPorts}
|
|
for vl in vls:
|
|
if vl.id == vl_id:
|
|
new_vl = vl
|
|
if vl.obj_attr_is_set('vnfLinkPorts'):
|
|
new_ports = {port.id for port in vl.vnfLinkPorts}
|
|
add_ports = new_ports - old_ports
|
|
rm_ports = old_ports - new_ports
|
|
# NOTE: Only for extManagedVirtualLink in case of heal
|
|
# (SOL003 all=true) there may be both of add_ports and rm_ports.
|
|
if add_ports:
|
|
affected_vl = objects.AffectedVirtualLinkV2(
|
|
id=new_vl.id,
|
|
vnfVirtualLinkDescId=new_vl.vnfVirtualLinkDescId,
|
|
changeType='LINK_PORT_ADDED',
|
|
networkResource=new_vl.networkResource,
|
|
vnfLinkPortIds=list(add_ports)
|
|
)
|
|
affected_vls.append(affected_vl)
|
|
if rm_ports:
|
|
affected_vl = objects.AffectedVirtualLinkV2(
|
|
id=old_vl.id,
|
|
vnfVirtualLinkDescId=old_vl.vnfVirtualLinkDescId,
|
|
changeType='LINK_PORT_REMOVED',
|
|
networkResource=old_vl.networkResource,
|
|
vnfLinkPortIds=list(rm_ports)
|
|
)
|
|
affected_vls.append(affected_vl)
|
|
|
|
return affected_vls
|
|
|
|
|
|
def _make_affected_strg(strg, change_type):
|
|
return objects.AffectedVirtualStorageV2(
|
|
id=strg.id,
|
|
virtualStorageDescId=strg.virtualStorageDescId,
|
|
changeType=change_type,
|
|
storageResource=strg.storageResource
|
|
)
|
|
|
|
|
|
def _make_affected_ext_link_ports(inst_info_saved, inst_info):
|
|
affected_ext_link_ports = []
|
|
|
|
ext_vl_ports_saved = set()
|
|
ext_vl_ports = set()
|
|
if inst_info_saved.obj_attr_is_set('extVirtualLinkInfo'):
|
|
for ext_vl in inst_info_saved.extVirtualLinkInfo:
|
|
if ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
ext_vl_ports_saved |= {port.id
|
|
for port in ext_vl.extLinkPorts}
|
|
if inst_info.obj_attr_is_set('extVirtualLinkInfo'):
|
|
for ext_vl in inst_info.extVirtualLinkInfo:
|
|
if ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
ext_vl_ports |= {port.id
|
|
for port in ext_vl.extLinkPorts}
|
|
add_ext_vl_ports = ext_vl_ports - ext_vl_ports_saved
|
|
rm_ext_vl_ports = ext_vl_ports_saved - ext_vl_ports
|
|
|
|
if add_ext_vl_ports:
|
|
for ext_vl in inst_info.extVirtualLinkInfo:
|
|
if not ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
continue
|
|
affected_ext_link_ports += [
|
|
objects.AffectedExtLinkPortV2(
|
|
id=port.id,
|
|
changeType='ADDED',
|
|
extCpInstanceId=port.cpInstanceId,
|
|
resourceHandle=port.resourceHandle
|
|
)
|
|
for port in ext_vl.extLinkPorts
|
|
if port.id in add_ext_vl_ports
|
|
]
|
|
if rm_ext_vl_ports:
|
|
for ext_vl in inst_info_saved.extVirtualLinkInfo:
|
|
if not ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
continue
|
|
affected_ext_link_ports += [
|
|
objects.AffectedExtLinkPortV2(
|
|
id=port.id,
|
|
changeType='REMOVED',
|
|
extCpInstanceId=port.cpInstanceId,
|
|
resourceHandle=port.resourceHandle
|
|
)
|
|
for port in ext_vl.extLinkPorts
|
|
if port.id in rm_ext_vl_ports
|
|
]
|
|
|
|
return affected_ext_link_ports
|
|
|
|
|
|
def _check_modification(inst_saved, inst, attr):
|
|
if not inst.obj_attr_is_set(attr):
|
|
return False
|
|
if (not inst_saved.obj_attr_is_set(attr) or
|
|
getattr(inst_saved, attr) != getattr(inst, attr)):
|
|
return True
|
|
return False
|
|
|
|
|
|
def _check_modification_inst(obj, inst_saved, inst):
|
|
obj.vnfdId = inst.vnfdId
|
|
if inst_saved.vnfProvider != inst.vnfProvider:
|
|
obj.vnfProvider = inst.vnfProvider
|
|
if inst_saved.vnfProductName != inst.vnfProductName:
|
|
obj.vnfProductName = inst.vnfProductName
|
|
if inst_saved.vnfSoftwareVersion != inst.vnfSoftwareVersion:
|
|
obj.vnfSoftwareVersion = inst.vnfSoftwareVersion
|
|
if inst_saved.vnfdVersion != inst.vnfdVersion:
|
|
obj.vnfdVersion = inst.vnfdVersion
|
|
|
|
|
|
def _change_vnf_info(lcmocc, inst_saved, inst):
|
|
vnf_info_modify = objects.VnfInfoModificationsV2()
|
|
|
|
# vnfdid is required, don't check the existence of the value.
|
|
if inst_saved.vnfdId != inst.vnfdId:
|
|
_check_modification_inst(vnf_info_modify, inst_saved, inst)
|
|
|
|
attrs = ['vnfInstanceName', 'vnfInstanceDescription',
|
|
'vnfConfigurableProperties', 'metadata', 'extensions']
|
|
for attr in attrs:
|
|
if _check_modification(inst_saved, inst, attr):
|
|
setattr(vnf_info_modify, attr, getattr(inst, attr))
|
|
|
|
if (inst.obj_attr_is_set('vimConnectionInfo') and
|
|
inst_saved.obj_attr_is_set('vimConnectionInfo')):
|
|
inst_viminfo = inst.to_dict()["vimConnectionInfo"]
|
|
inst_saved_viminfo = inst_saved.to_dict()["vimConnectionInfo"]
|
|
if inst_viminfo != inst_saved_viminfo:
|
|
vnf_info_modify.vimConnectionInfo = inst.vimConnectionInfo
|
|
elif (inst.obj_attr_is_set('vimConnectionInfo') and
|
|
not inst_saved.obj_attr_is_set('vimConnectionInfo')):
|
|
vnf_info_modify.vimConnectionInfo = inst.vimConnectionInfo
|
|
|
|
vnfc_info_mod = []
|
|
vnfc_info = []
|
|
if (inst.obj_attr_is_set('instantiatedVnfInfo') and
|
|
inst.instantiatedVnfInfo.obj_attr_is_set('vnfcInfo')):
|
|
vnfc_info = inst.instantiatedVnfInfo.vnfcInfo
|
|
vnfc_info_saved = []
|
|
if (inst_saved.obj_attr_is_set('instantiatedVnfInfo') and
|
|
inst_saved.instantiatedVnfInfo.obj_attr_is_set('vnfcInfo')):
|
|
vnfc_info_saved = inst_saved.instantiatedVnfInfo.vnfcInfo
|
|
|
|
for vnfc in vnfc_info:
|
|
prop_saved = {}
|
|
for vnfc_saved in vnfc_info_saved:
|
|
if vnfc.id == vnfc_saved.id:
|
|
if vnfc_saved.obj_attr_is_set('vnfcConfigurableProperties'):
|
|
prop_saved = vnfc_saved.vnfcConfigurableProperties
|
|
break
|
|
prop = {}
|
|
if vnfc.obj_attr_is_set('vnfcConfigurableProperties'):
|
|
prop = vnfc.vnfcConfigurableProperties
|
|
if prop != prop_saved:
|
|
vnfc_info_mod.append(
|
|
objects.VnfcInfoModificationsV2(
|
|
id=vnfc.id,
|
|
vnfcConfigurableProperties=prop
|
|
)
|
|
)
|
|
if vnfc_info_mod:
|
|
vnf_info_modify.vnfcInfoModifications = vnfc_info_mod
|
|
|
|
lcmocc.changedInfo = vnf_info_modify
|
|
|
|
|
|
def _create_modifications_triggered_by_vnfpkg_change(lcmocc, inst_saved, inst):
|
|
vnfpkg_modifications = objects.ModificationsTriggeredByVnfPkgChangeV2()
|
|
_check_modification_inst(vnfpkg_modifications, inst_saved, inst)
|
|
|
|
attrs = ['vnfConfigurableProperties', 'metadata', 'extensions']
|
|
for attr in attrs:
|
|
if _check_modification(inst_saved, inst, attr):
|
|
setattr(vnfpkg_modifications, attr, getattr(inst, attr))
|
|
|
|
lcmocc.modificationsTriggeredByVnfPkgChange = vnfpkg_modifications
|
|
|
|
|
|
def update_lcmocc(lcmocc, inst_saved, inst):
|
|
# if operation is MODIFY_INFO, make changedInfo of lcmocc.
|
|
# for other operations, make ResourceChanges of lcmocc
|
|
# from instantiatedVnfInfo. In addition if operation is
|
|
# CHANGE_EXT_CONN, make changedExtConnectivity of lcmocc.
|
|
# NOTE: grant related info such as resourceDefinitionId, zoneId
|
|
# and so on are not included in lcmocc since such info are not
|
|
# included in instantiatedVnfInfo.
|
|
|
|
if lcmocc.operation == fields.LcmOperationType.MODIFY_INFO:
|
|
_change_vnf_info(lcmocc, inst_saved, inst)
|
|
return
|
|
|
|
if inst_saved.obj_attr_is_set('instantiatedVnfInfo'):
|
|
inst_info_saved = inst_saved.instantiatedVnfInfo
|
|
else:
|
|
# dummy
|
|
inst_info_saved = objects.VnfInstanceV2_InstantiatedVnfInfo()
|
|
|
|
inst_info = inst.instantiatedVnfInfo
|
|
|
|
# NOTE: objects may be re-created. so compare 'id' instead of object
|
|
# itself.
|
|
def _calc_diff(attr):
|
|
# NOTE: instantiatedVnfInfo object is dict compat
|
|
objs_saved = set()
|
|
if inst_info_saved.obj_attr_is_set(attr):
|
|
objs_saved = {obj.id for obj in inst_info_saved[attr]}
|
|
objs = set()
|
|
if inst_info.obj_attr_is_set(attr):
|
|
objs = {obj.id for obj in inst_info[attr]}
|
|
|
|
# return removed_objs, added_objs, common_objs
|
|
return objs_saved - objs, objs - objs_saved, objs_saved & objs
|
|
|
|
removed_strgs, added_strgs, _ = _calc_diff('virtualStorageResourceInfo')
|
|
affected_strgs = []
|
|
if removed_strgs:
|
|
affected_strgs += [
|
|
_make_affected_strg(strg, 'REMOVED')
|
|
for strg in inst_info_saved.virtualStorageResourceInfo
|
|
if strg.id in removed_strgs
|
|
]
|
|
if added_strgs:
|
|
affected_strgs += [_make_affected_strg(strg, 'ADDED')
|
|
for strg in inst_info.virtualStorageResourceInfo
|
|
if strg.id in added_strgs]
|
|
|
|
removed_vnfcs, added_vnfcs, common_vnfcs = _calc_diff('vnfcResourceInfo')
|
|
affected_vnfcs = []
|
|
if removed_vnfcs:
|
|
affected_vnfcs += [
|
|
_make_affected_vnfc(vnfc, 'REMOVED', removed_strgs)
|
|
for vnfc in inst_info_saved.vnfcResourceInfo
|
|
if vnfc.id in removed_vnfcs
|
|
]
|
|
if added_vnfcs:
|
|
affected_vnfcs += [
|
|
_make_affected_vnfc(vnfc, 'ADDED', added_strgs)
|
|
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
|
|
|
|
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))
|
|
|
|
_create_modifications_triggered_by_vnfpkg_change(
|
|
lcmocc, inst_saved, inst)
|
|
|
|
removed_vls, added_vls, common_vls = _calc_diff(
|
|
'vnfVirtualLinkResourceInfo')
|
|
affected_vls = []
|
|
if removed_vls:
|
|
affected_vls += [_make_affected_vl(vl, 'REMOVED')
|
|
for vl in inst_info_saved.vnfVirtualLinkResourceInfo
|
|
if vl.id in removed_vls]
|
|
if added_vls:
|
|
affected_vls += [_make_affected_vl(vl, 'ADDED')
|
|
for vl in inst_info.vnfVirtualLinkResourceInfo
|
|
if vl.id in added_vls]
|
|
if common_vls:
|
|
affected_vls += _make_affected_vls_link_port_change(
|
|
inst_info_saved.vnfVirtualLinkResourceInfo,
|
|
inst_info.vnfVirtualLinkResourceInfo, common_vls)
|
|
|
|
removed_mgd_vls, added_mgd_vls, common_mgd_vls = _calc_diff(
|
|
'extManagedVirtualLinkInfo')
|
|
if removed_mgd_vls:
|
|
affected_vls += [_make_affected_vl(vl, 'LINK_PORT_REMOVED')
|
|
for vl in inst_info_saved.extManagedVirtualLinkInfo
|
|
if vl.id in removed_mgd_vls]
|
|
if added_mgd_vls:
|
|
affected_vls += [_make_affected_vl(vl, 'LINK_PORT_ADDED')
|
|
for vl in inst_info.extManagedVirtualLinkInfo
|
|
if vl.id in added_mgd_vls]
|
|
if common_mgd_vls:
|
|
affected_vls += _make_affected_vls_link_port_change(
|
|
inst_info_saved.extManagedVirtualLinkInfo,
|
|
inst_info.extManagedVirtualLinkInfo, common_mgd_vls)
|
|
|
|
affected_ext_link_ports = _make_affected_ext_link_ports(
|
|
inst_info_saved, inst_info)
|
|
|
|
if (affected_vnfcs or affected_vls or affected_strgs or
|
|
affected_ext_link_ports):
|
|
change_info = objects.VnfLcmOpOccV2_ResourceChanges()
|
|
if affected_vnfcs:
|
|
change_info.affectedVnfcs = affected_vnfcs
|
|
if affected_vls:
|
|
change_info.affectedVirtualLinks = affected_vls
|
|
if affected_strgs:
|
|
change_info.affectedVirtualStorages = affected_strgs
|
|
if affected_ext_link_ports:
|
|
change_info.affectedExtLinkPorts = affected_ext_link_ports
|
|
lcmocc.resourceChanges = change_info
|
|
|
|
if lcmocc.operation == fields.LcmOperationType.CHANGE_EXT_CONN:
|
|
_, added_ext_vls, common_ext_vls = _calc_diff('extVirtualLinkInfo')
|
|
|
|
def _get_ext_vl(vl_id, vl_array):
|
|
for vl in vl_array:
|
|
if vl.id == vl_id:
|
|
return vl
|
|
|
|
chg_ext_conn = [_get_ext_vl(ext_vl_id, inst_info.extVirtualLinkInfo)
|
|
for ext_vl_id in added_ext_vls]
|
|
|
|
for ext_vl_id in common_ext_vls:
|
|
ext_vl = _get_ext_vl(ext_vl_id, inst_info.extVirtualLinkInfo)
|
|
ext_vl_saved = _get_ext_vl(ext_vl_id,
|
|
inst_info_saved.extVirtualLinkInfo)
|
|
cp_data = []
|
|
if ext_vl.obj_attr_is_set('currentVnfExtCpData'):
|
|
cp_data = sorted(ext_vl.to_dict()['currentVnfExtCpData'],
|
|
key=lambda x: x['cpdId'])
|
|
cp_data_saved = []
|
|
if ext_vl_saved.obj_attr_is_set('currentVnfExtCpData'):
|
|
cp_data_saved = sorted(
|
|
ext_vl_saved.to_dict()['currentVnfExtCpData'],
|
|
key=lambda x: x['cpdId'])
|
|
if cp_data != cp_data_saved:
|
|
chg_ext_conn.append(ext_vl)
|
|
continue
|
|
|
|
# NOTE: For ports created by the heat, the id is not changed if
|
|
# its resourceId is not changed. But for ports given outside the
|
|
# heat, the resourceId may be changed without changing the id,
|
|
# so it is a policy to set changedExtConnectivity when there is
|
|
# a change in "id" or "resourceHandle.resourceId".
|
|
port_ids = set()
|
|
if ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
port_ids = {(port.id, port.resourceHandle.resourceId)
|
|
for port in ext_vl.extLinkPorts}
|
|
port_ids_saved = set()
|
|
if ext_vl_saved.obj_attr_is_set('extLinkPorts'):
|
|
port_ids_saved = {(port.id, port.resourceHandle.resourceId)
|
|
for port in ext_vl_saved.extLinkPorts}
|
|
if port_ids != port_ids_saved:
|
|
chg_ext_conn.append(ext_vl)
|
|
|
|
if chg_ext_conn:
|
|
lcmocc.changedExtConnectivity = chg_ext_conn
|
|
|
|
|
|
def get_inst_lcmocc(context, inst):
|
|
lcmoccs = objects.VnfLcmOpOccV2.get_by_filter(
|
|
context, vnfInstanceId=inst.id,
|
|
operationState=fields.LcmOperationStateType.COMPLETED,
|
|
operation=fields.LcmOperationType.INSTANTIATE)
|
|
inst_lcmocc = [inst_lcmocc for inst_lcmocc in lcmoccs
|
|
if inst_lcmocc.startTime ==
|
|
max([lcmocc.startTime for lcmocc in lcmoccs])][0]
|
|
return inst_lcmocc
|
|
|
|
|
|
def get_grant_req_and_grant(context, lcmocc):
|
|
if lcmocc.operation == fields.LcmOperationType.MODIFY_INFO:
|
|
return None, None
|
|
|
|
grant_reqs = objects.GrantRequestV1.get_by_filter(context,
|
|
vnfLcmOpOccId=lcmocc.id)
|
|
grant = objects.GrantV1.get_by_id(context, lcmocc.grantId)
|
|
if not grant_reqs or grant is None:
|
|
raise sol_ex.GrantRequestOrGrantNotFound(lcmocc_id=lcmocc.id)
|
|
|
|
# len(grant_reqs) == 1 because vnfLcmOpOccId is primary key.
|
|
return grant_reqs[0], grant
|
|
|
|
|
|
def is_lcmocc_failure_status(context, inst_id):
|
|
inst_lcmoccs = objects.VnfLcmOpOccV2.get_by_filter(
|
|
context, vnfInstanceId=inst_id)
|
|
failed_temp_lcmoccs = [
|
|
lcmocc for lcmocc in inst_lcmoccs
|
|
if lcmocc.operationState == fields.LcmOperationStateType.FAILED_TEMP]
|
|
failed_lcmocc = [
|
|
latest_lcmocc for latest_lcmocc in inst_lcmoccs
|
|
if latest_lcmocc.startTime == max(
|
|
[lcmocc.startTime for lcmocc in inst_lcmoccs])]
|
|
|
|
if failed_temp_lcmoccs or (failed_lcmocc[0].operationState ==
|
|
fields.LcmOperationStateType.FAILED):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def check_lcmocc_in_progress(context, inst_id):
|
|
# if the controller or conductor executes an operation for the vnf
|
|
# instance (i.e. operationState is ...ING), other operation for
|
|
# the same vnf instance is excluded by the coordinator.
|
|
# check here is existence of lcmocc for the vnf instance with
|
|
# FAILED_TEMP operationState.
|
|
lcmoccs = objects.VnfLcmOpOccV2.get_by_filter(
|
|
context, vnfInstanceId=inst_id,
|
|
operationState=fields.LcmOperationStateType.FAILED_TEMP)
|
|
if lcmoccs:
|
|
raise sol_ex.OtherOperationInProgress(inst_id=inst_id)
|
|
|
|
|
|
def update_lcmocc_status(lcmocc, op_state):
|
|
lcmocc.operationState = op_state
|
|
lcmocc.stateEnteredTime = datetime.utcnow()
|