mirror of
https://github.com/recklessop/Zerto_Exporter.git
synced 2026-07-03 16:03:15 -04:00
zvma10 wrapper module
Created a python module that has everything needed for comms with ZVMA version 10 in a seperate class. It does not have full api coverage, but is enough to start refactoring the exporter to use the class for ZVMa10
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
print("Initializing zvma10 package...")
|
||||
|
||||
#from .zvma import zvm
|
||||
from .vcenter import vcsite
|
||||
from .zvma import zvmsite
|
||||
@@ -0,0 +1,201 @@
|
||||
# Class for holding variables related to a site.
|
||||
from pyVim.connect import SmartConnect, Disconnect
|
||||
from pyVmomi import vim, vmodl
|
||||
import ssl
|
||||
import datetime
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
class vcsite:
|
||||
def __init__(self, host, username, password, port=443, verify_ssl=False, loglevel="INFO"):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.verify_ssl = verify_ssl
|
||||
self.version = None
|
||||
self.__conn__ = None
|
||||
self.LOGLEVEL = loglevel.upper()
|
||||
|
||||
#set log line format including container_id
|
||||
log_formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(threadName)s;%(message)s", "%Y-%m-%d %H:%M:%S")
|
||||
log_handler = RotatingFileHandler(filename=f"./logs/Log-Main-vcenter.log", maxBytes=1024*1024*100, backupCount=5)
|
||||
log_handler.setFormatter(log_formatter)
|
||||
self.log = logging.getLogger("Node-Exporter")
|
||||
self.log.setLevel(self.LOGLEVEL)
|
||||
self.log.addHandler(log_handler)
|
||||
|
||||
def connect(self):
|
||||
self.log.info(f"Log Level set to {self.LOGLEVEL}")
|
||||
if self.__conn__ is None:
|
||||
context = ssl.create_default_context()
|
||||
if not self.verify_ssl:
|
||||
print("dont verify SSL")
|
||||
# Create an SSL context without certificate verification
|
||||
context.check_hostname = False
|
||||
context.verify_mode = ssl.CERT_NONE
|
||||
|
||||
# connect to vCenter Server
|
||||
si = None
|
||||
try:
|
||||
self.__conn__ = SmartConnect(host=self.host, user=self.username, pwd=self.password, sslContext=context)
|
||||
about_info = self.__conn__.content.about
|
||||
version = about_info.version
|
||||
self.version = version
|
||||
self.log.debug("Connected to vCenter Server %s", self.host)
|
||||
except Exception as e:
|
||||
self.log.error(f"Error connecting to vCenter Server: {e}")
|
||||
|
||||
def version(self):
|
||||
return self.version
|
||||
|
||||
def get_cpu_mem_used(self, vra):
|
||||
if vra == None:
|
||||
self.log.debug("Get_cpu_mem_used called with no vm name...returning no data")
|
||||
return
|
||||
if self.__conn__ == None:
|
||||
self.log.debug("Trying to get VRA stats without vCenter connection, trying to connect")
|
||||
self.connect()
|
||||
|
||||
# get the root folder of the vCenter Server
|
||||
try:
|
||||
content = self.__conn__.RetrieveContent()
|
||||
root_folder = content.rootFolder
|
||||
except:
|
||||
self.log.debug("Could not get content from vCenter when trying to get VRA stats")
|
||||
|
||||
# create a view for all VMs on the vCenter Server
|
||||
view_manager = content.viewManager
|
||||
vm_view = view_manager.CreateContainerView(root_folder, [vim.VirtualMachine], True)
|
||||
|
||||
vm = None
|
||||
for vm_obj in vm_view.view:
|
||||
if str(vm_obj.name) == str(vra):
|
||||
vm = vm_obj
|
||||
if vm is not None:
|
||||
self.log.debug(f"Found VRA VM in vCenter with name {vm.name}")
|
||||
# get the CPU usage and memory usage for the VM
|
||||
cpu_usage_mhz = vm.summary.quickStats.overallCpuUsage
|
||||
memory_usage_mb = vm.summary.quickStats.guestMemoryUsage
|
||||
|
||||
# print the CPU and memory usage for the VM
|
||||
self.log.info(f"VM {vm.name} has CPU usage of {cpu_usage_mhz} MHz and memory usage of {memory_usage_mb} MB")
|
||||
return [cpu_usage_mhz, memory_usage_mb]
|
||||
else:
|
||||
self.log.debug(f"{vm_obj.name} is not a VRA")
|
||||
raise ValueError("No VRA Found")
|
||||
|
||||
def get_write_iops(self, vm):
|
||||
try:
|
||||
content = self.__conn__.RetrieveContent()
|
||||
except:
|
||||
self.log.debug("Could not get content from vCenter when trying to get VRA stats")
|
||||
|
||||
# Find the virtual machine by name
|
||||
vm_name = str(vm)
|
||||
vm = None
|
||||
|
||||
for obj in content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True).view:
|
||||
if obj.name == vm_name:
|
||||
vm = obj
|
||||
break
|
||||
|
||||
if vm is None:
|
||||
print(f"Virtual machine '{vm_name}' not found")
|
||||
return
|
||||
|
||||
# Get performance manager
|
||||
perf_manager = content.perfManager
|
||||
|
||||
# Define the metric ID for write IOPS (counterId = 6)
|
||||
metric_id = vim.PerformanceManager.MetricId(counterId=6, instance="")
|
||||
|
||||
# calculate the last 60 seconds
|
||||
end_time = datetime.datetime.now()
|
||||
start_time = end_time - datetime.timedelta(seconds=60)
|
||||
|
||||
# Create a query specification for roll-up data
|
||||
query_spec = vim.PerformanceManager.QuerySpec(
|
||||
entity=vm,
|
||||
metricId=[metric_id],
|
||||
format="normal",
|
||||
startTime=start_time,
|
||||
endTime=end_time,
|
||||
intervalId=20, # Use an appropriate interval for the roll-up data
|
||||
)
|
||||
|
||||
|
||||
# Query the performance statistics
|
||||
result = perf_manager.QueryStats(querySpec=[query_spec])
|
||||
|
||||
if result:
|
||||
# Get the average write IOPS for the last 60 seconds
|
||||
average_write_iops = sum(result[0].value[0].value) / len(result[0].value[0].value)
|
||||
print(f"Average write IOPS for the last 60 seconds for {vm_name}: {average_write_iops}")
|
||||
return average_write_iops
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_average_write_latency(self, vm):
|
||||
try:
|
||||
content = self.__conn__.RetrieveContent()
|
||||
except:
|
||||
self.log.debug("Could not get content from vCenter when trying to get VM stats")
|
||||
|
||||
# Find the virtual machine by name
|
||||
vm_name = str(vm)
|
||||
vm = None
|
||||
|
||||
for obj in content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True).view:
|
||||
if obj.name == vm_name:
|
||||
vm = obj
|
||||
break
|
||||
|
||||
if vm is None:
|
||||
self.log.debug(f"Virtual machine '{vm_name}' not found")
|
||||
return None
|
||||
|
||||
# Get performance manager
|
||||
perf_manager = content.perfManager
|
||||
|
||||
# Define the metric ID for write latency (counterId = X) - replace X with the correct counter ID
|
||||
# You'll need to find the specific counter ID for write latency in your vSphere environment.
|
||||
# The counter for write latency may vary based on your configuration.
|
||||
|
||||
metric_id = vim.PerformanceManager.MetricId(counterId=10, instance="") # Replace X with the correct counter ID
|
||||
|
||||
end_time = datetime.datetime.now()
|
||||
start_time = end_time - datetime.timedelta(seconds=60)
|
||||
|
||||
# Create a query specification for roll-up data
|
||||
query_spec = vim.PerformanceManager.QuerySpec(
|
||||
entity=vm,
|
||||
metricId=[metric_id],
|
||||
format="normal",
|
||||
startTime=start_time,
|
||||
endTime=end_time,
|
||||
intervalId=20, # Use an appropriate interval for the roll-up data
|
||||
)
|
||||
|
||||
# Query the performance statistics
|
||||
result = perf_manager.QueryStats(querySpec=[query_spec])
|
||||
|
||||
if result:
|
||||
# Get the average write latency for the last 60 seconds
|
||||
if result[0].value[0].value:
|
||||
average_write_latency = sum(result[0].value[0].value) / len(result[0].value[0].value)
|
||||
self.log.info(f"Average write latency for the last 60 seconds for {vm_name}: {average_write_latency}")
|
||||
return average_write_latency
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def disconnect(self):
|
||||
if self.__conn__ == None:
|
||||
self.log.debug(f"vCenter disconnect requested, but not currently connected.")
|
||||
return
|
||||
# Disconnect from vCenter
|
||||
Disconnect(self.__conn__)
|
||||
self.__conn__ = None
|
||||
self.version = None
|
||||
self.log.debug(f"Disconnected from vCenter")
|
||||
@@ -0,0 +1,10 @@
|
||||
# version.py
|
||||
VERSION = "0.1.0"
|
||||
|
||||
def main():
|
||||
# Put your main program code here
|
||||
print(VERSION)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# This code will be executed only when the file is run as the main program
|
||||
main()
|
||||
Reference in New Issue
Block a user