added zvma class to module

This commit is contained in:
2023-10-26 19:35:29 -04:00
parent 4781b942f4
commit b51a7bd068
2 changed files with 223 additions and 34 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
print("Initializing zvma10 package...") print("Initializing zvma10 package...")
#from .zvma import zvm #from .zvma import zvm
from .vcenter import vcsite from .vcenter import vcsite
from .zvma import zvmsite
+221 -33
View File
@@ -1,34 +1,59 @@
# Class for holding variables related to a site. # Class for holding variables related to a site.
from pyVim.connect import SmartConnect, Disconnect #from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim, vmodl #from pyVmomi import vim, vmodl
import threading
import atexit
import ssl import ssl
import datetime import datetime
import logging import logging
import requests
from time import sleep
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from requests.structures import CaseInsensitiveDict
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
class zvmsite: class zvmsite:
def __init__(self, host, username, password, clientid="zerto-client", clientsecret=None, port=443, verify_ssl=False, loglevel="INFO"): def __init__(self, host, username=None, password=None, port=443, verify_ssl=False, client_id="zerto-client", client_secret=None, grant_type="password", loglevel="debug"):
self.host = host self.host = host
self.port = port self.port = port
self.username = username self.username = username
self.password = password self.password = password
self.verify_ssl = verify_ssl self.verify_ssl = verify_ssl
self.uri = "https://" + str(self.host) + ":" + str(self.port)
self.clientid = None self.client_id = client_id
self.clientsecret = None self.client_secret = None
self.authtoken = None self.grant_type = grant_type
self.refreshtoken = None
self.id = None self.__auththread__ = None
self.name = None self.token = None
self.expiresIn = 0
self.token_expire_time = None
self.version = None self.site_id = None
self.zvm_version_major = None self.site_name = None
self.zvm_version_minor = None self.site_type = None
self.zvm_version_update = None self.site_type_version = None
self.zvm_version_patch = None
self.__conn__ = None self.zvm_version = dict(
full=None,
major=None,
minor=None,
update=None,
patch=None
)
self.api_version = dict(
major = None,
minor = None,
update = None
)
self.apiheader = CaseInsensitiveDict()
self.apiheader["Accept"] = "application/json"
self.__connected__ = False
self._running = False
self.LOGLEVEL = loglevel.upper() self.LOGLEVEL = loglevel.upper()
#set log line format including container_id #set log line format including container_id
@@ -39,9 +64,27 @@ class zvmsite:
self.log.setLevel(self.LOGLEVEL) self.log.setLevel(self.LOGLEVEL)
self.log.addHandler(log_handler) self.log.addHandler(log_handler)
atexit.register(self.terminate)
self._running = True
def terminate(self):
self.log.debug("Terminating other threads")
self._running = False
self.__auththread__.join()
def connect(self): def connect(self):
if (self.__auththread__ == None) or (not self.__auththread__.is_alive()):
self._running = True
self.__auththread__ = threading.Thread(target=self.__authhandler__)
self.__auththread__.start()
self.log.info(f"Starting authentication thread {self.__auththread__.ident}")
else:
self.log.info("Already connected to the ZVM")
def __authhandler__(self):
self.log.info(f"Log Level set to {self.LOGLEVEL}") self.log.info(f"Log Level set to {self.LOGLEVEL}")
if self.__conn__ is None: if not self.__connected__:
context = ssl.create_default_context() context = ssl.create_default_context()
if not self.verify_ssl: if not self.verify_ssl:
print("dont verify SSL") print("dont verify SSL")
@@ -49,19 +92,139 @@ class zvmsite:
context.check_hostname = False context.check_hostname = False
context.verify_mode = ssl.CERT_NONE context.verify_mode = ssl.CERT_NONE
# connect to vCenter Server
si = None
try: try:
self.__conn__ = SmartConnect(host=self.host, user=self.username, pwd=self.password, sslContext=context) # connect to zvm Server
about_info = self.__conn__.content.about retries = 0
version = about_info.version while self._running:
self.version = version if self.expiresIn < 30:
self.log.debug("Connected to vCenter Server %s", self.host) self.log.debug(f"Trying login with the following: grant_type: {self.grant_type}, username: {self.username}, password: {self.password}, client_id: {self.client_id}")
except Exception as e: h = CaseInsensitiveDict()
self.log.error(f"Error connecting to vCenter Server: {e}") h["Content-Type"] = "application/x-www-form-urlencoded"
d = CaseInsensitiveDict()
d["grant_type"] = self.grant_type
if self.grant_type == "password":
d["client_id"] = self.client_id
d["username"] = self.username
d["password"] = self.password
elif self.grant_type == "client_credentials":
d["client_id"] = self.client_id
d["client_secret"] = self.client_secret
else:
self.__connected__ = False
self.log.error(f"Error connection credentials not defined")
uri = "https://" + str(self.host) + ":" + str(self.port) + "/auth/realms/zerto/protocol/openid-connect/token"
delay = 0
try:
response = requests.post(url=uri, data=d, headers=h, verify=self.verify_ssl)
response.raise_for_status()
except requests.exceptions.RequestException as e:
retries += 1
delay = 2 ** retries
self.log.error("Error while sending authentication request: " + str(e) + ". Retrying in " + str(delay) + " seconds")
sleep(delay)
continue
else:
retries = 0
responseJSON = response.json()
if 'access_token' not in responseJSON or 'expires_in' not in responseJSON:
self.log.error("Authentication response does not contain expected keys")
delay = 2 ** retries
self.__connected__ = False
sleep(delay)
retries += 1
continue
self.token = str(responseJSON.get('access_token'))
self.apiheader["Authorization"] = "Bearer " + self.token
self.expiresIn = int(responseJSON.get('expires_in'))
self.log.info("Authentication successful. Token expires in " + str(self.expiresIn) + " seconds")
self.__connected__ = True
if response.status_code != 200:
self.log.error("Authentication request failed with status code " + str(response.status_code))
delay = 2 ** retries
self.__connected__ = False
sleep(delay)
retries += 1
continue
self.log.debug("Connected to ZVM Server %s", self.host)
else:
if not self._running:
self.__auththread__.terminate()
self.log.debug(f"Time till token expiration: {self.expiresIn} seconds")
self.log.debug(f"Current auth token: {self.token}")
sleep(10)
self.expiresIn = self.expiresIn - 10
except Exception as e:
self.__connected__ = False
self.log.error(f"Error connecting to ZVM Server: {e}")
def __set_zvm_version__(self):
# Get Site ID and Name
uri = self.uri + "/v1/localsite"
delay = 0
try:
self.log.debug("Getting Site ID and Name")
response = requests.get(url=uri, timeout=3, headers=self.apiheader, verify=self.verify_ssl)
response.raise_for_status()
except requests.exceptions.RequestException as e:
retries += 1
delay = 2 ** retries
self.log.error("Error while sending api request: " + str(e))
else:
retries = 0
responseJSON = response.json()
self.log.debug(responseJSON)
if 'SiteIdentifier' not in responseJSON or 'SiteName' not in responseJSON:
self.log.error("LocalSite API response does not contain expected keys")
delay = 2 ** retries
#sleep(delay)
retries += 1
else:
self.site_id = str(responseJSON.get('SiteIdentifier'))
self.site_name = str(responseJSON.get('SiteName'))
self.zvm_version['full'] = str(responseJSON.get('Version'))
self.site_type_version = str(responseJSON.get('SiteTypeVersion'))
self.site_type = str(responseJSON.get('SiteType'))
# Break out ZVM version strings
self.zvm_version['major'], self.zvm_version['minor'], temp = self.zvm_version['full'].split(".")
self.zvm_version['update'] = temp[0]
if (len(temp) > 1):
self.zvm_version['patch'] = temp[1]
else:
self.zvm_version['patch'] = "0"
self.log.info("Site ID: " + self.site_id + " Site Name: " + self.site_name + " Site Type: " + self.site_type )
def version(self): def version(self):
return self.version if self.__connected__ and self._running:
if self.zvm_version['full'] == None:
self.__set_zvm_version__()
return self.zvm_version
else:
return "Error: Not Connected to ZVM"
'''
def set_version(self):
# Set main zvm version variable
self.zvm_version = value
# Break out ZVM version string into Major, Minor, Update, Patch variables
self.zvm_version_major, self.zvm_version_minor, temp = self.zvm_version.split(".")
self.zvm_version_update = temp[0]
if (len(temp) > 1):
self.zvm_version_patch = temp[1]
else:
self.zvm_version_patch = "0"
def get_cpu_mem_used(self, vra): def get_cpu_mem_used(self, vra):
if vra == None: if vra == None:
@@ -203,13 +366,38 @@ class zvmsite:
return None return None
'''
def disconnect(self): def disconnect(self):
if self.__conn__ == None: if self._running == False:
self.log.debug(f"vCenter disconnect requested, but not currently connected.") self.log.debug(f"ZVM disconnect requested, but not currently connected.")
return return
# Disconnect from vCenter
Disconnect(self.__conn__) self.terminate()
self.__conn__ = None # clear class variables
self.version = None self._running = False
self.log.debug(f"Disconnected from vCenter") self.__connected__ = False
self.__auththread__ = None
self.token = None
self.expiresIn = 0
self.token_expire_time = None
self.site_id = None
self.site_name = None
self.site_type = None
self.site_type_version = None
self.zvm_version = dict(
major=None,
minor=None,
update=None,
patch=None
)
self.api_version = dict(
major = None,
minor = None,
update = None
)
self.log.debug(f"Disconnected from ZVM")