Files
zerto-ai-rewind/src/zerto_rewind_mcp/status.py
T
claude 38ba9c1b50 feat(poc): rewind MCP, skill, and recover-ladder docs
Initial PoC: find_protection, tagged checkpoints, FLR, mutating catalog.
Lab 10.9 status enums (0=Initializing, 1=MeetingSLA). Credentials stay in gitignored config.json.
2026-09-21 12:09:11 -04:00

134 lines
3.6 KiB
Python

"""VPG status / substatus integers from GET /v1/vpgs/statuses and /substatuses.
Live 10.9 ZVM (192.168.50.30, 2026-09-21). Older api_lessons mapping
(0=Protecting, 1=Moving) is wrong on this appliance.
"""
# GET /v1/vpgs/statuses
INITIALIZING = 0
MEETING_SLA = 1
NOT_MEETING_SLA = 2
RPO_NOT_MEETING_SLA = 3
HISTORY_NOT_MEETING_SLA = 4
FAILING_OVER = 5
MOVING = 6
DELETING = 7
RECOVERED = 8
STATUS_NAME = {
INITIALIZING: "Initializing",
MEETING_SLA: "MeetingSLA",
NOT_MEETING_SLA: "NotMeetingSLA",
RPO_NOT_MEETING_SLA: "RpoNotMeetingSLA",
HISTORY_NOT_MEETING_SLA: "HistoryNotMeetingSLA",
FAILING_OVER: "FailingOver",
MOVING: "Moving",
DELETING: "Deleting",
RECOVERED: "Recovered",
}
# GET /v1/vpgs/substatuses
NONE = 0
INITIAL_SYNC = 1
CREATING = 2
VOLUME_INITIAL_SYNC = 3
SYNC = 4
RECOVERY_POSSIBLE = 5
DELTA_SYNC = 6
NEEDS_CONFIGURATION = 7
ERROR = 8
EMPTY_PROTECTION_GROUP = 9
DISCONNECTED_NO_RECOVERY_POINTS = 10
FULL_SYNC = 11
VOLUME_DELTA_SYNC = 12
VOLUME_FULL_SYNC = 13
FAILING_OVER_COMMITTING = 14
FAILING_OVER_BEFORE_COMMIT = 15
FAILING_OVER_ROLLING_BACK = 16
PROMOTING = 17
MOVING_COMMITTING = 18
MOVING_BEFORE_COMMIT = 19
MOVING_ROLLING_BACK = 20
DELETING_SUB = 21
PENDING_REMOVE = 22
BITMAP_SYNC = 23
DISCONNECTED_FROM_PEER = 24
REPLICATION_PAUSED_USER = 25
REPLICATION_PAUSED_SYSTEM = 26
ADDED_VMS_IN_INITIAL_SYNC = 34
SUBSTATUS_NAME = {
NONE: "None",
INITIAL_SYNC: "InitialSync",
CREATING: "Creating",
VOLUME_INITIAL_SYNC: "VolumeInitialSync",
SYNC: "Sync",
RECOVERY_POSSIBLE: "RecoveryPossible",
DELTA_SYNC: "DeltaSync",
NEEDS_CONFIGURATION: "NeedsConfiguration",
ERROR: "Error",
EMPTY_PROTECTION_GROUP: "EmptyProtectionGroup",
DISCONNECTED_NO_RECOVERY_POINTS: "DisconnectedFromPeerNoRecoveryPoints",
FULL_SYNC: "FullSync",
VOLUME_DELTA_SYNC: "VolumeDeltaSync",
VOLUME_FULL_SYNC: "VolumeFullSync",
FAILING_OVER_COMMITTING: "FailingOverCommitting",
FAILING_OVER_BEFORE_COMMIT: "FailingOverBeforeCommit",
FAILING_OVER_ROLLING_BACK: "FailingOverRollingBack",
PROMOTING: "Promoting",
MOVING_COMMITTING: "MovingCommitting",
MOVING_BEFORE_COMMIT: "MovingBeforeCommit",
MOVING_ROLLING_BACK: "MovingRollingBack",
DELETING_SUB: "Deleting",
PENDING_REMOVE: "PendingRemove",
BITMAP_SYNC: "BitmapSync",
DISCONNECTED_FROM_PEER: "DisconnectedFromPeer",
REPLICATION_PAUSED_USER: "ReplicationPausedUserInitiated",
REPLICATION_PAUSED_SYSTEM: "ReplicationPausedSystemInitiated",
ADDED_VMS_IN_INITIAL_SYNC: "AddedVmsInInitialSync",
}
SYNCING = {
INITIAL_SYNC,
CREATING,
VOLUME_INITIAL_SYNC,
SYNC,
DELTA_SYNC,
FULL_SYNC,
VOLUME_DELTA_SYNC,
VOLUME_FULL_SYNC,
BITMAP_SYNC,
ADDED_VMS_IN_INITIAL_SYNC,
}
TAGGABLE_STATUS = {
MEETING_SLA,
NOT_MEETING_SLA,
RPO_NOT_MEETING_SLA,
HISTORY_NOT_MEETING_SLA,
}
def status_name(value: int | None) -> str:
if value is None:
return "unknown"
return STATUS_NAME.get(value, f"status:{value}")
def substatus_name(value: int | None) -> str:
if value is None:
return "unknown"
return SUBSTATUS_NAME.get(value, f"substatus:{value}")
def can_tag(status: int | None, substatus: int | None) -> tuple[bool, str | None]:
"""Whether a tagged checkpoint can be inserted on this VPG right now."""
if status not in TAGGABLE_STATUS:
return False, f"VPG status is {status_name(status)}; not MeetingSLA"
if substatus in SYNCING:
return False, (
f"VPG is {substatus_name(substatus)}; "
"checkpoints are not durable until sync ends"
)
return True, None