Overview
This guide provides step-by-step instructions for executing the VAST user quota report script and installing the required dependencies. This script leverages the VAST Python library (vastpy), which enables interaction with the VAST API.
Prerequisites
Before running the script, ensure that:
Python 3.6+ is installed on your machine.
You have network access to the VAST Cluster API (https://IP)
API credentials (admin username and password) that have sufficient permissions to fetch quota data.
Installing Required Python Modules
The script requires the following dependencies:
vastpy(for VAST API interaction)pandas(for data processing)requests(for handling API requests)
Please run the following procedure
Install from a
requirements.txtFileCreate a file named
requirements.txtwith the following contents:vastpy pandas requestsInstall the dependencies:
pip install -r requirements.txt
Create the Quota Report Script
Save the Script as
quota_report.pyModify the relevant information within the script ( The script can monitor several VAST clusters. To do that, please add your VMS IPs & Credentials) :
VAST_CREDENTIALS = { "VMS1_IP": {"username": "USER1", "password": "PASSWORD1"}, "VMS2_IP": {"username": "USER2", "password": "PASSWORD2"}, }
quota_report.py
import logging
import pandas as pd
from datetime import datetime
from vastpy import VASTClient
# Dictionary mapping VAST Cluster IPs to unique credentials
VAST_CREDENTIALS = {
"VMS1_IP": {"username": "USER1", "password": "PASSWORD1"},
"VMS2_IP": {"username": "USER2", "password": "PASSWORD2"},
}
# Configure logging to both console and a log file
log_filename = "quota_report.log"
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
handlers=[
logging.FileHandler(log_filename, mode='a'), # Append to log file
logging.StreamHandler() # Also print to console
]
)
# Conversion factor from Bytes to GB
BYTES_TO_GB = 1073741824 # 1GB
def bytes_to_gb(value):
"""Convert bytes to GB, return 'N/A' if None."""
return round(value / BYTES_TO_GB, 2) if value is not None else "N/A"
def get_vast_client(address):
"""Authenticate with the VAST API for a given cluster IP using its specific credentials."""
if address not in VAST_CREDENTIALS:
logging.error(f"No credentials found for {address}. Skipping.")
return None
username = VAST_CREDENTIALS[address]["username"]
password = VAST_CREDENTIALS[address]["password"]
try:
logging.info(f"Starting data retrieval for VAST Cluster: {address} (User: {username})")
client = VASTClient(user=username, password=password, address=address)
# Validate connection by retrieving basic settings
settings = client.basicsettings.get()
logging.info(f"Connected to VAST at {address}")
return client
except Exception as e:
logging.error(f"Failed to connect to VAST API at {address}: {e}")
return None
def get_quotas(address):
"""Retrieve quota information from a specific VAST Cluster IP."""
client = get_vast_client(address)
if not client:
logging.error(f"Skipping {address} due to connection failure.")
return None
try:
logging.info(f"Fetching quota data from VAST at {address}...")
quotas = client.quotas.get()
if not quotas or len(quotas) == 0:
logging.warning(f"No quotas found at {address}.")
return []
logging.info(f"Quota data retrieved successfully from {address}. Number of records: {len(quotas)}")
return quotas
except Exception as e:
logging.error(f"Error retrieving quota data from {address}: {e}")
return None
def generate_report():
"""Fetch quota data from all specified VAST clusters, print reports, and append to CSVs."""
for index, address in enumerate(VAST_CREDENTIALS.keys()):
if index > 0:
print(f"\nFinished processing {list(VAST_CREDENTIALS.keys())[index - 1]}")
logging.info(f"Finished processing {list(VAST_CREDENTIALS.keys())[index - 1]}")
print("\nMoving to the next cluster...\n")
logging.info("Moving to the next cluster...\n")
quotas = get_quotas(address)
data = []
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if quotas is None:
logging.info(f"Skipping {address} due to retrieval failure.")
quotas = [] # Ensure an empty dataset to generate an empty CSV
for quota in quotas:
default_user_quota = quota.get("default_user_quota") or {} # Ensure it's a dict
quota_system_id = default_user_quota.get("quota_system_id", "N/A")
user_soft_limit = bytes_to_gb(default_user_quota.get("soft_limit"))
user_hard_limit = bytes_to_gb(default_user_quota.get("hard_limit"))
main_soft_limit = bytes_to_gb(quota.get("soft_limit"))
main_hard_limit = bytes_to_gb(quota.get("hard_limit"))
data.append({
"Timestamp": current_time, # Add timestamp for each entry
"Quota ID": quota.get("id"),
"Name": quota.get("name", "N/A"),
"Path": quota.get("path", "N/A"),
"State": quota.get("state", "N/A"),
"Main Soft Limit (GB)": main_soft_limit,
"Main Hard Limit (GB)": main_hard_limit,
"User Soft Limit (GB)": user_soft_limit,
"User Hard Limit (GB)": user_hard_limit,
"Quota System ID": quota_system_id,
"Used Capacity (GB)": bytes_to_gb(quota.get("used_capacity")),
"Used Effective Capacity (GB)": bytes_to_gb(quota.get("used_effective_capacity")),
"Sync State": quota.get("sync_state", "N/A"),
"Cluster": quota.get("cluster", "N/A"),
"Tenant ID": quota.get("tenant_id", "N/A"),
})
df = pd.DataFrame(data)
# Print a separate table for each cluster
print(f"\nQuota Report for VAST Cluster: {address}\n")
if not df.empty:
print(df.to_string(index=False))
else:
print(f"No quota data available for {address}. An empty CSV file will be maintained.")
# Save the report as a CSV file, appending to it instead of overwriting
csv_filename = f"quota_report_{address}.csv"
df.to_csv(csv_filename, mode='a', header=not pd.io.common.file_exists(csv_filename), index=False)
logging.info(f"Quota report appended to {csv_filename}")
print("\nAll clusters processed successfully.\n")
logging.info("All clusters processed successfully.")
if __name__ == "__main__":
logging.info("Starting quota report generation for all configured VAST clusters...")
generate_report()
Executing the Script
Execute the script using the following command :
python3 quota_report.pyExpected output:
The script will check the quota status, print it to the screen, and generate a CSV file.
##python3 quota_report.py
2025-02-09 11:57:07 - INFO - Starting quota report generation for all configured VAST clusters...
2025-02-09 11:57:07 - INFO - Starting data retrieval for VAST Cluster: 10.27.200.136 (User: admin)
2025-02-09 11:57:07 - INFO - Connected to VAST at 10.27.200.136
2025-02-09 11:57:07 - INFO - Fetching quota data from VAST at 10.27.200.136...
2025-02-09 11:57:08 - INFO - Quota data retrieved successfully from 10.27.200.136. Number of records: 1
Quota Report for VAST Cluster: 10.27.200.136
Timestamp Quota ID Name Path State Main Soft Limit (GB) Main Hard Limit (GB) User Soft Limit (GB) User Hard Limit (GB) Quota System ID Used Capacity (GB) Used Effective Capacity (GB) Sync State Cluster Tenant ID
2025-02-09 11:57 4 test1 /test1 OK 0.93 N/A 0.01 0.02 2 0.0 0.0 SYNCHRONIZED v136 1
2025-02-09 11:57:08 - INFO - Quota report appended to quota_report_10.27.200.136.csv
Finished processing 10.27.200.136
2025-02-09 11:57:08 - INFO - Finished processing 10.27.200.136
Moving to the next cluster...
2025-02-09 11:57:08 - INFO - Moving to the next cluster...
2025-02-09 11:57:08 - INFO - Starting data retrieval for VAST Cluster: 10.27.200.6 (User: admin)
2025-02-09 11:57:08 - INFO - Connected to VAST at 10.27.200.6
2025-02-09 11:57:08 - INFO - Fetching quota data from VAST at 10.27.200.6...
2025-02-09 11:57:08 - INFO - Quota data retrieved successfully from 10.27.200.6. Number of records: 1
Quota Report for VAST Cluster: 10.27.200.6
Timestamp Quota ID Name Path State Main Soft Limit (GB) Main Hard Limit (GB) User Soft Limit (GB) User Hard Limit (GB) Quota System ID Used Capacity (GB) Used Effective Capacity (GB) Sync State Cluster Tenant ID
2025-02-09 11:57 1 quota_demo1 /quota OK 93.13 N/A 93.13 186.26 1 0.0 0.0 SYNCHRONIZED vast6-kfs 1
2025-02-09 11:57:08 - INFO - Quota report appended to quota_report_10.27.200.6.csv
All clusters processed successfully.
2025-02-09 11:57:08 - INFO - All clusters processed successfully.Further Reading
VASTpy Library (Python API for VAST Data Platform):
https://pypi.org/project/vastpy/