Files
zvml-python-sdk/examples/vras_example.py
T
2025-07-25 15:03:39 -04:00

259 lines
10 KiB
Python

# Legal Disclaimer
# This script is an example script and is not supported under any Zerto support program or service.
# The author and Zerto further disclaim all implied warranties including, without limitation,
# any implied warranties of merchantability or of fitness for a particular purpose.
# In no event shall Zerto, its authors or anyone else involved in the creation,
# production or delivery of the scripts be liable for any damages whatsoever (including,
# without limitation, damages for loss of business profits, business interruption, loss of business
# information, or other pecuniary loss) arising out of the use of or the inability to use the sample
# scripts or documentation, even if the author or Zerto has been advised of the possibility of such damages.
# The entire risk arising out of the use or performance of the sample scripts and documentation remains with you.
"""
Zerto Virtual Replication Appliance (VRA) Management Example Script
This script demonstrates how to manage VRAs using the Zerto Virtual Manager (ZVM) API.
It showcases VRA deployment, configuration, and cleanup operations.
Key Features:
1. VRA Management:
- List existing VRAs and their details
- Delete existing VRAs
- Deploy new VRAs with custom configurations
- Monitor VRA deployment status
2. Resource Selection:
- Interactive selection of hosts
- Interactive selection of datastores
- Interactive selection of networks
- Custom IP configuration for VRAs
3. Parallel Operations:
- Deploy multiple VRAs simultaneously
- Delete multiple VRAs in parallel
- Monitor multiple VRA operations
Required Arguments:
--zvm_address: ZVM server address
--client_id: Keycloak client ID
--client_secret: Keycloak client secret
--ignore_ssl: Ignore SSL certificate verification (optional)
Example Usage:
python examples/vras_example.py \
--zvm_address "192.168.111.20" \
--client_id "zerto-api" \
--client_secret "your-secret-here" \
--ignore_ssl
Script Flow:
1. Lists all existing VRAs and their details
2. Optionally deletes all existing VRAs
3. Creates new VRAs with user-selected resources:
- First VRA with IP 192.168.111.30
- Second VRA with IP 192.168.111.31 (optional)
4. Verifies final VRA configuration
Note: This script includes interactive prompts for resource selection and operation
confirmation. It demonstrates proper error handling and logging for VRA management
operations.
"""
# Configure logging BEFORE any imports
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
import argparse
import urllib3
import json
import sys
import os
import time
from typing import Dict, List
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from zvml import ZVMLClient
# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def setup_client(args):
"""Initialize and return Zerto client"""
client = ZVMLClient(
zvm_address=args.zvm_address,
client_id=args.client_id,
client_secret=args.client_secret,
verify_certificate=not args.ignore_ssl
)
return client
def get_user_confirmation(prompt: str) -> bool:
"""Get user confirmation for an action"""
while True:
response = input(f"\n{prompt} (yes/no): ").lower().strip()
if response in ['yes', 'y']:
return True
if response in ['no', 'n']:
return False
print("Please answer 'yes' or 'no'")
def select_from_list(items, item_type: str):
"""Let user select an item from a list"""
logging.info(f"select_from_list: {json.dumps(items, indent=2)}")
print(f"\nAvailable {item_type}s:")
for idx, item in enumerate(items, 1):
if 'VirtualizationHostName' in item: # For hosts
print(f"{idx}. {item['VirtualizationHostName']} ({item['HostIdentifier']})")
elif 'DatastoreName' in item: # For datastores
print(f"{idx}. {item['DatastoreName']} ({item['DatastoreIdentifier']})")
elif 'VirtualizationNetworkName' in item: # For networks
print(f"{idx}. {item['VirtualizationNetworkName']} ({item['NetworkIdentifier']})")
while True:
try:
choice = int(input(f"\nSelect {item_type} (1-{len(items)}): "))
if 1 <= choice <= len(items):
return items[choice - 1]
except ValueError:
pass
print(f"Please enter a number between 1 and {len(items)}")
def list_vras(client: ZVMLClient):
"""List all VRAs and their details"""
vras = client.vras.list_vras()
print(f"\nFound {len(vras)} VRAs:")
for vra in vras:
print(f"\nVRA Details:")
print(f" Name: {vra.get('VraName')}")
print(f" Status: {vra.get('Status')}")
print(f" IP Address: {vra.get('IpAddress')}")
print(f" Version: {vra.get('VraVersion')}")
print(f" Host: {vra.get('HostName')}")
def create_vra_with_selection(client: ZVMLClient, vra_number: int) -> Dict:
"""Create a VRA with user-selected resources"""
# Get local site information
local_site = client.localsite.get_local_site()
site_id = local_site['SiteIdentifier']
# Get available resources for the local site
print("\nRetrieving available resources...")
hosts = client.virtualization_sites.get_virtualization_site_hosts(site_id)
if not hosts:
raise ValueError("No hosts found in local site")
datastores = client.virtualization_sites.get_virtualization_site_datastores(site_id)
if not datastores:
raise ValueError("No datastores found in local site")
networks = client.virtualization_sites.get_virtualization_site_networks(site_id)
if not networks:
raise ValueError("No networks found in local site")
# Let user select resources
print("\nSelect resources for VRA deployment:")
host = select_from_list(hosts, "Host")
datastore = select_from_list(datastores, "Datastore")
network = select_from_list(networks, "Network")
while True:
# Let user customize IP address
default_ip = f"192.168.111.{30 + vra_number - 1}"
custom_ip = input(f"\nEnter VRA IP address (press Enter to use default {default_ip}): ").strip()
vra_ip = custom_ip if custom_ip else default_ip
# Create VRA configuration
vra_config = {
"hostIdentifier": host['HostIdentifier'],
"datastoreIdentifier": datastore['DatastoreIdentifier'],
"networkIdentifier": network['NetworkIdentifier'],
"hostRootPassword": input("\nEnter host root password: "),
"memoryInGb": 3,
"groupName": f"VRA_Group{vra_number}",
"vraNetworkDataApi": {
"vraIPConfigurationTypeApi": "Static",
"vraIPAddress": vra_ip,
"vraIPAddressRangeEnd": "",
"subnetMask": "255.255.255.0",
"defaultGateway": "192.168.111.254"
},
"usePublicKeyInsteadOfCredentials": False,
"populatePostInstallation": True,
"numOfCpus": 1,
"vmInstanceType": ""
}
# Create VRA
print(f"\nCreating VRA {vra_number} with configuration:")
print(json.dumps(vra_config, indent=2))
response = input("\nProceed with VRA creation? (yes/no/edit): ").lower().strip()
if response in ['yes', 'y']:
result = client.vras.create_vra(vra_config)
print(f"VRA creation initiated: {json.dumps(result, indent=2)}")
return result
elif response in ['no', 'n']:
return None
elif response in ['edit', 'e']:
print("\nRestarting VRA configuration...")
continue
else:
print("Please answer 'yes', 'no', or 'edit'")
def main():
parser = argparse.ArgumentParser(description="VRA Management Example")
parser.add_argument("--zvm_address", required=True, help="ZVM address")
parser.add_argument('--client_id', required=True, help='Keycloak client ID')
parser.add_argument('--client_secret', required=True, help='Keycloak client secret')
parser.add_argument("--ignore_ssl", action="store_true", help="Ignore SSL certificate verification")
args = parser.parse_args()
try:
# Setup client
client = setup_client(args)
# Step 1: List existing VRAs
print("\nStep 1: Listing existing VRAs...")
list_vras(client)
# Step 2: Ask for deletion confirmation
if get_user_confirmation("Would you like to delete all existing VRAs?"):
print("\nStep 2: Deleting existing VRAs...")
vras = client.vras.list_vras()
for vra in vras:
vra_id = vra.get('VraIdentifier')
print(f"Deleting VRA: {vra.get('VraName')} ({vra_id})")
client.vras.delete_vra(vra_id)
print("Waiting for deletion to complete...")
time.sleep(5) # Give some time for deletion to process
# Step 3: Create new VRAs
if get_user_confirmation("Would you like to create new VRAs?"):
print("\nStep 3: Creating new VRAs...")
# Create first VRA
print("\nConfiguring first VRA...")
result1 = create_vra_with_selection(client, 1)
if result1:
print("Waiting for first VRA deployment to complete...")
time.sleep(30)
# Create second VRA
if get_user_confirmation("Would you like to create a second VRA?"):
print("\nConfiguring second VRA...")
result2 = create_vra_with_selection(client, 2)
if result2:
print("Waiting for second VRA deployment to complete...")
time.sleep(30)
# Step 4: Verify final state
print("\nStep 4: Verifying final VRA configuration...")
list_vras(client)
except Exception as e:
logging.exception("Error occurred:")
sys.exit(1)
if __name__ == "__main__":
main()