From 253af3e94b5077b0236ef1d70714caf56456ddbc Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 1 Aug 2019 14:41:47 +0800 Subject: [PATCH 01/18] Trivial: Added new types of errors to xcli --- pyxcli/errors.py | 895 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 890 insertions(+), 5 deletions(-) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 9813595..79671e9 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -131,12 +131,10 @@ class CommandFailedInternalError(CommandExecutionError): class MCLTimeoutError(CommandFailedRuntimeError): pass - @CommandExecutionError.register("VOLUME_IS_MASTER") class VolumeMasterError(CommandFailedRuntimeError): pass - @CommandExecutionError.register("PARTIAL_SUCCESS") class PartialSuccessError(CommandFailedRuntimeError): pass @@ -713,12 +711,899 @@ class VolumeIsSlave(CommandFailedRuntimeError): pass -@CommandExecutionError.register( - "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") -class StorageObjectIsNotInDomain(CommandFailedRuntimeError): +@CommandExecutionError.register("MULTISITE_STANDBY_RELATION_ALREADY_DEFINED") +class StandbyAlreadyDefined(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_BAD_TARGET") +class ConsGroupBadTarget(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_HA_ACTIVATION_MISMATCH") +class ConsGroupHaActivationMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_HA_ROLE_MISMATCH") +class ConsGroupHaRoleMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_HA_TARGET_MISMATCH") +class ConsGroupHaTargetMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_IS_NOT_HA") +class ConsGroupIsNotHa(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_IS_NOT_MULTISITE") +class ConsGroupIsNotMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_MEMBER_VOL_IS_MISSING_A_RELATION") +class ConsGroupMemberVolIsMissingARelation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_MIRROR_OR_HA_TYPE_MISMATCH") +class ConsGroupMirrorOrHaTypeMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_MIRROR_ROLE_MISMATCH") +class ConsGroupMirrorRoleMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_MIRROR_SCHEDULE_MISMATCH") +class ConsGroupMirrorScheduleMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("CONS_GROUP_RELATION_PART_OF_MULTISITE_MISMATCH") +class ConsGroupRelationPartOfMultisiteMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("DATA_REDUCTION_TIER_IS_OFFLINE") +class DataReductionTierIsOffline(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_ASSOCIATED_WITH_MULTISITE") +class HaAssociatedWithMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_BAD_ID") +class HaBadId(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_CONFIGURATION_ERROR") +class HaConfigurationError(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_CONNECTIVITY_NOT_SUFFICIENT") +class HaConnectivityNotSufficient(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_HAS_SYNC_JOB") +class HaHasSyncJob(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_HIGH_AVAILABILITY_DISABLED_IN_VOL") +class HaHighAvailabilityDisabledInVol(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_HIGH_AVAILABILITY_ENABLED_IN_VOL") +class HaHighAvailabilityEnabledInVol(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_INCOMPATIBLE_TARGET_VERSION") +class HaIncompatibleTargetVersion(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_IS_ACTIVE") +class HaIsActive(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_IS_INITIAL") +class HaIsInitial(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_IS_NON_OPERATIONAL") +class HaIsNonOperational(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_IS_NOT_OPERATIONAL") +class HaIsNotOperational(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_IS_NOT_SYNCHRONIZED") +class HaIsNotSynchronized(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_LAST_SYNC_TIMES_DIFFER") +class HaLastSyncTimesDiffer(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_LOCAL_PEER_HAS_NO_QUORUM_WITNESS_CONNECTIVITY") +class HaLocalPeerHasNoQuorumWitnessConnectivity(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_PART_OF_MULTISITE") +class HaPartOfMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_PEER_QUORUM_WITNESS_CONFIGURATION_NOT_VERIFIED") +class HaPeerQuorumWitnessConfigurationNotVerified(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_POSSIBLE_CONS_GROUP_MEMBERSHIP_MISMATCH") +class HaPossibleConsGroupMembershipMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_POSSIBLE_SIZE_MISMATCH") +class HaPossibleSizeMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_RELATION_MASTER_COULD_NOT_UPDATE_QW_AFTER_RETURN_TO_GOOD_STATE") +class HaRelationMasterCouldNotUpdateQwAfterReturnToGoodState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_REMOTE_PEER_HAS_NO_QUORUM_WITNESS_CONNECTIVITY") +class HaRemotePeerHasNoQuorumWitnessConnectivity(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_REMOTE_PEER_QUORUM_WITNESS_CONFIGURATION_NOT_VERIFIED") +class HaRemotePeerQuorumWitnessConfigurationNotVerified(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_REMOTE_TARGET_QUORUM_IS_NOT_ACTIVATED") +class HaRemoteTargetQuorumIsNotActivated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_RETRY_OPERATION") +class HaRetryOperation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_TARGET_QUORUM_IS_NOT_ACTIVATED") +class HaTargetQuorumIsNotActivated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_TARGET_QUORUM_WITNESS_IS_NOT_ACTIVATED") +class HaTargetQuorumWitnessIsNotActivated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HOST_TYPE_IS_NOT_CONFIGURED") +class HostTypeIsNotConfigured(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HYPERSWAP_EXISTS_ON_TARGET") +class HyperswapExistsOnTarget(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HYPERSWAP_EXISTS_ON_VOLUME") +class HyperswapExistsOnVolume(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("LOCAL_AND_REMOTE_VOLUME_NAMES_ARE_DIFFERENT") +class LocalAndRemoteVolumeNamesAreDifferent(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("LOCAL_MAX_HA_REACHED") +class LocalMaxHaReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("LOCAL_PEER_HAS_NO_QUORUM_CONNECTIVITY") +class LocalPeerHasNoQuorumConnectivity(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MASTER_CANNOT_BE_DEMOTED") +class MasterCannotBeDemoted(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MAX_NUM_OF_PROXY_VOLUME_REACHED") +class MaxNumOfProxyVolumeReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MAX_SNAPSHOTS_PER_VOLUME_REACHED") +class MaxSnapshotsPerVolumeReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_CAN_NOT_BE_ACTIVATED") +class MirrorCanNotBeActivated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_CONFIGURATION_ERROR") +class MirrorConfigurationError(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_EXISTS_ON_TARGET") +class MirrorExistsOnTarget(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_HAS_NO_SYNCHED_SNAPSHOT") +class MirrorHasNoSynchedSnapshot(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_IS_STANDBY") +class MirrorIsStandby(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_OF_SAME_TYPE_EXISTS_ON_VOLUME") +class MirrorOfSameTypeExistsOnVolume(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_OR_HYPERSWAP_CONS_GROUP_CANNOT_CONTAIN_MULTISITE_VOLS") +class MirrorOrHyperswapConsGroupCannotContainMultisiteVols(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_PART_OF_MULTISITE") +class MirrorPartOfMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_RETRY_OPERATION") +class MirrorRetryOperation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_SIZE_MISMATCH") +class MirrorSizeMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MIRROR_TYPE_IS_NOT_SYNC") +class MirrorTypeIsNotSync(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ALREADY_DEFINED") +class MultisiteAlreadyDefined(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ASYNC_MIRROR_IS_ACTIVE") +class MultisiteAsyncMirrorIsActive(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ASYNC_MIRROR_IS_NOT_CONNECTED") +class MultisiteAsyncMirrorIsNotConnected(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CANNOT_CONTAIN_SYNC_MIRROR") +class MultisiteCannotContainSyncMirror(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CG_ADD_VOL_FAILED_TO_ROLLBACK_MANUAL_CLEANUP_REQUIRED") +class MultisiteCgAddVolFailedToRollbackManualCleanupRequired(CommandFailedRuntimeError): pass +@CommandExecutionError.register("MULTISITE_CONS_GROUP_CANNOT_CONTAIN_NON_MULTISITEED_VOLS") +class MultisiteConsGroupCannotContainNonMultisiteedVols(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CONS_GROUP_MEMBERSHIP_MISMATCH") +class MultisiteConsGroupMembershipMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CONS_GROUP_MEMBER_VOL_IS_MISSING_A_RELATION") +class MultisiteConsGroupMemberVolIsMissingARelation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CONS_GROUP_ROLE_IS_NOT_MASTER") +class MultisiteConsGroupRoleIsNotMaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_CONS_GROUP_STANDBY_CONFIGURATION_MISMATCH") +class MultisiteConsGroupStandbyConfigurationMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_DEFINE_FAILED_TO_ROLLBACK_MANUAL_CLEANUP_REQUIRED") +class MultisiteDefineFailedToRollbackManualCleanupRequired(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_DELETE_PARTIAL_FAILURE_MANUAL_CLEANUP_REQUIRED") +class MultisiteDeletePartialFailureManualCleanupRequired(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INCOMPATIBLE_TARGET_VERSION") +class MultisiteIncompatibleTargetVersion(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INIT_RELATION_BAD_UID") +class MultisiteInitRelationBadUid(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INVALID_MASTER_LOOPBACK_CONFIGURATION") +class MultisiteInvalidMasterLoopbackConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INVALID_MASTER_SLAVE_TARGET_CONNECTIVITY") +class MultisiteInvalidMasterSlaveTargetConnectivity(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INVALID_MASTER_SMASTER_TARGET_CONNECTIVITY") +class MultisiteInvalidMasterSmasterTargetConnectivity(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INVALID_SLAVE_LOOPBACK_CONFIGURATION") +class MultisiteInvalidSlaveLoopbackConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_INVALID_SMASTER_LOOPBACK_CONFIGURATION") +class MultisiteInvalidSmasterLoopbackConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_IS_PATIALY_DEFINED") +class MultisiteIsPatialyDefined(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_CAN_ONLY_BE_CHANGED_TO_SLAVE") +class MultisiteMasterCanOnlyBeChangedToSlave(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_CAN_ONLY_BE_CHANGED_TO_SMASTER") +class MultisiteMasterCanOnlyBeChangedToSmaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_INVALID_CONFIGURATION") +class MultisiteMasterInvalidConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_INVALID_RELATION_STATE") +class MultisiteMasterInvalidRelationState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_SLAVE_INCONSISTENT_LRS_CONFIGURATION") +class MultisiteMasterSlaveInconsistentLrsConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_MASTER_SMASTER_CLOCK_SKEW_TOO_BIG") +class MultisiteMasterSmasterClockSkewTooBig(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_NOT_OPERATIONAL") +class MultisiteNotOperational(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_MASTER_LIMIT_REACHED") +class MultisiteNumOfMultisitesOnMasterLimitReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_SLAVE_LIMIT_REACHED") +class MultisiteNumOfMultisitesOnSlaveLimitReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_SMASTER_LIMIT_REACHED") +class MultisiteNumOfMultisitesOnSmasterLimitReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ROLE_IS_NOT_MASTER") +class MultisiteRoleIsNotMaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ROLE_IS_NOT_SMASTER") +class MultisiteRoleIsNotSmaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_ROLE_IS_STANDALONE_MASTER") +class MultisiteRoleIsStandaloneMaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_CAN_ONLY_BE_CHANGED_TO_MASTER") +class MultisiteSlaveCanOnlyBeChangedToMaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_HAS_MORE_RECENT_DATA") +class MultisiteSlaveHasMoreRecentData(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_INCOMPATIBLE_VERSION") +class MultisiteSlaveIncompatibleVersion(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_CONFIGURATION") +class MultisiteSlaveInvalidConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_MIRROR_STATE") +class MultisiteSlaveInvalidMirrorState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_RELATION_STATE") +class MultisiteSlaveInvalidRelationState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_STANDBY_CONFIGURATION") +class MultisiteSlaveInvalidStandbyConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_MASTER_RELATION_IS_MISSING") +class MultisiteSlaveMasterRelationIsMissing(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_MASTER_TARGET_MISMATCH") +class MultisiteSlaveMasterTargetMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_SMASTER_TARGET_MISMATCH") +class MultisiteSlaveSmasterTargetMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SLAVE_TARGET_NOT_CONNECTED") +class MultisiteSlaveTargetNotConnected(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_CAN_ONLY_BE_CHANGED_TO_MASTER") +class MultisiteSmasterCanOnlyBeChangedToMaster(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_HAS_NO_SYNCHED_SNAPSHOT") +class MultisiteSmasterHasNoSynchedSnapshot(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_INCOMPATIBLE_VERSION") +class MultisiteSmasterIncompatibleVersion(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_INVALID_CONFIGURATION") +class MultisiteSmasterInvalidConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_INVALID_MIRROR_STATE") +class MultisiteSmasterInvalidMirrorState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_INVALID_RELATION_STATE") +class MultisiteSmasterInvalidRelationState(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_INVALID_STANDBY_CONFIGURATION") +class MultisiteSmasterInvalidStandbyConfiguration(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_MASTER_RELATION_IS_MISSING") +class MultisiteSmasterMasterRelationIsMissing(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_MASTER_TARGET_MISMATCH") +class MultisiteSmasterMasterTargetMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_SLAVE_TARGET_MISMATCH") +class MultisiteSmasterSlaveTargetMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SMASTER_TARGET_NOT_CONNECTED") +class MultisiteSmasterTargetNotConnected(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_SNAPSHOT_MIRROR_NOT_SUPPORTED") +class MultisiteSnapshotMirrorNotSupported(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_STANDBY_MIRROR_ALREADY_DEFINED") +class MultisiteStandbyMirrorAlreadyDefined(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_STANDBY_MIRROR_IS_NOT_CONNECTED") +class MultisiteStandbyMirrorIsNotConnected(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_STANDBY_MIRROR_NOT_REGISTERED") +class MultisiteStandbyMirrorNotRegistered(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_TOO_MANY_ACTIVE_RELATIONS") +class MultisiteTooManyActiveRelations(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("OPERATION_NOT_ALLOWED_ON_LOOPBACK") +class OperationNotAllowedOnLoopback(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("OVERWRITE_SNAPSHOT_BAD_NAME") +class OverwriteSnapshotBadName(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("QUORUM_WITNESS_BAD_NAME") +class QuorumWitnessBadName(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("QUORUM_WITNESS_CANNOT_BE_ADDED_TO_A_TARGET_OF_THIS_TYPE") +class QuorumWitnessCannotBeAddedToATargetOfThisType(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("QUORUM_WITNESS_IS_NOT_ACTIVATED") +class QuorumWitnessIsNotActivated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("RELATION_RETRY_OPERATION") +class RelationRetryOperation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_ALU_ALREADY_EXISTS") +class RemoteAluAlreadyExists(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_CONS_GROUP_BAD_NAME") +class RemoteConsGroupBadName(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_CONS_GROUP_EMPTY") +class RemoteConsGroupEmpty(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_CONS_GROUP_MISMATCH") +class RemoteConsGroupMismatch(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_CONS_GROUP_NOT_EMPTY") +class RemoteConsGroupNotEmpty(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_DATA_REDUCTION_TIER_IS_OFFLINE") +class RemoteDataReductionTierIsOffline(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_DOMAIN_MAX_VOLUMES_REACHED") +class RemoteDomainMaxVolumesReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_HA_IS_NOT_ACTIVE") +class RemoteHaIsNotActive(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_HA_IS_STANDBY") +class RemoteHaIsStandby(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAX_HA_REACHED") +class RemoteMaxHaReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAX_METADATA_OBJECTS_REACHED") +class RemoteMaxMetadataObjectsReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAX_NUM_OF_PROXY_VOLUME_REACHED") +class RemoteMaxNumOfProxyVolumeReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAX_SNAPSHOTS_FOR_VOLUME_REACHED") +class RemoteMaxSnapshotsForVolumeReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAX_SNAPSHOTS_PER_VOLUME_REACHED") +class RemoteMaxSnapshotsPerVolumeReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_ALU_ALREADY_EXISTSREMOTE_MAX_VOLUMES_REACHED") +class RemoteAluAlreadyExistsremoteMaxVolumesReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MAY_NOT_HAVE_COMPLETED_THE_OPERATION") +class RemoteMayNotHaveCompletedTheOperation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MIRROR_IS_STANDBY") +class RemoteMirrorIsStandby(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_OVERWRITE_SNAPSHOT_GROUP_DOES_NOT_BELONG_TO_GIVEN_GROUP") +class RemoteOverwriteSnapshotGroupDoesNotBelongToGivenGroup(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_POOL_SNAPSHOT_LIMIT_REACHED") +class RemotePoolSnapshotLimitReached(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SNAPSHOT_BAD_PREFIX") +class RemoteSnapshotBadPrefix(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SNAPSHOT_GROUP_ILLEGAL_PRIORITY") +class RemoteSnapshotGroupIllegalPriority(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SNAPSHOT_GROUP_NAME_EXISTS") +class RemoteSnapshotGroupNameExists(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SNAPSHOT_ILLEGAL_PRIORITY") +class RemoteSnapshotIllegalPriority(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SNAPSHOT_NAME_EXISTS") +class RemoteSnapshotNameExists(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_SYSTEM_OUT_OF_PHYSICAL_SPACE") +class RemoteSystemOutOfPhysicalSpace(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_TARGET_HAS_NO_QUORUM_WITNESS") +class RemoteTargetHasNoQuorumWitness(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_VOLUME_IS_SNAPSHOT") +class RemoteVolumeIsSnapshot(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SLAVE_VOLUME_IS_MAPPED") +class SlaveVolumeIsMapped(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_CAN_NOT_BE_CREATED_REMOTE_CONS_GROUP_DEFINITION_CHANGED") +class SnapshotCanNotBeCreatedRemoteConsGroupDefinitionChanged(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_CAN_NOT_BE_CREATED_REMOTE_CONS_GROUP_IO_IS_NOT_PAUSED") +class SnapshotCanNotBeCreatedRemoteConsGroupIoIsNotPaused(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_GROUP_ILLEGAL_PRIORITY") +class SnapshotGroupIllegalPriority(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_GROUP_IS_INTERNAL") +class SnapshotGroupIsInternal(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_ILLEGAL_PRIORITY") +class SnapshotIllegalPriority(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_IS_INTERNAL") +class SnapshotIsInternal(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SNAPSHOT_IS_PART_OF_SNAPSHOT_GROUP") +class SnapshotIsPartOfSnapshotGroup(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("SYSTEM_OUT_OF_PHYSICAL_SPACE") +class SystemOutOfPhysicalSpace(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_BAD_NAME") +class TargetBadName(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_BAD_TYPE") +class TargetBadType(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_HAS_A_QUORUM_WITNESS") +class TargetHasAQuorumWitness(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_HAS_ENABLED_HA") +class TargetHasEnabledHa(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_HAS_NO_QUORUM_WITNESS") +class TargetHasNoQuorumWitness(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_PEER_NOT_HEALTHY") +class TargetPeerNotHealthy(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("TARGET_VOLUME_HAS_OLVM") +class TargetVolumeHasOlvm(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_BAD_PREFIX") +class VolumeBadPrefix(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_BELONGS_TO_HA_CONS_GROUP") +class VolumeBelongsToHaConsGroup(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_BELONGS_TO_MULTISITE_CONS_GROUP") +class VolumeBelongsToMultisiteConsGroup(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_HAS_HA") +class VolumeHasHa(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_HAS_MULTIPLE_MIRRORS") +class VolumeHasMultipleMirrors(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_HAS_STANDBY_SNAPSHOTS") +class VolumeHasStandbySnapshots(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_IS_NOT_CONSISTENT_SLAVE") +class VolumeIsNotConsistentSlave(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_IS_NOT_HA") +class VolumeIsNotHa(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_IS_NOT_MULTISITE") +class VolumeIsNotMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_RELATION_IN_CG_CAN_NOT_BE_CREATED") +class VolumeRelationInCgCanNotBeCreated(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("VOLUME_TARGET_MISMATCH") +class VolumeTargetMismatch(CommandFailedRuntimeError): + pass ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from From 128e5c56c24e4c03dc3e5db23bc8f9d54fb10199 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 1 Aug 2019 16:23:55 +0800 Subject: [PATCH 02/18] Add new parameter to support HyperSwap and multi-site --- pyxcli/mirroring/cg_recovery_manager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyxcli/mirroring/cg_recovery_manager.py b/pyxcli/mirroring/cg_recovery_manager.py index a245611..5f0ee6d 100644 --- a/pyxcli/mirroring/cg_recovery_manager.py +++ b/pyxcli/mirroring/cg_recovery_manager.py @@ -105,7 +105,7 @@ def get_target_group_test_snap_groups(self, group_id, def create_mirror(self, resource_name, target_name, mirror_type, slave_resource_name, rpo=None, remote_rpo=None, schedule=None, remote_schedule=None, - activate_mirror='no'): + activate_mirror='no', part_of_multisite='no'): '''creates a mirror and returns a mirror object. target name must be a valid target from target_list, mirror type must be 'sync' or 'async', @@ -115,7 +115,8 @@ def create_mirror(self, resource_name, target_name, mirror_type, mirror_type, slave_resource_name, rpo=rpo, remote_rpo=remote_rpo, schedule=schedule, remote_schedule=remote_schedule, - activate_mirror=activate_mirror) + activate_mirror=activate_mirror, + part_of_multisite=part_of_multisite) def delete_mirror(self, resource_id): '''delete a mirror by resource_id''' From 1260db9ce98e26c0ce1ffc4b8a2b9c70f06b4ec3 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 1 Aug 2019 16:25:31 +0800 Subject: [PATCH 03/18] Add new parameter to support HyperSwap and multi-site --- pyxcli/mirroring/recovery_manager.py | 42 ++++++++++++++++++---------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/pyxcli/mirroring/recovery_manager.py b/pyxcli/mirroring/recovery_manager.py index d2931c5..f3a2af4 100644 --- a/pyxcli/mirroring/recovery_manager.py +++ b/pyxcli/mirroring/recovery_manager.py @@ -274,25 +274,39 @@ def _create_mirror(self, resource_type, resource_name, target_name, mirror_type, slave_resource_name, create_slave='no', remote_pool=None, rpo=None, remote_rpo=None, schedule=None, remote_schedule=None, - activate_mirror='no'): + activate_mirror='no', part_of_multisite='no'): '''creates a mirror and returns a mirror object. resource_type must be 'vol' or 'cg', target name must be a valid target from target_list, mirror type must be 'sync' or 'async', slave_resource_name would be the slave_vol or slave_cg name''' - - kwargs = { - resource_type: resource_name, - 'target': target_name, - 'type': mirror_type, - 'slave_' + resource_type: slave_resource_name, - 'create_slave': create_slave, - 'remote_pool': remote_pool, - 'rpo': rpo, - 'remote_rpo': remote_rpo, - 'schedule': schedule, - 'remote_schedule': remote_schedule - } + if part_of_multisite == 'yes': + kwargs = { + resource_type: resource_name, + 'target': target_name, + 'type': mirror_type, + 'slave_' + resource_type: slave_resource_name, + 'create_slave': create_slave, + 'remote_pool': remote_pool, + 'rpo': rpo, + 'remote_rpo': remote_rpo, + 'schedule': schedule, + 'remote_schedule': remote_schedule, + 'part_of_multisite': part_of_multisite + } + else: + kwargs = { + resource_type: resource_name, + 'target': target_name, + 'type': mirror_type, + 'slave_' + resource_type: slave_resource_name, + 'create_slave': create_slave, + 'remote_pool': remote_pool, + 'rpo': rpo, + 'remote_rpo': remote_rpo, + 'schedule': schedule, + 'remote_schedule': remote_schedule + } if mirror_type == 'sync': kwargs['type'] = 'sync_best_effort' From e362a796d0b131376e6c511b066ee88c3807f915 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 1 Aug 2019 16:26:19 +0800 Subject: [PATCH 04/18] Add new parameter to support HyperSwap and multi-site --- pyxcli/mirroring/volume_recovery_manager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyxcli/mirroring/volume_recovery_manager.py b/pyxcli/mirroring/volume_recovery_manager.py index bc6ee81..481a882 100644 --- a/pyxcli/mirroring/volume_recovery_manager.py +++ b/pyxcli/mirroring/volume_recovery_manager.py @@ -85,7 +85,8 @@ def _create_and_unlock_snapshot(self, vol, name, test_snapshot_prefix): def create_mirror(self, resource_name, target_name, mirror_type, slave_resource_name, create_slave='no', remote_pool=None, rpo=None, remote_rpo=None, schedule=None, - remote_schedule=None, activate_mirror='no'): + remote_schedule=None, activate_mirror='no', + part_of_multisite='no'): '''creates a mirror and returns a mirror object, target name must be a valid target from target_list, mirror type must be 'sync' or 'async', @@ -97,7 +98,8 @@ def create_mirror(self, resource_name, target_name, mirror_type, remote_pool=remote_pool, rpo=rpo, remote_rpo=remote_rpo, schedule=schedule, remote_schedule=remote_schedule, - activate_mirror=activate_mirror) + activate_mirror=activate_mirror, + part_of_multisite=part_of_multisite) def delete_mirror(self, resource_id): '''delete a mirror by mirror name''' From ccb04319bfd7e27736bf3bd1b1467cd3b6e3c3b9 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Fri, 9 Aug 2019 15:44:35 +0800 Subject: [PATCH 05/18] Remove unnecessary events --- pyxcli/errors.py | 334 +++-------------------------------------------- 1 file changed, 20 insertions(+), 314 deletions(-) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 79671e9..19ccd47 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -131,10 +131,12 @@ class CommandFailedInternalError(CommandExecutionError): class MCLTimeoutError(CommandFailedRuntimeError): pass + @CommandExecutionError.register("VOLUME_IS_MASTER") class VolumeMasterError(CommandFailedRuntimeError): pass + @CommandExecutionError.register("PARTIAL_SUCCESS") class PartialSuccessError(CommandFailedRuntimeError): pass @@ -716,6 +718,12 @@ class StandbyAlreadyDefined(CommandFailedRuntimeError): pass +@CommandExecutionError.register( + "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") +class StorageObjectIsNotInDomain(CommandFailedRuntimeError): + pass + + @CommandExecutionError.register("CONS_GROUP_BAD_TARGET") class ConsGroupBadTarget(CommandFailedRuntimeError): pass @@ -781,6 +789,12 @@ class HaAssociatedWithMultisite(CommandFailedRuntimeError): pass +@CommandExecutionError.register( + "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") +class StorageObjectIsNotInDomain(CommandFailedRuntimeError): + pass + + @CommandExecutionError.register("HA_BAD_ID") class HaBadId(CommandFailedRuntimeError): pass @@ -846,66 +860,16 @@ class HaLastSyncTimesDiffer(CommandFailedRuntimeError): pass -@CommandExecutionError.register("HA_LOCAL_PEER_HAS_NO_QUORUM_WITNESS_CONNECTIVITY") -class HaLocalPeerHasNoQuorumWitnessConnectivity(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("HA_PART_OF_MULTISITE") class HaPartOfMultisite(CommandFailedRuntimeError): pass -@CommandExecutionError.register("HA_PEER_QUORUM_WITNESS_CONFIGURATION_NOT_VERIFIED") -class HaPeerQuorumWitnessConfigurationNotVerified(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_POSSIBLE_CONS_GROUP_MEMBERSHIP_MISMATCH") -class HaPossibleConsGroupMembershipMismatch(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_POSSIBLE_SIZE_MISMATCH") -class HaPossibleSizeMismatch(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_RELATION_MASTER_COULD_NOT_UPDATE_QW_AFTER_RETURN_TO_GOOD_STATE") -class HaRelationMasterCouldNotUpdateQwAfterReturnToGoodState(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_REMOTE_PEER_HAS_NO_QUORUM_WITNESS_CONNECTIVITY") -class HaRemotePeerHasNoQuorumWitnessConnectivity(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_REMOTE_PEER_QUORUM_WITNESS_CONFIGURATION_NOT_VERIFIED") -class HaRemotePeerQuorumWitnessConfigurationNotVerified(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_REMOTE_TARGET_QUORUM_IS_NOT_ACTIVATED") -class HaRemoteTargetQuorumIsNotActivated(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("HA_RETRY_OPERATION") class HaRetryOperation(CommandFailedRuntimeError): pass -@CommandExecutionError.register("HA_TARGET_QUORUM_IS_NOT_ACTIVATED") -class HaTargetQuorumIsNotActivated(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("HA_TARGET_QUORUM_WITNESS_IS_NOT_ACTIVATED") -class HaTargetQuorumWitnessIsNotActivated(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("HOST_TYPE_IS_NOT_CONFIGURED") class HostTypeIsNotConfigured(CommandFailedRuntimeError): pass @@ -981,11 +945,6 @@ class MirrorOfSameTypeExistsOnVolume(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MIRROR_OR_HYPERSWAP_CONS_GROUP_CANNOT_CONTAIN_MULTISITE_VOLS") -class MirrorOrHyperswapConsGroupCannotContainMultisiteVols(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MIRROR_PART_OF_MULTISITE") class MirrorPartOfMultisite(CommandFailedRuntimeError): pass @@ -1021,116 +980,6 @@ class MultisiteAsyncMirrorIsNotConnected(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_CANNOT_CONTAIN_SYNC_MIRROR") -class MultisiteCannotContainSyncMirror(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CG_ADD_VOL_FAILED_TO_ROLLBACK_MANUAL_CLEANUP_REQUIRED") -class MultisiteCgAddVolFailedToRollbackManualCleanupRequired(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CONS_GROUP_CANNOT_CONTAIN_NON_MULTISITEED_VOLS") -class MultisiteConsGroupCannotContainNonMultisiteedVols(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CONS_GROUP_MEMBERSHIP_MISMATCH") -class MultisiteConsGroupMembershipMismatch(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CONS_GROUP_MEMBER_VOL_IS_MISSING_A_RELATION") -class MultisiteConsGroupMemberVolIsMissingARelation(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CONS_GROUP_ROLE_IS_NOT_MASTER") -class MultisiteConsGroupRoleIsNotMaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_CONS_GROUP_STANDBY_CONFIGURATION_MISMATCH") -class MultisiteConsGroupStandbyConfigurationMismatch(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_DEFINE_FAILED_TO_ROLLBACK_MANUAL_CLEANUP_REQUIRED") -class MultisiteDefineFailedToRollbackManualCleanupRequired(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_DELETE_PARTIAL_FAILURE_MANUAL_CLEANUP_REQUIRED") -class MultisiteDeletePartialFailureManualCleanupRequired(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INCOMPATIBLE_TARGET_VERSION") -class MultisiteIncompatibleTargetVersion(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INIT_RELATION_BAD_UID") -class MultisiteInitRelationBadUid(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INVALID_MASTER_LOOPBACK_CONFIGURATION") -class MultisiteInvalidMasterLoopbackConfiguration(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INVALID_MASTER_SLAVE_TARGET_CONNECTIVITY") -class MultisiteInvalidMasterSlaveTargetConnectivity(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INVALID_MASTER_SMASTER_TARGET_CONNECTIVITY") -class MultisiteInvalidMasterSmasterTargetConnectivity(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INVALID_SLAVE_LOOPBACK_CONFIGURATION") -class MultisiteInvalidSlaveLoopbackConfiguration(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_INVALID_SMASTER_LOOPBACK_CONFIGURATION") -class MultisiteInvalidSmasterLoopbackConfiguration(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_IS_PATIALY_DEFINED") -class MultisiteIsPatialyDefined(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_MASTER_CAN_ONLY_BE_CHANGED_TO_SLAVE") -class MultisiteMasterCanOnlyBeChangedToSlave(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_MASTER_CAN_ONLY_BE_CHANGED_TO_SMASTER") -class MultisiteMasterCanOnlyBeChangedToSmaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_MASTER_INVALID_CONFIGURATION") -class MultisiteMasterInvalidConfiguration(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_MASTER_INVALID_RELATION_STATE") -class MultisiteMasterInvalidRelationState(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_MASTER_SLAVE_INCONSISTENT_LRS_CONFIGURATION") -class MultisiteMasterSlaveInconsistentLrsConfiguration(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_MASTER_SMASTER_CLOCK_SKEW_TOO_BIG") class MultisiteMasterSmasterClockSkewTooBig(CommandFailedRuntimeError): pass @@ -1141,71 +990,6 @@ class MultisiteNotOperational(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_MASTER_LIMIT_REACHED") -class MultisiteNumOfMultisitesOnMasterLimitReached(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_SLAVE_LIMIT_REACHED") -class MultisiteNumOfMultisitesOnSlaveLimitReached(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_NUM_OF_MULTISITES_ON_SMASTER_LIMIT_REACHED") -class MultisiteNumOfMultisitesOnSmasterLimitReached(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_ROLE_IS_NOT_MASTER") -class MultisiteRoleIsNotMaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_ROLE_IS_NOT_SMASTER") -class MultisiteRoleIsNotSmaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_ROLE_IS_STANDALONE_MASTER") -class MultisiteRoleIsStandaloneMaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_CAN_ONLY_BE_CHANGED_TO_MASTER") -class MultisiteSlaveCanOnlyBeChangedToMaster(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_HAS_MORE_RECENT_DATA") -class MultisiteSlaveHasMoreRecentData(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_INCOMPATIBLE_VERSION") -class MultisiteSlaveIncompatibleVersion(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_CONFIGURATION") -class MultisiteSlaveInvalidConfiguration(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_MIRROR_STATE") -class MultisiteSlaveInvalidMirrorState(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_RELATION_STATE") -class MultisiteSlaveInvalidRelationState(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("MULTISITE_SLAVE_INVALID_STANDBY_CONFIGURATION") -class MultisiteSlaveInvalidStandbyConfiguration(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_SLAVE_MASTER_RELATION_IS_MISSING") class MultisiteSlaveMasterRelationIsMissing(CommandFailedRuntimeError): pass @@ -1226,21 +1010,11 @@ class MultisiteSlaveTargetNotConnected(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_SMASTER_CAN_ONLY_BE_CHANGED_TO_MASTER") -class MultisiteSmasterCanOnlyBeChangedToMaster(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_SMASTER_HAS_NO_SYNCHED_SNAPSHOT") class MultisiteSmasterHasNoSynchedSnapshot(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_SMASTER_INCOMPATIBLE_VERSION") -class MultisiteSmasterIncompatibleVersion(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_SMASTER_INVALID_CONFIGURATION") class MultisiteSmasterInvalidConfiguration(CommandFailedRuntimeError): pass @@ -1256,11 +1030,6 @@ class MultisiteSmasterInvalidRelationState(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_SMASTER_INVALID_STANDBY_CONFIGURATION") -class MultisiteSmasterInvalidStandbyConfiguration(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_SMASTER_MASTER_RELATION_IS_MISSING") class MultisiteSmasterMasterRelationIsMissing(CommandFailedRuntimeError): pass @@ -1281,11 +1050,6 @@ class MultisiteSmasterTargetNotConnected(CommandFailedRuntimeError): pass -@CommandExecutionError.register("MULTISITE_SNAPSHOT_MIRROR_NOT_SUPPORTED") -class MultisiteSnapshotMirrorNotSupported(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("MULTISITE_STANDBY_MIRROR_ALREADY_DEFINED") class MultisiteStandbyMirrorAlreadyDefined(CommandFailedRuntimeError): pass @@ -1316,31 +1080,11 @@ class OverwriteSnapshotBadName(CommandFailedRuntimeError): pass -@CommandExecutionError.register("QUORUM_WITNESS_BAD_NAME") -class QuorumWitnessBadName(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("QUORUM_WITNESS_CANNOT_BE_ADDED_TO_A_TARGET_OF_THIS_TYPE") -class QuorumWitnessCannotBeAddedToATargetOfThisType(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("QUORUM_WITNESS_IS_NOT_ACTIVATED") -class QuorumWitnessIsNotActivated(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("RELATION_RETRY_OPERATION") class RelationRetryOperation(CommandFailedRuntimeError): pass -@CommandExecutionError.register("REMOTE_ALU_ALREADY_EXISTS") -class RemoteAluAlreadyExists(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("REMOTE_CONS_GROUP_BAD_NAME") class RemoteConsGroupBadName(CommandFailedRuntimeError): pass @@ -1406,11 +1150,6 @@ class RemoteMaxSnapshotsPerVolumeReached(CommandFailedRuntimeError): pass -@CommandExecutionError.register("REMOTE_ALU_ALREADY_EXISTSREMOTE_MAX_VOLUMES_REACHED") -class RemoteAluAlreadyExistsremoteMaxVolumesReached(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("REMOTE_MAY_NOT_HAVE_COMPLETED_THE_OPERATION") class RemoteMayNotHaveCompletedTheOperation(CommandFailedRuntimeError): pass @@ -1421,11 +1160,6 @@ class RemoteMirrorIsStandby(CommandFailedRuntimeError): pass -@CommandExecutionError.register("REMOTE_OVERWRITE_SNAPSHOT_GROUP_DOES_NOT_BELONG_TO_GIVEN_GROUP") -class RemoteOverwriteSnapshotGroupDoesNotBelongToGivenGroup(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("REMOTE_POOL_SNAPSHOT_LIMIT_REACHED") class RemotePoolSnapshotLimitReached(CommandFailedRuntimeError): pass @@ -1476,16 +1210,6 @@ class SlaveVolumeIsMapped(CommandFailedRuntimeError): pass -@CommandExecutionError.register("SNAPSHOT_CAN_NOT_BE_CREATED_REMOTE_CONS_GROUP_DEFINITION_CHANGED") -class SnapshotCanNotBeCreatedRemoteConsGroupDefinitionChanged(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("SNAPSHOT_CAN_NOT_BE_CREATED_REMOTE_CONS_GROUP_IO_IS_NOT_PAUSED") -class SnapshotCanNotBeCreatedRemoteConsGroupIoIsNotPaused(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("SNAPSHOT_GROUP_ILLEGAL_PRIORITY") class SnapshotGroupIllegalPriority(CommandFailedRuntimeError): pass @@ -1526,21 +1250,11 @@ class TargetBadType(CommandFailedRuntimeError): pass -@CommandExecutionError.register("TARGET_HAS_A_QUORUM_WITNESS") -class TargetHasAQuorumWitness(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("TARGET_HAS_ENABLED_HA") class TargetHasEnabledHa(CommandFailedRuntimeError): pass -@CommandExecutionError.register("TARGET_HAS_NO_QUORUM_WITNESS") -class TargetHasNoQuorumWitness(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("TARGET_PEER_NOT_HEALTHY") class TargetPeerNotHealthy(CommandFailedRuntimeError): pass @@ -1556,16 +1270,6 @@ class VolumeBadPrefix(CommandFailedRuntimeError): pass -@CommandExecutionError.register("VOLUME_BELONGS_TO_HA_CONS_GROUP") -class VolumeBelongsToHaConsGroup(CommandFailedRuntimeError): - pass - - -@CommandExecutionError.register("VOLUME_BELONGS_TO_MULTISITE_CONS_GROUP") -class VolumeBelongsToMultisiteConsGroup(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("VOLUME_HAS_HA") class VolumeHasHa(CommandFailedRuntimeError): pass @@ -1596,13 +1300,13 @@ class VolumeIsNotMultisite(CommandFailedRuntimeError): pass -@CommandExecutionError.register("VOLUME_RELATION_IN_CG_CAN_NOT_BE_CREATED") -class VolumeRelationInCgCanNotBeCreated(CommandFailedRuntimeError): +@CommandExecutionError.register("VOLUME_TARGET_MISMATCH") +class VolumeTargetMismatch(CommandFailedRuntimeError): pass -@CommandExecutionError.register("VOLUME_TARGET_MISMATCH") -class VolumeTargetMismatch(CommandFailedRuntimeError): +@CommandExecutionError.register("TARGET_VOLUME_HAS_HA") +class TargetVolumeHasHa(CommandFailedRuntimeError): pass ############################################################################## # CredentialsError @@ -1610,6 +1314,8 @@ class VolumeTargetMismatch(CommandFailedRuntimeError): # CommandExecutionError, so although it is raised by _build_response, # it derives from XCLIError directly ############################################################################## + + @CommandExecutionError.register("LOGIN_FAILURE_USER_FAILED_TO_LOGIN", "USER_NAME_DOES_NOT_EXIST", "DEFAULT_USER_IS_NOT_DEFINED", From d85fdc8a5ff667f05f238da273c671806f68544c Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Fri, 9 Aug 2019 15:45:40 +0800 Subject: [PATCH 06/18] Change the method to handle part_of_multisite param --- pyxcli/mirroring/recovery_manager.py | 44 +++++++++++----------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/pyxcli/mirroring/recovery_manager.py b/pyxcli/mirroring/recovery_manager.py index f3a2af4..99c93e8 100644 --- a/pyxcli/mirroring/recovery_manager.py +++ b/pyxcli/mirroring/recovery_manager.py @@ -280,33 +280,20 @@ def _create_mirror(self, resource_type, resource_name, target_name, target name must be a valid target from target_list, mirror type must be 'sync' or 'async', slave_resource_name would be the slave_vol or slave_cg name''' - if part_of_multisite == 'yes': - kwargs = { - resource_type: resource_name, - 'target': target_name, - 'type': mirror_type, - 'slave_' + resource_type: slave_resource_name, - 'create_slave': create_slave, - 'remote_pool': remote_pool, - 'rpo': rpo, - 'remote_rpo': remote_rpo, - 'schedule': schedule, - 'remote_schedule': remote_schedule, - 'part_of_multisite': part_of_multisite - } - else: - kwargs = { - resource_type: resource_name, - 'target': target_name, - 'type': mirror_type, - 'slave_' + resource_type: slave_resource_name, - 'create_slave': create_slave, - 'remote_pool': remote_pool, - 'rpo': rpo, - 'remote_rpo': remote_rpo, - 'schedule': schedule, - 'remote_schedule': remote_schedule - } + + kwargs = { + resource_type: resource_name, + 'target': target_name, + 'type': mirror_type, + 'slave_' + resource_type: slave_resource_name, + 'create_slave': create_slave, + 'remote_pool': remote_pool, + 'rpo': rpo, + 'remote_rpo': remote_rpo, + 'schedule': schedule, + 'remote_schedule': remote_schedule, + 'part_of_multisite': part_of_multisite + } if mirror_type == 'sync': kwargs['type'] = 'sync_best_effort' @@ -316,6 +303,9 @@ def _create_mirror(self, resource_type, resource_name, target_name, if kwargs['remote_schedule'] is None: kwargs['remote_schedule'] = kwargs['schedule'] + if part_of_multisite == 'no': + kwargs['part_of_multisite'] = None + # avoids a python3 issue of the dict changing # during iteration keys = set(kwargs.keys()).copy() From c91b5cdc51ea6ebeb4f7e28ad08b903652bde59f Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 12 Aug 2019 18:08:19 +0800 Subject: [PATCH 07/18] delete dup TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS --- pyxcli/errors.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 19ccd47..d0947d5 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -789,12 +789,6 @@ class HaAssociatedWithMultisite(CommandFailedRuntimeError): pass -@CommandExecutionError.register( - "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") -class StorageObjectIsNotInDomain(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("HA_BAD_ID") class HaBadId(CommandFailedRuntimeError): pass From d5a72b2dd45b1469638383c44f519bb6fd1f8b97 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 12 Aug 2019 18:10:18 +0800 Subject: [PATCH 08/18] Revert "delete dup TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS" This reverts commit c91b5cdc51ea6ebeb4f7e28ad08b903652bde59f. --- pyxcli/errors.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index d0947d5..19ccd47 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -789,6 +789,12 @@ class HaAssociatedWithMultisite(CommandFailedRuntimeError): pass +@CommandExecutionError.register( + "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") +class StorageObjectIsNotInDomain(CommandFailedRuntimeError): + pass + + @CommandExecutionError.register("HA_BAD_ID") class HaBadId(CommandFailedRuntimeError): pass From 7296f0f257e15b11ffe5e35c0bf979ac82209618 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 12 Aug 2019 18:13:11 +0800 Subject: [PATCH 09/18] delete dup class StorageObjectIsNotInDomain --- pyxcli/errors.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 19ccd47..d0947d5 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -789,12 +789,6 @@ class HaAssociatedWithMultisite(CommandFailedRuntimeError): pass -@CommandExecutionError.register( - "TRNS_MGMT_STATUS_OBJECTS_IN_DIFFERENT_DOMAINS") -class StorageObjectIsNotInDomain(CommandFailedRuntimeError): - pass - - @CommandExecutionError.register("HA_BAD_ID") class HaBadId(CommandFailedRuntimeError): pass From cf407310c08bc4363fbaa31a282672e84486f783 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 12 Aug 2019 18:32:47 +0800 Subject: [PATCH 10/18] fix backwards compatibility issue after adding part_of_multisite --- pyxcli/mirroring/cg_recovery_manager.py | 2 +- pyxcli/mirroring/recovery_manager.py | 5 +---- pyxcli/mirroring/volume_recovery_manager.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pyxcli/mirroring/cg_recovery_manager.py b/pyxcli/mirroring/cg_recovery_manager.py index 5f0ee6d..dc19a67 100644 --- a/pyxcli/mirroring/cg_recovery_manager.py +++ b/pyxcli/mirroring/cg_recovery_manager.py @@ -105,7 +105,7 @@ def get_target_group_test_snap_groups(self, group_id, def create_mirror(self, resource_name, target_name, mirror_type, slave_resource_name, rpo=None, remote_rpo=None, schedule=None, remote_schedule=None, - activate_mirror='no', part_of_multisite='no'): + activate_mirror='no', part_of_multisite=None): '''creates a mirror and returns a mirror object. target name must be a valid target from target_list, mirror type must be 'sync' or 'async', diff --git a/pyxcli/mirroring/recovery_manager.py b/pyxcli/mirroring/recovery_manager.py index 99c93e8..2c2255d 100644 --- a/pyxcli/mirroring/recovery_manager.py +++ b/pyxcli/mirroring/recovery_manager.py @@ -274,7 +274,7 @@ def _create_mirror(self, resource_type, resource_name, target_name, mirror_type, slave_resource_name, create_slave='no', remote_pool=None, rpo=None, remote_rpo=None, schedule=None, remote_schedule=None, - activate_mirror='no', part_of_multisite='no'): + activate_mirror='no', part_of_multisite=None): '''creates a mirror and returns a mirror object. resource_type must be 'vol' or 'cg', target name must be a valid target from target_list, @@ -303,9 +303,6 @@ def _create_mirror(self, resource_type, resource_name, target_name, if kwargs['remote_schedule'] is None: kwargs['remote_schedule'] = kwargs['schedule'] - if part_of_multisite == 'no': - kwargs['part_of_multisite'] = None - # avoids a python3 issue of the dict changing # during iteration keys = set(kwargs.keys()).copy() diff --git a/pyxcli/mirroring/volume_recovery_manager.py b/pyxcli/mirroring/volume_recovery_manager.py index 481a882..acc36c3 100644 --- a/pyxcli/mirroring/volume_recovery_manager.py +++ b/pyxcli/mirroring/volume_recovery_manager.py @@ -86,7 +86,7 @@ def create_mirror(self, resource_name, target_name, mirror_type, slave_resource_name, create_slave='no', remote_pool=None, rpo=None, remote_rpo=None, schedule=None, remote_schedule=None, activate_mirror='no', - part_of_multisite='no'): + part_of_multisite=None): '''creates a mirror and returns a mirror object, target name must be a valid target from target_list, mirror type must be 'sync' or 'async', From 91eb9486f13413efa44f208f8fbf626327a00826 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 19 Aug 2019 19:40:14 +0800 Subject: [PATCH 11/18] increase timeout value to handle multisite related commands --- pyxcli/transports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyxcli/transports.py b/pyxcli/transports.py index 88f3d69..ca85c76 100644 --- a/pyxcli/transports.py +++ b/pyxcli/transports.py @@ -154,7 +154,7 @@ def __repr__(self): h, p, ssl) @classmethod - def connect(cls, hostname, port, timeout=5.0): + def connect(cls, hostname, port, timeout=10.0): xlog.debug("CONNECT (non SSL) %s:%s", hostname, port) sock = socket.socket() sock.settimeout(timeout) @@ -185,7 +185,7 @@ def _certificate_required(cls, hostname, port=XCLI_DEFAULT_PORT, return True @classmethod - def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=5.0, + def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=10.0, ca_certs=None, validate=None): certificate_required = cls._certificate_required(hostname, From 91fc63a49201f7929bd53996d04a5a24ce2583d1 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 19 Aug 2019 19:42:28 +0800 Subject: [PATCH 12/18] new return codes need to be handle after increase timeout value --- pyxcli/errors.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index d0947d5..012ac01 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -1302,6 +1302,17 @@ class VolumeTargetMismatch(CommandFailedRuntimeError): @CommandExecutionError.register("TARGET_VOLUME_HAS_HA") class TargetVolumeHasHa(CommandFailedRuntimeError): pass + + +@CommandExecutionError.register("REMOTE_ACTION_FAILED") +class RemoteActionFailed(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_DELETE_PARTIAL" + "_FAILURE_MANUAL_CLEANUP_REQUIRED") +class MultisitePartialDelete(CommandFailedRuntimeError): + pass ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from From d1bc1a6e640203fb6b0eff01da831ddec0081610 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 22 Aug 2019 16:36:10 +0800 Subject: [PATCH 13/18] increase timeout value to 15s --- pyxcli/transports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyxcli/transports.py b/pyxcli/transports.py index ca85c76..77ad0e9 100644 --- a/pyxcli/transports.py +++ b/pyxcli/transports.py @@ -154,7 +154,7 @@ def __repr__(self): h, p, ssl) @classmethod - def connect(cls, hostname, port, timeout=10.0): + def connect(cls, hostname, port, timeout=15.0): xlog.debug("CONNECT (non SSL) %s:%s", hostname, port) sock = socket.socket() sock.settimeout(timeout) @@ -185,7 +185,7 @@ def _certificate_required(cls, hostname, port=XCLI_DEFAULT_PORT, return True @classmethod - def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=10.0, + def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=15.0, ca_certs=None, validate=None): certificate_required = cls._certificate_required(hostname, From fbb0acc1641d273379f51e22324e514921cb8449 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Thu, 22 Aug 2019 16:36:59 +0800 Subject: [PATCH 14/18] add new error code found in test --- pyxcli/errors.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 012ac01..afca9da 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -1313,6 +1313,11 @@ class RemoteActionFailed(CommandFailedRuntimeError): "_FAILURE_MANUAL_CLEANUP_REQUIRED") class MultisitePartialDelete(CommandFailedRuntimeError): pass + + +@CommandExecutionError.register("RPC_READ_RESPONSE_FAILED") +class RpcReadResponseFailed(CommandFailedRuntimeError): + pass ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from From 358f54e4f806903ef46f359340459acc695649f4 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 26 Aug 2019 16:09:11 +0800 Subject: [PATCH 15/18] git add error code found in test --- pyxcli/errors.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index afca9da..234ce6d 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -1318,6 +1318,17 @@ class MultisitePartialDelete(CommandFailedRuntimeError): @CommandExecutionError.register("RPC_READ_RESPONSE_FAILED") class RpcReadResponseFailed(CommandFailedRuntimeError): pass + + +@CommandExecutionError.register("ERROR.") +class GeneralError(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MAPPING_IS_NOT_DEFINED") +class MappingIsNotDefined(CommandFailedRuntimeError): + pass + ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from From a55bdcd5581ca26696457a94b2d8c5089f19038c Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 26 Aug 2019 21:16:00 +0800 Subject: [PATCH 16/18] add new error code found in test --- pyxcli/errors.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 234ce6d..95083e1 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -1320,15 +1320,24 @@ class RpcReadResponseFailed(CommandFailedRuntimeError): pass -@CommandExecutionError.register("ERROR.") +@CommandExecutionError.register("ERROR") class GeneralError(CommandFailedRuntimeError): pass +@CommandExecutionError.register("MULTISITE_MASTER_INVALID_CONFIGURATION") +class MultisiteMasterInvalidConfiguration(CommandFailedRuntimeError): + pass + @CommandExecutionError.register("MAPPING_IS_NOT_DEFINED") class MappingIsNotDefined(CommandFailedRuntimeError): pass + +@CommandExecutionError.register("MULTISITE_MAX_NUM_OF_MIRRORS_REACHED") +class MultisiteMaxNumOfMirrorsReached(CommandFailedRuntimeError): + pass + ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from @@ -1415,3 +1424,7 @@ class TransportError(XCLIError): class ConnectionError(TransportError): """Represents errors that occur during connection""" pass + + +class RanOutOfEndpointError(IOError, TransportError): + pass From 80b8242fe849eb29661d7918f6c5c7490c0d2b84 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Mon, 26 Aug 2019 21:17:29 +0800 Subject: [PATCH 17/18] add debug message for Ran out of endpoints --- pyxcli/transports.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pyxcli/transports.py b/pyxcli/transports.py index 77ad0e9..ba2ec63 100644 --- a/pyxcli/transports.py +++ b/pyxcli/transports.py @@ -33,6 +33,7 @@ from pyxcli.errors import ConnectionError from pyxcli.errors import CorruptResponse from pyxcli.errors import BaseScsiException +from pyxcli.errors import RanOutOfEndpointError try: basestring @@ -154,7 +155,7 @@ def __repr__(self): h, p, ssl) @classmethod - def connect(cls, hostname, port, timeout=15.0): + def connect(cls, hostname, port, timeout=10.0): xlog.debug("CONNECT (non SSL) %s:%s", hostname, port) sock = socket.socket() sock.settimeout(timeout) @@ -185,7 +186,7 @@ def _certificate_required(cls, hostname, port=XCLI_DEFAULT_PORT, return True @classmethod - def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=15.0, + def connect_ssl(cls, hostname, port=XCLI_DEFAULT_PORT, timeout=10.0, ca_certs=None, validate=None): certificate_required = cls._certificate_required(hostname, @@ -328,8 +329,8 @@ def _connect(self): if not self.available_endpoints: xlog.debug("MultiEndpointTransport: no more endpoints \ available") - raise ClosedTransportError("Ran out of endpoints to \ - connect to", exceptions) + raise RanOutOfEndpointError("Ran out of endpoints to \ + connect to", exceptions) ep = self.available_endpoints.pop(0) xlog.debug("MultiEndpointTransport: changing to \ @@ -355,8 +356,17 @@ def send(self, *args): self._connect() try: return self.transport.send(*args) - except (TransportError, IOError): + except TransportError as ex: self.transport.close() self.transport = ClosedTransport xlog.debug("MultiEndpointTransport: sending over %s failed", self.transport) + xlog.debug("Request failed in TransportError with error message: " + "%(msg)s" % dict(msg=ex)) + except IOError as ex: + self.transport.close() + self.transport = ClosedTransport + xlog.debug("MultiEndpointTransport: sending over %s failed", + self.transport) + xlog.debug("Request failed in IOError with error message: " + "%(msg)s" % dict(msg=ex)) From e7556e1b2b05e86100611aac4cf5bba44c995297 Mon Sep 17 00:00:00 2001 From: Xu chu Jiang Date: Tue, 27 Aug 2019 15:57:15 +0800 Subject: [PATCH 18/18] error from try to delete a partial deletion multisite volume --- pyxcli/errors.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 95083e1..8a931ec 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -1338,6 +1338,10 @@ class MappingIsNotDefined(CommandFailedRuntimeError): class MultisiteMaxNumOfMirrorsReached(CommandFailedRuntimeError): pass + +@CommandExecutionError.register("MIRROR_ASSOCIATED_WITH_MULTISITE") +class MirrorAssociatedWithMultisite(CommandFailedRuntimeError): + pass ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from