diff --git a/pyxcli/errors.py b/pyxcli/errors.py index 9813595..8a931ec 100644 --- a/pyxcli/errors.py +++ b/pyxcli/errors.py @@ -713,18 +713,643 @@ class VolumeIsSlave(CommandFailedRuntimeError): pass +@CommandExecutionError.register("MULTISITE_STANDBY_RELATION_ALREADY_DEFINED") +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 + + +@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_PART_OF_MULTISITE") +class HaPartOfMultisite(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("HA_RETRY_OPERATION") +class HaRetryOperation(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_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_MASTER_SMASTER_CLOCK_SKEW_TOO_BIG") +class MultisiteMasterSmasterClockSkewTooBig(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("MULTISITE_NOT_OPERATIONAL") +class MultisiteNotOperational(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_HAS_NO_SYNCHED_SNAPSHOT") +class MultisiteSmasterHasNoSynchedSnapshot(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_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_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("RELATION_RETRY_OPERATION") +class RelationRetryOperation(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_MAY_NOT_HAVE_COMPLETED_THE_OPERATION") +class RemoteMayNotHaveCompletedTheOperation(CommandFailedRuntimeError): + pass + + +@CommandExecutionError.register("REMOTE_MIRROR_IS_STANDBY") +class RemoteMirrorIsStandby(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_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_ENABLED_HA") +class TargetHasEnabledHa(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_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_TARGET_MISMATCH") +class VolumeTargetMismatch(CommandFailedRuntimeError): + pass + + +@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 + + +@CommandExecutionError.register("RPC_READ_RESPONSE_FAILED") +class RpcReadResponseFailed(CommandFailedRuntimeError): + pass + + +@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 + + +@CommandExecutionError.register("MIRROR_ASSOCIATED_WITH_MULTISITE") +class MirrorAssociatedWithMultisite(CommandFailedRuntimeError): + pass ############################################################################## # CredentialsError # we explicitly want to differentiate CredentialsError from # 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", @@ -803,3 +1428,7 @@ class TransportError(XCLIError): class ConnectionError(TransportError): """Represents errors that occur during connection""" pass + + +class RanOutOfEndpointError(IOError, TransportError): + pass diff --git a/pyxcli/mirroring/cg_recovery_manager.py b/pyxcli/mirroring/cg_recovery_manager.py index a245611..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'): + 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', @@ -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''' diff --git a/pyxcli/mirroring/recovery_manager.py b/pyxcli/mirroring/recovery_manager.py index d2931c5..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'): + 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, @@ -291,7 +291,8 @@ def _create_mirror(self, resource_type, resource_name, target_name, 'rpo': rpo, 'remote_rpo': remote_rpo, 'schedule': schedule, - 'remote_schedule': remote_schedule + 'remote_schedule': remote_schedule, + 'part_of_multisite': part_of_multisite } if mirror_type == 'sync': diff --git a/pyxcli/mirroring/volume_recovery_manager.py b/pyxcli/mirroring/volume_recovery_manager.py index bc6ee81..acc36c3 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=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', @@ -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''' diff --git a/pyxcli/transports.py b/pyxcli/transports.py index 88f3d69..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=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 +186,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, @@ -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))