Skip to content

Commit

Permalink
v1.0.1, Validate DiskStores and esxi Creds
Browse files Browse the repository at this point in the history
Former-commit-id: 1c4a9fb
  • Loading branch information
josenk committed Aug 28, 2018
1 parent 8cf68cf commit f4d4c39
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 39 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ Known issues with vmware_esxi

Version History
---------------
* 1.0.1 Validate DiskStores and refresh
* 1.0.0 First Major release
* 0.1.2 Add ability to manage existing Guest VMs. A lot of code cleanup, various fixes, more validation.
* 0.1.0 Add virtual_disk resource.
* 0.0.8 Add virthwver.
Expand Down
15 changes: 13 additions & 2 deletions esxi/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package esxi

import (
//"fmt"
//"log"
"fmt"
"log"
)

type Config struct {
Expand All @@ -13,5 +13,16 @@ type Config struct {
}

func (c *Config) validateEsxiCreds() error {
esxiSSHinfo := SshConnectionStruct{c.esxiHostName, c.esxiHostPort, c.esxiUserName, c.esxiPassword}
log.Printf("[validateEsxiCreds]\n")

var remote_cmd string
var err error

remote_cmd = fmt.Sprintf("vmware --version")
_, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "Connectivity test, get vmware version")
if err != nil {
return fmt.Errorf("Failed to connect to esxi host: %s\n", err)
}
return nil
}
18 changes: 9 additions & 9 deletions esxi/guest-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
//
// Check if Disk Store already exists
//
remote_cmd = fmt.Sprintf("ls -d \"/vmfs/volumes/%s\"", disk_store)
_, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "check if disk_store already exists.")
err = diskStoreValidate(c, disk_store)
if err != nil {
return "", fmt.Errorf("Disk Store does not exists :%s\n", disk_store)
return "", err
}


//
// Check if guest already exists
//
Expand All @@ -46,7 +46,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,

if vmid != "" {
// We don't need to create the VM. It already exists.
fmt.Printf("[provider-esxi] guest %s already exists vmid: \n",guest_name, stdout)
fmt.Printf("[guestCREATE] guest %s already exists vmid: \n",guest_name, stdout)

//
// Power off guest if it's powered on.
Expand Down Expand Up @@ -145,7 +145,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
//
// Write vmx file to esxi host
//
log.Printf("[provider-esxi] New guest_name.vmx: %s\n", vmx_contents)
log.Printf("[guestCREATE] New guest_name.vmx: %s\n", vmx_contents)

dst_vmx_file := fmt.Sprintf("%s/%s.vmx", fullPATH, guest_name)

Expand All @@ -163,7 +163,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
}

poolID, err := getPoolID(c, resource_pool_name)
log.Println("[provider-esxi] DEBUG: " + poolID)
log.Println("[guestCREATE] DEBUG: " + poolID)
if err != nil {
log.Printf("Failed to use Resource Pool ID:%s\n", poolID)
return "", fmt.Errorf("Failed to use Resource Pool ID:%s\n", poolID)
Expand All @@ -186,11 +186,11 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
"-dm=%s --name='%s' --overwrite -ds='%s' '%s' '%s'",boot_disk_type, guest_name, disk_store, src_path, dst_path)
cmd := exec.Command("/bin/bash", "-c", ovf_cmd)

log.Println("[provider-esxi] ovf_cmd: " + ovf_cmd )
log.Println("[guestCREATE] ovf_cmd: " + ovf_cmd )

cmd.Stdout = &out
err = cmd.Run()
log.Printf("[provider-esxi] ovftool output: %q\n", out.String())
log.Printf("[guestCREATE] ovftool output: %q\n", out.String())
if err != nil {
log.Printf("Failed, There was an ovftool Error:%s\n", err.Error())
return "", fmt.Errorf("There was an ovftool Error:%s\n", err.Error())
Expand All @@ -203,7 +203,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
"tail -1", guest_name, guest_name)

vmid, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "get vmid")
log.Printf("[provider-esxi] get_vmid_cmd: %s\n", vmid)
log.Printf("[guestCREATE] get_vmid_cmd: %s\n", vmid)
if err != nil {
log.Printf("Failed get vmid: %s\n", err)
return "", fmt.Errorf("Failed get vmid: %s\n", err)
Expand Down
4 changes: 2 additions & 2 deletions esxi/guest-delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ func resourceGUESTDelete(d *schema.ResourceData, m interface{}) error {
// remove storage from vmx so it doesn't get deleted by the vim-cmd destroy
err = cleanStorageFromVmx(c, vmid)
if err != nil {
log.Printf("[provider-esxi] Failed clean storage from vmid: %s (to be deleted)\n", vmid)
log.Printf("[resourceGUESTDelete] Failed clean storage from vmid: %s (to be deleted)\n", vmid)
}

remote_cmd = fmt.Sprintf("vim-cmd vmsvc/destroy %s", vmid)
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "vmsvc/destroy")
if err != nil {
// todo more descriptive err message
log.Printf("[provider-esxi] Failed destroy vmid: %s\n", stdout)
log.Printf("[resourceGUESTDelete] Failed destroy vmid: %s\n", stdout)
return err
}

Expand Down
26 changes: 15 additions & 11 deletions esxi/guest-read.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func resourceGUESTRead(d *schema.ResourceData, m interface{}) error {
var power string

guest_name, disk_store, disk_size, resource_pool_name, memsize, numvcpus, virthwver, guestos, ip_address, virtual_networks, power, err := guestREAD(c, d.Id(), guest_startup_timeout)
if err != nil {
if err != nil || guest_name == "" {
d.SetId("")
return nil
}
Expand Down Expand Up @@ -68,6 +68,10 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin
remote_cmd := fmt.Sprintf("vim-cmd vmsvc/get.summary %s", vmid)
stdout, err := runRemoteSshCommand(esxiSSHinfo, remote_cmd, "Get Guest summary")

if strings.Contains(stdout, "Unable to find a VM corresponding") {
return "", "", "", "", "", "", "", "", "", virtual_networks, "", nil
}

scanner := bufio.NewScanner(strings.NewReader(stdout))
for scanner.Scan() {
switch {
Expand Down Expand Up @@ -109,8 +113,8 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin

dst_vmx_file = "/vmfs/volumes/" + dst_vmx_ds + "/" + dst_vmx

log.Printf("[provider-esxi] dst_vmx_file: %s\n", dst_vmx_file)
log.Printf("[provider-esxi] disk_store: %s dst_vmx_ds:%s\n", disk_store, dst_vmx_file)
log.Printf("[resourceGUESTRead] dst_vmx_file: %s\n", dst_vmx_file)
log.Printf("[resourceGUESTRead] disk_store: %s dst_vmx_ds:%s\n", disk_store, dst_vmx_file)

remote_cmd = fmt.Sprintf("cat \"%s\"", dst_vmx_file)
vmx_contents, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "read guest_name.vmx file")
Expand All @@ -128,26 +132,26 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin
stdout = r.FindString(scanner.Text())
nr = strings.NewReplacer(`"`,"", `"`,"")
memsize = nr.Replace(stdout)
log.Printf("[provider-esxi] memsize found: %s\n", memsize)
log.Printf("[resourceGUESTRead] memsize found: %s\n", memsize)

case strings.Contains(scanner.Text(),"numvcpus = "):
r,_ = regexp.Compile(`\".*\"`)
stdout = r.FindString(scanner.Text())
nr = strings.NewReplacer(`"`,"", `"`,"")
numvcpus = nr.Replace(stdout)
log.Printf("[provider-esxi] numvcpus found: %s\n", numvcpus)
log.Printf("[resourceGUESTRead] numvcpus found: %s\n", numvcpus)

case strings.Contains(scanner.Text(),"virtualHW.version = "):
r,_ = regexp.Compile(`\".*\"`)
stdout = r.FindString(scanner.Text())
virthwver = strings.Replace(stdout,`"`,"",-1)
log.Printf("[provider-esxi] virthwver found: %s\n", virthwver)
log.Printf("[resourceGUESTRead] virthwver found: %s\n", virthwver)

case strings.Contains(scanner.Text(),"guestOS = "):
r,_ = regexp.Compile(`\".*\"`)
stdout = r.FindString(scanner.Text())
guestos = strings.Replace(stdout,`"`,"",-1)
log.Printf("[provider-esxi] guestos found: %s\n", guestos)
log.Printf("[resourceGUESTRead] guestos found: %s\n", guestos)

case strings.Contains(scanner.Text(),"ethernet"):
re := regexp.MustCompile("ethernet(.).(.*) = \"(.*)\"")
Expand All @@ -157,7 +161,7 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin
switch results[2] {
case "networkName":
virtual_networks[index][0] = results[3]
log.Printf("[provider-esxi] %s : %s\n", results[0], results[3])
log.Printf("[resourceGUESTRead] %s : %s\n", results[0], results[3])

case "addressType":
if results[3] == "generated" {
Expand All @@ -167,18 +171,18 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin
case "generatedAddress":
if isGeneratedMAC[index] == true {
virtual_networks[index][1] = results[3]
log.Printf("[provider-esxi] %s : %s\n", results[0], results[3])
log.Printf("[resourceGUESTRead] %s : %s\n", results[0], results[3])
}

case "address":
if isGeneratedMAC[index] == false {
virtual_networks[index][1] = results[3]
log.Printf("[provider-esxi] %s : %s\n", results[0], results[3])
log.Printf("[resourceGUESTRead] %s : %s\n", results[0], results[3])
}

case "virtualDev":
virtual_networks[index][2] = results[3]
log.Printf("[provider-esxi] %s : %s\n", results[0], results[3])
log.Printf("[resourceGUESTRead] %s : %s\n", results[0], results[3])
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions esxi/guest_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func getBootDiskPath(c *Config, vmid string) (string, error) {
remote_cmd = fmt.Sprintf("vim-cmd vmsvc/device.getdevices %s | grep -A10 'key = 2000'|grep -m 1 fileName", vmid)
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "get boot disk")
if err != nil {
log.Printf("[provider-esxi] Failed get boot disk path: %s\n", stdout)
log.Printf("[getBootDiskPath] Failed get boot disk path: %s\n", stdout)
return "Failed get boot disk path:", err
}
r := strings.NewReplacer("fileName = \"[", "/vmfs/volumes/",
Expand Down Expand Up @@ -72,9 +72,12 @@ func updateVmx_contents(c *Config, vmid string, iscreate bool, memsize int, numv

vmx_contents, err := readVmx_contents(c, vmid)
if err != nil {
log.Printf("[provider-esxi] Failed get vmx contents: %s\n", err)
log.Printf("[updateVmx_contents] Failed get vmx contents: %s\n", err)
return err
}
if strings.Contains(vmx_contents, "Unable to find a VM corresponding") {
return nil
}

// modify memsize
if memsize != 0 {
Expand Down Expand Up @@ -134,12 +137,12 @@ func updateVmx_contents(c *Config, vmid string, iscreate bool, memsize int, numv
networkType = ""

for i := 0; i < 4; i++ {
log.Printf("[provider-esxi] i: %s\n", i)
log.Printf("[updateVmx_contents] i: %s\n", i)

if virtual_networks[i][0] != "" {

// Set virtual_network name
log.Printf("[provider-esxi] virtual_networks[i][0]: %s\n", virtual_networks[i][0])
log.Printf("[updateVmx_contents] virtual_networks[i][0]: %s\n", virtual_networks[i][0])
tmpvar = fmt.Sprintf("ethernet%d.networkName = \"%s\"\n", i, virtual_networks[i][0])
vmx_contents_new = vmx_contents_new + tmpvar

Expand Down Expand Up @@ -211,7 +214,7 @@ func updateVmx_contents(c *Config, vmid string, iscreate bool, memsize int, numv
// Write vmx file to esxi host
//
vmx_contents = strings.Replace(vmx_contents, "\"", "\\\"", -1)
log.Printf("[provider-esxi] New guest_name.vmx: %s\n", vmx_contents)
log.Printf("[updateVmx_contents] New guest_name.vmx: %s\n", vmx_contents)

dst_vmx_file,err := getDst_vmx_file(c, vmid)
remote_cmd = fmt.Sprintf("echo \"%s\" >%s", vmx_contents, dst_vmx_file)
Expand All @@ -230,7 +233,7 @@ func cleanStorageFromVmx(c *Config, vmid string) error {

vmx_contents, err := readVmx_contents(c, vmid)
if err != nil {
log.Printf("[provider-esxi] Failed get vmx contents: %s\n", err)
log.Printf("[updateVmx_contents] Failed get vmx contents: %s\n", err)
return err
}

Expand Down Expand Up @@ -324,6 +327,9 @@ func guestPowerGetState(c *Config, vmid string) string {

remote_cmd := fmt.Sprintf("vim-cmd vmsvc/power.getstate %s", vmid)
stdout, _ := runRemoteSshCommand(esxiSSHinfo, remote_cmd, "vmsvc/power.getstate")
if strings.Contains(stdout, "Unable to find a VM corresponding") {
return "Unknown"
}

if strings.Contains(stdout, "Powered off") == true {
return "off"
Expand Down
6 changes: 3 additions & 3 deletions esxi/resource-pool_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ func resourcePoolRead(c *Config, pool_id string) (string, int, string, int, stri
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "resource pool_config_get")

if strings.Contains(stdout, "deleted") == true {
log.Printf("[provider-esxi] Already deleted: %s\n", err)
log.Printf("[resourcePoolRead] Already deleted: %s\n", err)
return "", 0, "", 0, "", 0, "", 0, "", nil
}
if err != nil {
log.Printf("[provider-esxi] Failed to get %s: %s\n", "resource pool_config_get", err)
log.Printf("[resourcePoolRead] Failed to get %s: %s\n", "resource pool_config_get", err)
return "", 0, "", 0, "", 0, "", 0, "", errors.New("Failed to get Resource Pool config.")
}

Expand Down Expand Up @@ -165,7 +165,7 @@ func resourcePoolRead(c *Config, pool_id string) (string, int, string, int, stri

resource_pool_name, err := getPoolNAME(c, pool_id)
if err != nil {
log.Printf("[provider-esxi] Failed to get Resource Pool name: %s\n", err)
log.Printf("[resourcePoolRead] Failed to get Resource Pool name: %s\n", err)
return "", 0, "", 0, "", 0, "", 0, "", errors.New("Failed to get Resource Pool name.")
}

Expand Down
3 changes: 2 additions & 1 deletion esxi/virtual-disk_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ func resourceVIRTUALDISKCreate(d *schema.ResourceData, m interface{}) error {
if err == nil {
d.SetId(virtdisk_id)
} else {
log.Println("[provider-esxi] Error: " + err.Error())
log.Println("[resourceVIRTUALDISKCreate] Error: " + err.Error())
d.SetId("")
return fmt.Errorf("Failed to create virtual Disk :%s\n", virtual_disk_name)
}

return nil
Expand Down
47 changes: 43 additions & 4 deletions esxi/virtual-disk_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,43 @@ import (
"errors"
)

//
// Validate Disk Store
//
func diskStoreValidate(c *Config, disk_store string) error {
esxiSSHinfo := SshConnectionStruct{c.esxiHostName, c.esxiHostPort, c.esxiUserName, c.esxiPassword}
log.Printf("[diskStoreValidate]\n")

var remote_cmd, stdout string
var err error

//
// Check if Disk Store already exists
//
remote_cmd = fmt.Sprintf("esxcli storage filesystem list | grep '/vmfs/volumes/.*[VMFS|NFS]' | awk '{print $2}'")
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "Get list of disk stores")
if err != nil {
return fmt.Errorf("Unable to get list of disk stores :%s\n", err)
}
log.Printf("1: Available Disk Stores :%s\n", strings.Replace(stdout, "\n", " ", -1))

if strings.Contains(stdout, disk_store) == false {
remote_cmd = fmt.Sprintf("esxcli storage filesystem rescan")
_, _ = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "Refresh filesystems")

remote_cmd = fmt.Sprintf("esxcli storage filesystem list | grep '/vmfs/volumes/.*[VMFS|NFS]' | awk '{print $2}'")
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "Get list of disk stores")
if err != nil {
return fmt.Errorf("Unable to get list of disk stores :%s\n", err)
}
log.Printf("2: Available Disk Stores :%s\n", strings.Replace(stdout, "\n", " ", -1))

if strings.Contains(stdout, disk_store) == false {
return fmt.Errorf("Disk Store %s does not exist.\nAvailable Disk Stores :%s\n", disk_store, stdout)
}
}
return nil
}

//
// Create virtual disk
Expand All @@ -23,10 +60,9 @@ func virtualDiskCREATE(c *Config, virtual_disk_disk_store string, virtual_disk_d
//
// Validate disk store exists
//
remote_cmd = fmt.Sprintf("ls -d \"/vmfs/volumes/%s\"", virtual_disk_disk_store)
_, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "validate disk store exists")
err = diskStoreValidate(c, virtual_disk_disk_store)
if err != nil {
return "", errors.New("virtual_disk_disk_store does not exist.")
return "", err
}

//
Expand Down Expand Up @@ -79,7 +115,7 @@ func growVirtualDisk(c *Config, virtdisk_id string, virtdisk_size string) error

newDiskSize, _ = strconv.Atoi(virtdisk_size)

log.Printf("[provider-esxi] currentDiskSize:%d new_size:%d fullPATH: %s\n", currentDiskSize, newDiskSize, virtdisk_id)
log.Printf("[growVirtualDisk] currentDiskSize:%d new_size:%d fullPATH: %s\n", currentDiskSize, newDiskSize, virtdisk_id)

if currentDiskSize < newDiskSize {
remote_cmd := fmt.Sprintf("/bin/vmkfstools -X %dG \"%s\"", newDiskSize, virtdisk_id)
Expand Down Expand Up @@ -109,6 +145,9 @@ func virtualDiskREAD(c *Config, virtdisk_id string) (string, string, string, int
// Split virtdisk_id into it's variables
s = strings.Split(virtdisk_id, "/")
log.Printf("[virtualDiskREAD] len=%d cap=%d %v\n", len(s), cap(s), s)
if len(s) < 6 {
return "","","",0,"", nil
}
virtual_disk_disk_store = s[3]
virtual_disk_dir = s[4]
virtual_disk_name = s[5]
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.0.0
v1.0.1

0 comments on commit f4d4c39

Please sign in to comment.