tacker/tacker/objects/fields.py
Hiromu Asahina d40de6c71e Fix LCM failure
In current implementation, if the tacker servers go down during LCM
operation, the operation state will be fixed to `PROCESSING` even after
servers restart. Once this problem happens, users cannot change the
operation state with APIs, which means users have to change the state by
updating DB directly.

This patch fixes this problem by adding a `/vnf_lcm_op_occs/{id}/cancel`
endpoint according to ETSI NFV SOL003 [1]. Users can change the state of
LCM operations in `PROCESSING` to `FAILED_TEMP` with this API.

Note that currently the cancel API support only a transition from
PROCESSING -> FAILED_TEMP (i.e., transitions from ROLLING_BACK and
STARTING are not supported)

In addition, as the current ``_get_affected_resources`` doesn't work
correctly when there are no updated resources, this patch modify
``utils.py`` [2] to fix it and update the tests [3] depending on
``utils.py``.

[1] https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.05.01_60/gs_NFV-SOL003v030501p.pdf
[2] tacker/vnflcm/utils.py
[3] tacker/tests/unit/conductor/test_conductor_server.py

Change-Id: I54aa967be7903c064433f01adf0f99074577a8da
Closes-bug: #1924917
Signed-off-by: Hiromu Asahina <hiromu.asahina.az@hco.ntt.co.jp>
2022-02-15 19:52:59 +09:00

296 lines
6.7 KiB
Python

# Copyright 2018 NTT Data.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from oslo_versionedobjects import fields
# Import fields from oslo.versionedobjects
StringField = fields.StringField
ListOfObjectsField = fields.ListOfObjectsField
ListOfStringsField = fields.ListOfStringsField
DictOfStringsField = fields.DictOfStringsField
DictOfNullableStringsField = fields.DictOfNullableStringsField
DateTimeField = fields.DateTimeField
BooleanField = fields.BooleanField
BaseEnumField = fields.BaseEnumField
Enum = fields.Enum
ObjectField = fields.ObjectField
IntegerField = fields.IntegerField
FieldType = fields.FieldType
class BaseTackerEnum(Enum):
def __init__(self):
super(BaseTackerEnum, self).__init__(valid_values=self.__class__.ALL)
class ContainerFormat(BaseTackerEnum):
AKI = 'AKI'
AMI = 'AMI'
ARI = 'ARI'
BARE = 'BARE'
DOCKER = 'DOCKER'
OVA = 'OVA'
OVF = 'OVF'
ALL = (AKI, AMI, ARI, BARE, DOCKER, OVA, OVF)
class ContainerFormatFields(BaseEnumField):
AUTO_TYPE = ContainerFormat()
class DiskFormat(BaseTackerEnum):
AKI = 'AKI'
AMI = 'AMI'
ARI = 'ARI'
ISO = 'ISO'
QCOW2 = 'QCOW2'
RAW = 'RAW'
VDI = 'VDI'
VHD = 'VHD'
VHDX = 'VHDX'
VMDK = 'VMDK'
ALL = (AKI, AMI, ARI, ISO, QCOW2, RAW, VDI, VHD, VHDX, VMDK)
class DiskFormatFields(BaseEnumField):
AUTO_TYPE = DiskFormat()
class PackageOnboardingStateType(BaseTackerEnum):
CREATED = 'CREATED'
UPLOADING = 'UPLOADING'
PROCESSING = 'PROCESSING'
ONBOARDED = 'ONBOARDED'
ALL = (CREATED, UPLOADING, PROCESSING, ONBOARDED)
class PackageOnboardingStateTypeField(BaseEnumField):
AUTO_TYPE = PackageOnboardingStateType()
class PackageOperationalStateType(BaseTackerEnum):
ENABLED = 'ENABLED'
DISABLED = 'DISABLED'
ALL = (ENABLED, DISABLED)
class PackageOperationalStateTypeField(BaseEnumField):
AUTO_TYPE = PackageOperationalStateType()
class PackageUsageStateType(BaseTackerEnum):
IN_USE = 'IN_USE'
NOT_IN_USE = 'NOT_IN_USE'
ALL = (IN_USE, NOT_IN_USE)
class PackageUsageStateTypeField(BaseEnumField):
AUTO_TYPE = PackageUsageStateType()
class DictOfNullableField(fields.AutoTypedField):
AUTO_TYPE = fields.Dict(fields.FieldType(), nullable=True)
class UUID(fields.UUID):
def coerce(self, obj, attr, value):
uuid.UUID(str(value))
return str(value)
class UUIDField(fields.AutoTypedField):
AUTO_TYPE = UUID()
class VnfInstanceState(BaseTackerEnum):
INSTANTIATED = 'INSTANTIATED'
NOT_INSTANTIATED = 'NOT_INSTANTIATED'
ALL = (INSTANTIATED, NOT_INSTANTIATED)
class VnfInstanceStateField(BaseEnumField):
AUTO_TYPE = VnfInstanceState()
class VnfInstanceTaskState(BaseTackerEnum):
INSTANTIATING = 'INSTANTIATING'
HEALING = 'HEALING'
TERMINATING = 'TERMINATING'
SCALING = 'SCALING'
ERROR = 'ERROR'
ALL = (INSTANTIATING, HEALING, TERMINATING, SCALING, ERROR)
class VnfInstanceTaskStateField(BaseEnumField):
AUTO_TYPE = VnfInstanceTaskState()
class VnfOperationalStateType(BaseTackerEnum):
STARTED = 'STARTED'
STOPPED = 'STOPPED'
ALL = (STARTED, STOPPED)
class VnfOperationalStateTypeField(BaseEnumField):
AUTO_TYPE = VnfOperationalStateType()
class IpAddressType(BaseTackerEnum):
IPV4 = 'IPV4'
IPV6 = 'IPV6'
ALL = (IPV4, IPV6)
class IpAddressTypeField(BaseEnumField):
AUTO_TYPE = IpAddressType()
class VnfInstanceTerminationType(BaseTackerEnum):
FORCEFUL = 'FORCEFUL'
GRACEFUL = 'GRACEFUL'
ALL = (FORCEFUL, GRACEFUL)
class VnfInstanceTerminationTypeField(BaseEnumField):
AUTO_TYPE = VnfInstanceTerminationType()
# SOL003 5.5.4.6 Enumeration: CancelModeType
class VnfInstanceCancelModeType(BaseTackerEnum):
FORCEFUL = 'FORCEFUL'
GRACEFUL = 'GRACEFUL'
ALL = (FORCEFUL, GRACEFUL)
class VnfInstanceCancelTypeField(BaseEnumField):
AUTO_TYPE = VnfInstanceCancelModeType()
class VnfcState(BaseTackerEnum):
STARTED = 'STARTED'
STOPPED = 'STOPPED'
ALL = (STARTED, STOPPED)
class InstanceOperationalState(BaseTackerEnum):
STARTING = 'STARTING'
PROCESSING = 'PROCESSING'
COMPLETED = 'COMPLETED'
FAILED_TEMP = 'FAILED_TEMP'
ROLLING_BACK = 'ROLLING_BACK'
ROLLED_BACK = 'ROLLED_BACK'
ALL = (STARTING, PROCESSING, COMPLETED, FAILED_TEMP,
ROLLING_BACK, ROLLED_BACK)
class InstanceOperationalStateField(BaseEnumField):
AUTO_TYPE = InstanceOperationalState()
class InstanceOperation(BaseTackerEnum):
INSTANTIATE = 'INSTANTIATE'
SCALE = 'SCALE'
TERMINATE = 'TERMINATE'
HEAL = 'HEAL'
MODIFY_INFO = 'MODIFY_INFO'
ALL = (INSTANTIATE, SCALE,
TERMINATE, HEAL, MODIFY_INFO)
class InstanceOperationField(BaseEnumField):
AUTO_TYPE = InstanceOperation()
class LcmOccsOperationState(BaseTackerEnum):
STARTING = 'STARTING'
PROCESSING = 'PROCESSING'
COMPLETED = 'COMPLETED'
FAILED_TEMP = 'FAILED_TEMP'
FAILED = 'FAILED'
ALL = (STARTING, PROCESSING, COMPLETED, FAILED_TEMP, FAILED)
class LcmOccsOperationType(BaseTackerEnum):
INSTANTIATE = 'INSTANTIATE'
TERMINATE = 'TERMINATE'
HEAL = 'HEAL'
SCALE = 'SCALE'
CHANGE_EXT_CONN = 'CHANGE_EXT_CONN'
ALL = (INSTANTIATE, TERMINATE, HEAL, SCALE, CHANGE_EXT_CONN)
class LcmOccsNotificationStatus(BaseTackerEnum):
START = 'START'
RESULT = 'RESULT'
ALL = (START, RESULT)
class ResourceChangeType(BaseTackerEnum):
ADDED = 'ADDED'
REMOVED = 'REMOVED'
MODIFIED = 'MODIFIED'
TEMPORARY = 'TEMPORARY'
ALL = (ADDED, REMOVED, MODIFIED, TEMPORARY)
class LcmOccsNotificationType(BaseTackerEnum):
VNF_OP_OCC_NOTIFICATION = 'VnfLcmOperationOccurrenceNotification'
VNF_ID_CREATION_NOTIFICATION = 'VnfIdentifierCreationNotification'
ALL = (VNF_OP_OCC_NOTIFICATION)
class VnfStatus(BaseTackerEnum):
ACTIVE = 'ACTIVE'
INACTIVE = 'INACTIVE'
ALL = (ACTIVE, INACTIVE)
class InstanceOperation(BaseTackerEnum):
MODIFY_INFO = 'MODIFY_INFO'
class ErrorPoint(BaseTackerEnum):
INITIAL = 0
NOTIFY_PROCESSING = 1
VNF_CONFIG_START = 2
PRE_VIM_CONTROL = 3
POST_VIM_CONTROL = 4
INTERNAL_PROCESSING = 5
VNF_CONFIG_END = 6
NOTIFY_COMPLETED = 7