#!/usr/bin/python import argparse # Argument parser import time import re # For regex import paramiko # For remote ssh from esxi_vm_functions import * # Defaults and Variable setup ConfigData = setup_config() NAME = "" LOG = ConfigData['LOG'] isDryRun = ConfigData['isDryRun'] isVerbose = ConfigData['isVerbose'] isSummary = ConfigData['isSummary'] HOST = ConfigData['HOST'] PORT = ConfigData['PORT'] USER = ConfigData['USER'] PASSWORD = ConfigData['PASSWORD'] KEY = ConfigData['KEY'] CPU = ConfigData['CPU'] MEM = ConfigData['MEM'] HDISK = int(ConfigData['HDISK']) DISKFORMAT = ConfigData['DISKFORMAT'] VIRTDEV = ConfigData['VIRTDEV'] STORE = ConfigData['STORE'] NET = ConfigData['NET'] ISO = ConfigData['ISO'] GUESTOS = ConfigData['GUESTOS'] ErrorMessages = "" CheckHasErrors = False DSPATH = "" DSSTORE = "" # # Process Arguments # parser = argparse.ArgumentParser(description='ESXi Create VM utility.') parser.add_argument("-H", "--Host", dest='HOST', type=str, help="ESXi Host/IP (" + str(HOST) + ")") parser.add_argument("-T", "--Port", dest='PORT', type=int, help="ESXi Port number (" + str(PORT) + ")") parser.add_argument("-U", "--User", dest='USER', type=str, help="ESXi Host username (" + str(USER) + ")") parser.add_argument("-P", "--Password", dest='PASSWORD', type=str, help="ESXi Host password (*****)") parser.add_argument("-K", "--Key", dest='KEY', type=str, help="ESXi Host connection key (path to private key)") parser.add_argument("-n", "--name", dest='NAME', type=str, help="VM name") parser.add_argument('-V', '--verbose', dest='isVerbosearg', action='store_true', help="Enable Verbose mode (" + str(isVerbose) + ")") parser.add_argument('--summary', dest='isSummaryarg', action='store_true', help="Display Summary (" + str(isSummary) + ")") args = parser.parse_args() if args.isVerbosearg: isVerbose = True if args.isSummaryarg: isSummary = True if args.HOST: HOST = args.HOST if args.PORT: PORT = args.PORT if args.USER: USER = args.USER if args.PASSWORD: PASSWORD = args.PASSWORD if args.KEY: KEY = args.KEY if args.NAME: NAME = args.NAME # # main() # LogOutput = '{' LogOutput += '"datetime":"' + str(the_current_date_time()) + '",' if NAME == "": print("ERROR: Missing required option --name") sys.exit(1) try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(HOST, port=PORT, username=USER, password=PASSWORD, key_filename=KEY) (stdin, stdout, stderr) = ssh.exec_command("esxcli system version get |grep Version") type(stdin) if re.match("Version", str(stdout.readlines())) is not None: print("Unable to determine if this is a ESXi Host: {}, port: {}, username: {}".format(HOST, PORT, USER)) sys.exit(1) except: print("The Error is {}".format(sys.exc_info()[0])) print("Unable to access ESXi Host: {}, port: {}, username: {}".format(HOST, PORT, USER)) sys.exit(1) # # Check if VM exists # VMID = -1 CheckHasWarnings = False try: (stdin, stdout, stderr) = ssh.exec_command("vim-cmd vmsvc/getallvms") type(stdin) for line in stdout.readlines(): splitLine = line.split() if NAME == splitLine[1]: VMID = splitLine[0] JNK = line.split('[')[1] STORE = JNK.split(']')[0] VMDIR = splitLine[3] if VMID == -1: print("Warning: VM {} doesn't exists.".format(NAME)) ErrorMessages += " VM " + NAME + " doesn't exists." CheckHasErrors = True CheckHasWarnings = True except: print("The Error is {}".format(sys.exc_info()[0])) sys.exit(1) # Get List of Volumes, try: (stdin, stdout, stderr) = \ ssh.exec_command("esxcli storage filesystem list |grep '/vmfs/volumes/.*true VMFS' |sort -nk7") type(stdin) VOLUMES = {} for line in stdout.readlines(): splitLine = line.split() VOLUMES[splitLine[0]] = splitLine[1] except: print("The Error is {}".format(sys.exc_info()[0])) sys.exit(1) # Convert STORE to path and visa-versa V = [] for Path in VOLUMES: V.append(VOLUMES[Path]) if STORE == Path or STORE == VOLUMES[Path]: DSPATH = Path DSSTORE = VOLUMES[Path] if CheckHasErrors: Result = "Errors" else: Result = "Success" if not CheckHasErrors: try: CurrentState = "" CurrentStateCounter = 0 while CurrentStateCounter < 10: if isVerbose: print("Get state of VM") (stdin, stdout, stderr) = ssh.exec_command("vim-cmd vmsvc/power.getstate " + str(VMID)) type(stdin) lines = str(stdout.readlines()) + str(stderr.readlines()) if isVerbose: print("power.getstate: {}".format(lines)) if re.search("Powered off", lines): break # Power off VM if isVerbose: print("Power OFF VM") (stdin, stdout, stderr) = ssh.exec_command("vim-cmd vmsvc/power.off " + str(VMID) + " ||echo") type(stdin) lines = str(stdout.readlines()) + str(stderr.readlines()) if isVerbose: print("power.off: {}".format(lines)) CurrentStateCounter += 1 time.sleep(1) # destroy VM if isVerbose: print("Destroy VM") (stdin, stdout, stderr) = ssh.exec_command("vim-cmd vmsvc/destroy " + str(VMID)) type(stdin) lines = str(stdout.readlines()) + str(stderr.readlines()) if isVerbose: print("destroy: {}".format(lines)) except: print("There was an error destroying the VM.") ErrorMessages += " There was an error destroying the VM." CheckHasErrors = True Result = "Fail" # Print Summary # # The output log string LogOutput += '"Host":"' + HOST + '",' LogOutput += '"Name":"' + NAME + '",' LogOutput += '"Store Used":"' + DSPATH + '",' LogOutput += '"Verbose":"' + str(isVerbose) + '",' if ErrorMessages != "": LogOutput += '"Error Message":"' + ErrorMessages + '",' LogOutput += '"Result":"' + Result + '",' LogOutput += '"Completion Time":"' + str(the_current_date_time()) + '"' LogOutput += '}\n' try: with open(LOG, "a+w") as FD: FD.write(LogOutput) except: print("Error writing to log file: {}".format(LOG)) if isSummary: if isVerbose: print("ESXi Host: {}".format(HOST)) print("VM NAME: {}".format(NAME)) print("Path: {}".format(DSSTORE)) else: pass if CheckHasErrors and not CheckHasWarnings: print("Failed") sys.exit(1) else: print("Success") sys.exit(0)