Files
Zerto-Python-SDK-Hands-On-Labs/exercises/06_failover_test/working/failover.py
T
2025-06-12 20:09:35 -04:00

266 lines
8.7 KiB
Python

#!/usr/bin/env python3
"""
Exercise 6: Failover Testing - Beginner-Friendly Instructions
This script demonstrates how to perform a failover test on a VPG.
PREREQUISITES (Complete these first):
1. ✅ Completed Exercise 5 (VPG Operations)
2. ✅ Make sure you have the zvml package installed
3. ✅ Updated prerequisites/config.py with your ZVM details
4. ✅ Have a VPG created and running (from Exercise 5)
WHAT YOU NEED TO DO:
In this exercise, you will:
1. Create a ZVMLClient to connect to your ZVM
2. Parse command line arguments (VPG name)
3. Find a VPG by its name
4. Start a failover test on the VPG
5. Monitor the test progress
6. Optionally stop the test
STEP-BY-STEP INSTRUCTIONS:
1. Look at the TODO comments below - they tell you exactly what to do
2. Replace the placeholder code with the actual code
3. Each step has hints and examples to help you
4. If you get stuck, check the solution file in the solution/ directory
WHAT IS A FAILOVER TEST?
- **Failover Test**: Tests if your VMs can be successfully started at the recovery site
- It creates test VMs at the peer site to verify everything works
- The test VMs are isolated and don't affect production
- You can stop the test at any time to clean up the test VMs
USAGE EXAMPLE:
python failover.py --vpg-name "My-VPG"
"""
import sys
import os
import logging
import json
import argparse
import time
from pathlib import Path
import urllib3
# Suppress SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Add prerequisites to Python path (this helps Python find your config file)
prerequisites_path = Path(__file__).parent.parent.parent.parent / "prerequisites"
sys.path.append(str(prerequisites_path))
# Import the Zerto SDK - this gives us the ZVMLClient class
from zvml import ZVMLClient
# Import your configuration settings
try:
from config import (
ZVM_HOST, # Your ZVM IP address (e.g., "192.168.1.100")
ZVM_PORT, # Usually 443 for HTTPS
ZVM_SSL_VERIFY, # True/False for SSL certificate verification
CLIENT_ID, # Your Keycloak client ID (e.g., "my-api-client")
CLIENT_SECRET # Your Keycloak client secret
)
except ImportError:
print("❌ ERROR: Configuration file not found!")
print("Please copy config.example.py to config.py and update with your values")
print("Expected path:", prerequisites_path / "config.py")
sys.exit(1)
def parse_arguments():
"""
Parse command line arguments.
TODO: Implement argument parsing
HINT: Use this syntax:
parser = argparse.ArgumentParser(description='Perform failover test on a VPG')
parser.add_argument('--vpg-name', required=True,
help='Name of the VPG to test')
return parser.parse_args()
EXPLANATION:
- argparse helps you get command line arguments
- --vpg-name: Name of the VPG to test (required)
"""
pass # ← REPLACE WITH YOUR CODE
def find_vpg_by_name(client, vpg_name):
"""
Find a VPG by its name.
TODO: Implement the function to find a VPG by name
HINT: Use this syntax:
vpg = client.vpgs.list_vpgs(vpg_name=vpg_name)
return vpg if vpg else None
EXPLANATION:
- client.vpgs.list_vpgs() gets VPGs with a specific name
- Returns the VPG if found, None if not found
"""
pass # ← REPLACE WITH YOUR CODE
def start_failover_test(client, vpg_name):
"""
Start a failover test for the specified VPG.
TODO: Implement the function to start a failover test
HINT: Use this syntax:
response = client.vpgs.failover_test(
vpg_name=vpg_name,
sync=True # Wait for the test to start
)
return response
EXPLANATION:
- client.vpgs.failover_test() starts a failover test
- sync=True means wait for the test to start before returning
- Returns the response from the API
"""
pass # ← REPLACE WITH YOUR CODE
def monitor_test_progress(client, vpg_name, test_id):
"""
Monitor the progress of a failover test.
TODO: Implement the function to monitor test progress
HINT: Use this syntax:
test_status = client.vpgs.get_vpg_test_status(vpg_name, test_id)
status = test_status.get('Status')
progress = test_status.get('Progress', 0)
logging.info(f"Test status: {status} (Progress: {progress}%)")
if status == 'Succeeded':
return True
elif status in ['Failed', 'Stopped']:
return False
return False # Test is still running
EXPLANATION:
- client.vpgs.get_vpg_test_status() gets the current test status
- Returns True if test succeeded, False if failed/stopped/still running
"""
pass # ← REPLACE WITH YOUR CODE
def stop_failover_test(client, vpg_name):
"""
Stop a running failover test.
TODO: Implement the function to stop a failover test
HINT: Use this syntax:
response = client.vpgs.stop_failover_test(vpg_name=vpg_name)
EXPLANATION:
- client.vpgs.stop_failover_test() stops the running test
- This cleans up the test VMs at the recovery site
"""
pass # ← REPLACE WITH YOUR CODE
def main():
"""
Main function - this is where your code goes!
Follow the step-by-step instructions below.
"""
# Set up logging so you can see what's happening
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
print("🚀 Starting Zerto Failover Testing Exercise")
print("=" * 50)
try:
# ========================================
# STEP 1: Parse command line arguments
# ========================================
print("\n📝 STEP 1: Parsing command line arguments...")
print("You need to call the parse_arguments() function you created above.")
# TODO: Add code to parse arguments
# HINT: Use this syntax:
# args = parse_arguments()
#
# EXPLANATION:
# This gets the VPG name from command line
# ← ADD YOUR CODE HERE
# ========================================
# STEP 2: Create ZVMLClient instance
# ========================================
print("\n📝 STEP 2: Creating ZVMLClient...")
print("This is the same as previous exercises.")
# TODO: Add code to create ZVMLClient
# HINT: Use this syntax:
# client = ZVMLClient(
# zvm_address=ZVM_HOST,
# client_id=CLIENT_ID,
# client_secret=CLIENT_SECRET,
# verify_certificate=ZVM_SSL_VERIFY
# )
# ← ADD YOUR CODE HERE
# ========================================
# STEP 3: Find the VPG
# ========================================
print("\n📝 STEP 3: Finding the VPG...")
print("You need to find the VPG by its name.")
# TODO: Add code to find VPG
# HINT: Use this syntax:
# vpg = find_vpg_by_name(client, args.vpg_name)
# if not vpg:
# logging.error(f"VPG '{args.vpg_name}' not found!")
# sys.exit(1)
#
# EXPLANATION:
# This checks if the VPG exists before trying to test it
# ← ADD YOUR CODE HERE
# ========================================
# STEP 4: Start failover test
# ========================================
print("\n📝 STEP 4: Starting failover test...")
print("You need to start a failover test on the VPG.")
# TODO: Add code to start failover test
# HINT: Use this syntax:
# response = start_failover_test(client, args.vpg_name)
#
# EXPLANATION:
# This starts the failover test and waits for it to begin
# ← ADD YOUR CODE HERE
# ========================================
# STEP 5: Handle test stop request
# ========================================
print("\n📝 STEP 5: Handling test stop request...")
print("You can optionally stop the test.")
# TODO: Add code for interactive test stopping
# HINT: Use this syntax:
# response = input("\nWould you like to stop the test? (yes/no): ").lower()
# if response in ['yes', 'y']:
# stop_failover_test(client, args.vpg_name)
#
# EXPLANATION:
# This asks the user if they want to stop the test and cleans up if yes
# ← ADD YOUR CODE HERE
except Exception as e:
# This catches any errors that might occur
print(f"\n❌ ERROR: Something went wrong!")
print(f"Error details: {str(e)}")
logging.error(f"Failover test failed: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()