From 4fc8d3b7e759945ad47887a3b5a8d636d24433f5 Mon Sep 17 00:00:00 2001 From: Jonathan Senkerik Date: Mon, 8 May 2017 11:26:25 -0400 Subject: [PATCH] Add support for MAC address and ISO search --- README.md | 7 ++-- esxi-vm-create | 92 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index cc26bfe..b199edc 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,11 @@ Usage By default the Disk Store is set to "LeastUsed". This will use the Disk Store with the most free space (in bytes). - By default the ISO and Network are set to "None". + By default the ISO is set to "None". Specify the full path to the ISO image. If you specify just the ISO image (no path), the system will attempt to find the ISO image on the DataStores. - By default the VM is powered on. If an ISO was specified, then it will boot the ISO image. Otherwise, the VM will attempt a PXE boot. Use COBBLER, Foreman, Razor, or your favorite provisioning tools. + By default the Network set set to "None". A full or partial MAC address can be specified. A partial MAC address argument would be 3 Hex pairs which would then be prepended by VMware's OEM "00:50:56". + + By default the VM is powered on. If an ISO was specified, then it will boot the ISO image. Otherwise, the VM will attempt a PXE boot if a Network Interface was specified. You could customize the ISO image to specify the kickstart file, or PXE boot using COBBLER, Foreman, Razor, or your favorite provisioning tool. Requirements @@ -61,6 +63,7 @@ Command Line Args -s SIZE, --size SIZE Size of virt disk (20) -i ISO, --iso ISO CDROM ISO Path | None (None) -N NET, --net NET Network Interface | None (None) + -M MAC, --MAC MAC MAC address -S STORE, --store STORE vmfs Store | LeastUsed (DS_3TB_m) -g GUESTOS, --guestos GUESTOS diff --git a/esxi-vm-create b/esxi-vm-create index 881ba08..1b04d24 100755 --- a/esxi-vm-create +++ b/esxi-vm-create @@ -31,7 +31,8 @@ NET = ConfigData['NET'] ISO = ConfigData['ISO'] GUESTOS = ConfigData['GUESTOS'] - +MAC = "" +GeneratedMAC = "" # # Process Arguments @@ -49,6 +50,7 @@ parser.add_argument("-m", "--mem", type=int, help="Memory in GB (" + str(MEM) + parser.add_argument("-s", "--size", dest='SIZE', type=str, help="Size of virt disk (" + str(SIZE) + ")") parser.add_argument("-i", "--iso", dest='ISO', type=str, help="CDROM ISO Path | None (" + str(ISO) + ")") parser.add_argument("-N", "--net", dest='NET', type=str, help="Network Interface | None (" + str(NET) + ")") +parser.add_argument("-M", "--MAC", dest='MAC', type=str, help="MAC address") parser.add_argument("-S", "--store", dest='STORE', type=str, help="vmfs Store | LeastUsed (" + str(STORE) + ")") parser.add_argument("-g", "--guestos", dest='GUESTOS', type=str, help="Guest OS. (" + str(GUESTOS) + ")") parser.add_argument("-u", "--updateDefaults", dest='UPDATE', action='store_true', help="Update Default VM settings stored in ~/.esxi-vm.yml") @@ -77,6 +79,8 @@ if args.ISO: ISO=args.ISO if args.NET: NET=args.NET +if args.MAC: + MAC=args.MAC if args.STORE: STORE=args.STORE if STORE == "": @@ -121,11 +125,13 @@ try: (stdin, stdout, stderr) = ssh.exec_command("esxcli system version get |grep Version") type(stdin) - if re.match("Version", stdout.readlines()) is not None: - print "Unable to access ESXi Host: %s, username: %s" % (HOST, USER) + if re.match("Version", str(stdout.readlines())) is not None: + print "Unable to determine if this is a ESXi Host: %s, username: %s" % (HOST, USER) sys.exit(1) except: - pass + print "The Error is " + str(sys.exc_info()[0]) + print "Unable to access ESXi Host: %s, username: %s" % (HOST, USER) + sys.exit(1) # # Get list of DataStores, store in VOLUMES @@ -140,8 +146,7 @@ try: VOLUMES[splitLine[0]] = splitLine[1] LeastUsedDS = splitLine[1] except: - e = sys.exc_info()[0] - print "The Error is " + str(e) + print "The Error is " + str(sys.exc_info()[0]) sys.exit(1) if STORE == "LeastUsed": @@ -159,10 +164,24 @@ try: splitLine = re.split(',|\n', line) VMNICS.append(splitLine[0]) except: - e = sys.exc_info()[0] - print "The Error is " + str(e) + print "The Error is " + str(sys.exc_info()[0]) sys.exit(1) +# +# Check MAC address +# +if MAC != "": + MACregex = '^([a-fA-F0-9]{2}[:|\-]){5}[a-fA-F0-9]{2}$' + if re.compile(MACregex).search(MAC): + # Full MAC found. OK + MAC = MAC.replace("-",":") + elif re.compile(MACregex).search("00:50:56:" + MAC): + MAC="00:50:56:" + MAC.replace("-",":") + else: + print "ERROR: " + MAC + " Invalid MAC address." + CheckHasErrors = True + + # # Get from ESXi host if ISO exists # @@ -171,23 +190,23 @@ if ISO == "None": ISO = "" if ISO != "": try: + + # If ISO has no "/", try to find the ISO + if not re.match('/', ISO): + (stdin, stdout, stderr) = ssh.exec_command("find /vmfs/volumes/ -type f -name " + ISO + " -exec sh -c 'echo $1; kill $PPID' sh {} 2>/dev/null \;") + type(stdin) + FoundISOPath = str(stdout.readlines()[0]).strip('\n') + if isVerbose: + print "FoundISOPath: " + str(FoundISOPath) + ISO = str(FoundISOPath) + (stdin, stdout, stderr) = ssh.exec_command("ls " + str(ISO)) type(stdin) if stdout.readlines() and not stderr.readlines(): ISOfound = True - else: - # If ISO has no "/", try to find the ISO - if not re.match('/', ISO): - #(stdin, stdout, stderr) = ssh.exec_command("find /vmfs/volumes/ -type f -name " + ISO + "-exec sh -c 'echo $1; kill $PPID' sh {} 2>/dev/null \;") - (stdin, stdout, stderr) = ssh.exec_command("find /vmfs/volumes/ -type f -name " + ISO ) - type(stdin) - FoundISOPath = str(stdout.readlines()) - print "FoundISOPath: " + str(FoundISOPath) - if re.match('/', FoundISOPath): - ISO = FoundISOPath + except: - e = sys.exc_info()[0] - print "The Error is " + str(e) + print "The Error is " + str(sys.exc_info()[0]) sys.exit(1) # # Check if VM already exists @@ -203,8 +222,7 @@ try: print "ERROR: VM " + NAME + " already exists." CheckHasErrors = True except: - e = sys.exc_info()[0] - print "The Error is " + str(e) + print "The Error is " + str(sys.exc_info()[0]) sys.exit(1) # @@ -316,12 +334,14 @@ if NET != "None": VMX.append('ethernet0.virtualDev = "vmxnet3"') VMX.append('ethernet0.present = "TRUE"') VMX.append('ethernet0.networkName = "' + NET + '"') - VMX.append('ethernet0.addressType = "generated"') + if MAC == "": + VMX.append('ethernet0.addressType = "generated"') + else: + VMX.append('ethernet0.addressType = "static"') + VMX.append('ethernet0.address = "' + MAC + '"') -if isDryRun: - print "Dry Run Enabled. No VM created..." - sys.exit(0) -else: + +if not isDryRun: try: # Create NAME.vmx @@ -345,8 +365,7 @@ else: print "Register VM" (stdin, stdout, stderr) = ssh.exec_command("vim-cmd solo/registervm " + MyVM + ".vmx") type(stdin) - Jnk = stdout.readlines() - VMID = int(Jnk[0]) + VMID = int(stdout.readlines()[0]) # Power on VM if isVerbose: @@ -361,7 +380,18 @@ else: sys.exit(1) # Print Summary -print "\nCreate VM Success" +if isDryRun: + print "\nDry Run summary:" + if MAC != "": + GeneratedMAC = MAC +else: + print "\nCreate VM Success:" + + if NET != "None": + (stdin, stdout, stderr) = ssh.exec_command("grep -i 'ethernet0.*ddress = ' " + MyVM + ".vmx |tail -1|awk '{print $NF}'") + type(stdin) + GeneratedMAC = str(stdout.readlines()[0]).strip('\n"') + print "ESXi Host: " + HOST print "VM NAME: " + NAME print "vCPU: " + str(CPU) @@ -370,7 +400,7 @@ print "VM Disk: " + str(SIZE) + "GB" if isVerbose: print "Format: " + DISKFORMAT print "DS Store: " + DSSTORE -print "Network: " + NET +print "Network: " + NET + " (" + GeneratedMAC + ")" if ISO: print "ISO: " + ISO if isVerbose: