209 lines
7.8 KiB
Python
209 lines
7.8 KiB
Python
# 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.
|
|
|
|
"""Message Resource, Action, Detail and user visible message.
|
|
|
|
Use Resource, Action and Detail's combination to indicate the Event
|
|
in the format of:
|
|
|
|
EVENT: VOLUME_RESOURCE_ACTION_DETAIL
|
|
|
|
Also, use exception-to-detail mapping to decrease the workload of
|
|
classifying event in cinder's task code.
|
|
"""
|
|
|
|
from cinder.i18n import _
|
|
|
|
|
|
class Resource(object):
|
|
|
|
VOLUME = 'VOLUME'
|
|
VOLUME_SNAPSHOT = 'VOLUME_SNAPSHOT'
|
|
VOLUME_BACKUP = 'VOLUME_BACKUP'
|
|
|
|
|
|
class Action(object):
|
|
|
|
SCHEDULE_ALLOCATE_VOLUME = ('001', _('schedule allocate volume'))
|
|
ATTACH_VOLUME = ('002', _('attach volume'))
|
|
COPY_VOLUME_TO_IMAGE = ('003', _('copy volume to image'))
|
|
UPDATE_ATTACHMENT = ('004', _('update attachment'))
|
|
COPY_IMAGE_TO_VOLUME = ('005', _('copy image to volume'))
|
|
UNMANAGE_VOLUME = ('006', _('unmanage volume'))
|
|
EXTEND_VOLUME = ('007', _('extend volume'))
|
|
CREATE_VOLUME_FROM_BACKEND = ('008',
|
|
_('create volume from backend storage'))
|
|
SNAPSHOT_CREATE = ('009', _('create snapshot'))
|
|
SNAPSHOT_DELETE = ('010', _('delete snapshot'))
|
|
SNAPSHOT_UPDATE = ('011', _('update snapshot'))
|
|
SNAPSHOT_METADATA_UPDATE = ('012', _('update snapshot metadata'))
|
|
BACKUP_CREATE = ('013', _('create backup'))
|
|
BACKUP_DELETE = ('014', _('delete backup'))
|
|
BACKUP_RESTORE = ('015', _('restore backup'))
|
|
REIMAGE_VOLUME = ('016', _('reimage volume'))
|
|
|
|
ALL = (SCHEDULE_ALLOCATE_VOLUME,
|
|
ATTACH_VOLUME,
|
|
COPY_VOLUME_TO_IMAGE,
|
|
UPDATE_ATTACHMENT,
|
|
COPY_IMAGE_TO_VOLUME,
|
|
UNMANAGE_VOLUME,
|
|
EXTEND_VOLUME,
|
|
CREATE_VOLUME_FROM_BACKEND,
|
|
SNAPSHOT_CREATE,
|
|
SNAPSHOT_DELETE,
|
|
SNAPSHOT_UPDATE,
|
|
SNAPSHOT_METADATA_UPDATE,
|
|
BACKUP_CREATE,
|
|
BACKUP_DELETE,
|
|
BACKUP_RESTORE,
|
|
REIMAGE_VOLUME,
|
|
)
|
|
|
|
|
|
class Detail(object):
|
|
|
|
UNKNOWN_ERROR = ('001', _('An unknown error occurred.'))
|
|
DRIVER_NOT_INITIALIZED = ('002',
|
|
_('Driver is not initialized at present.'))
|
|
NO_BACKEND_AVAILABLE = ('003',
|
|
_('Could not find any available '
|
|
'weighted backend.'))
|
|
FAILED_TO_UPLOAD_VOLUME = ('004',
|
|
_("Failed to upload volume to image "
|
|
"at backend."))
|
|
VOLUME_ATTACH_MODE_INVALID = ('005',
|
|
_("Volume's attach mode is invalid."))
|
|
QUOTA_EXCEED = ('006',
|
|
_("Not enough quota resource for operation."))
|
|
NOT_ENOUGH_SPACE_FOR_IMAGE = ('007',
|
|
_("Image used for creating volume exceeds "
|
|
"available space."))
|
|
UNMANAGE_ENC_NOT_SUPPORTED = (
|
|
'008',
|
|
_("Unmanaging encrypted volumes is not supported."))
|
|
NOTIFY_COMPUTE_SERVICE_FAILED = (
|
|
'009',
|
|
_("Compute service failed to extend volume."))
|
|
DRIVER_FAILED_EXTEND = (
|
|
'010',
|
|
_("Volume Driver failed to extend volume."))
|
|
SIGNATURE_VERIFICATION_FAILED = (
|
|
'011',
|
|
_("Image signature verification failed."))
|
|
DRIVER_FAILED_CREATE = (
|
|
'012',
|
|
_('Driver failed to create the volume.'))
|
|
SNAPSHOT_CREATE_ERROR = ('013', _("Snapshot failed to create."))
|
|
SNAPSHOT_UPDATE_METADATA_FAILED = (
|
|
'014',
|
|
_("Volume snapshot update metadata failed."))
|
|
SNAPSHOT_IS_BUSY = ('015', _("Snapshot is busy."))
|
|
SNAPSHOT_DELETE_ERROR = ('016', _("Snapshot failed to delete."))
|
|
BACKUP_INVALID_STATE = ('017', _("Backup status is invalid."))
|
|
BACKUP_SERVICE_DOWN = ('018', _("Backup service is down."))
|
|
BACKUP_CREATE_DEVICE_ERROR = (
|
|
'019', _("Failed to get backup device from the volume service."))
|
|
BACKUP_CREATE_DRIVER_ERROR = (
|
|
'020', ("Backup driver failed to create backup."))
|
|
ATTACH_ERROR = ('021', _("Failed to attach volume."))
|
|
DETACH_ERROR = ('022', _("Failed to detach volume."))
|
|
BACKUP_CREATE_CLEANUP_ERROR = (
|
|
'023', _("Cleanup of temporary volume/snapshot failed."))
|
|
BACKUP_SCHEDULE_ERROR = (
|
|
'024',
|
|
("Backup failed to schedule. Service not found for creating backup."))
|
|
BACKUP_DELETE_DRIVER_ERROR = (
|
|
'025', _("Backup driver failed to delete backup."))
|
|
BACKUP_RESTORE_ERROR = (
|
|
'026', _("Backup driver failed to restore backup."))
|
|
VOLUME_INVALID_STATE = ('027', _("Volume status is invalid."))
|
|
REIMAGE_VOLUME_FAILED = (
|
|
'028',
|
|
_("Compute service failed to reimage volume."))
|
|
|
|
ALL = (UNKNOWN_ERROR,
|
|
DRIVER_NOT_INITIALIZED,
|
|
NO_BACKEND_AVAILABLE,
|
|
FAILED_TO_UPLOAD_VOLUME,
|
|
VOLUME_ATTACH_MODE_INVALID,
|
|
QUOTA_EXCEED,
|
|
NOT_ENOUGH_SPACE_FOR_IMAGE,
|
|
UNMANAGE_ENC_NOT_SUPPORTED,
|
|
NOTIFY_COMPUTE_SERVICE_FAILED,
|
|
DRIVER_FAILED_EXTEND,
|
|
SIGNATURE_VERIFICATION_FAILED,
|
|
DRIVER_FAILED_CREATE,
|
|
SNAPSHOT_CREATE_ERROR,
|
|
SNAPSHOT_UPDATE_METADATA_FAILED,
|
|
SNAPSHOT_IS_BUSY,
|
|
SNAPSHOT_DELETE_ERROR,
|
|
BACKUP_INVALID_STATE,
|
|
BACKUP_SERVICE_DOWN,
|
|
BACKUP_CREATE_DEVICE_ERROR,
|
|
BACKUP_CREATE_DRIVER_ERROR,
|
|
ATTACH_ERROR,
|
|
DETACH_ERROR,
|
|
BACKUP_CREATE_CLEANUP_ERROR,
|
|
BACKUP_SCHEDULE_ERROR,
|
|
BACKUP_DELETE_DRIVER_ERROR,
|
|
BACKUP_RESTORE_ERROR,
|
|
VOLUME_INVALID_STATE,
|
|
REIMAGE_VOLUME_FAILED,
|
|
)
|
|
|
|
# Exception and detail mappings
|
|
EXCEPTION_DETAIL_MAPPINGS = {
|
|
DRIVER_NOT_INITIALIZED: ['DriverNotInitialized'],
|
|
NO_BACKEND_AVAILABLE: ['NoValidBackend'],
|
|
VOLUME_ATTACH_MODE_INVALID: ['InvalidVolumeAttachMode'],
|
|
QUOTA_EXCEED: ['ImageLimitExceeded',
|
|
'BackupLimitExceeded',
|
|
'SnapshotLimitExceeded'],
|
|
NOT_ENOUGH_SPACE_FOR_IMAGE: ['ImageTooBig'],
|
|
SNAPSHOT_IS_BUSY: ['SnapshotIsBusy'],
|
|
}
|
|
|
|
|
|
def translate_action(action_id):
|
|
action_message = next((action[1] for action in Action.ALL
|
|
if action[0] == action_id), None)
|
|
return action_message or 'unknown action'
|
|
|
|
|
|
def translate_detail(detail_id):
|
|
detail_message = next((action[1] for action in Detail.ALL
|
|
if action[0] == detail_id), None)
|
|
return detail_message or Detail.UNKNOWN_ERROR[1]
|
|
|
|
|
|
def translate_detail_id(exception, detail):
|
|
"""Get a detail_id to use for a message.
|
|
|
|
If exception is in the EXCEPTION_DETAIL_MAPPINGS, returns the detail_id
|
|
of the mapped Detail field. If exception is not in the mapping or is None,
|
|
returns the detail_id of the passed-in Detail field. Otherwise, returns
|
|
the detail_id of Detail.UNKNOWN_ERROR.
|
|
|
|
:param exception: an Exception (or None)
|
|
:param detail: a message_field.Detail field (or None)
|
|
:returns: string
|
|
:returns: the detail_id of a message_field.Detail field
|
|
"""
|
|
if exception is not None and isinstance(exception, Exception):
|
|
for key, value in Detail.EXCEPTION_DETAIL_MAPPINGS.items():
|
|
if exception.__class__.__name__ in value:
|
|
return key[0]
|
|
if detail in Detail.ALL:
|
|
return detail[0]
|
|
return Detail.UNKNOWN_ERROR[0]
|