Skip to content

Commit

Permalink
Merge pull request #86 from josenk/v1.6.1/refresh-fixes
Browse files Browse the repository at this point in the history
v1.6.1 Fix some refesh bugs, allow http(s) ovf sources.
  • Loading branch information
josenk authored Dec 7, 2019
2 parents 6d40cee + 02ef9c1 commit 9242a42
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 68 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Terraform-provider-esxi plugin
>https://configmax.vmware.com/guest



What's New:
-----------
* Terraform can import existing Guest VMs, Virtual Disks & Resource pools by name. See wiki page for more info.
Expand All @@ -71,6 +73,13 @@ Features and Compatibility
* Terraform will Create, Destroy, Update & Read Guest VMs.
* Terraform will Create, Destroy, Update & Read Extra Storage for Guests.

This is a provider! NOT a provisioner.
---------------------------------------
* This plugin does not configure your guest VM, it creates it.
* To configure your guest VM after it's built, you need to use a provisioner.
* Refer to Hashicorp list of provisioners: https://www.terraform.io/docs/provisioners/index.html
* To help you get started, there is are examples in a separate repo I created. You can create a Pull Request if you would like to contribute.
* https://github.com/josenk/terraform-provider-esxi-wiki

Vagrant vs Terraform.
---------------------
Expand Down Expand Up @@ -208,8 +217,10 @@ Known issues with vmware_esxi
* Using an incorrect password could lockout your account using default esxi pam settings.



Version History
---------------
* 1.6.1 Fix some minor refesh bugs, allow http(s) ovf sources.
* 1.6.0 Add support for ovf_properties for OVF/OVA sources.
* 1.5.4 Fix bare-metal build when using additional virtual disks.
* 1.5.3 Fix introduced bug when creating a bare-metal guest.
Expand Down
27 changes: 21 additions & 6 deletions esxi/guest-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"log"
"net/http"
"net/url"
"os"
"os/exec"
Expand Down Expand Up @@ -83,7 +84,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
remote_cmd = fmt.Sprintf("mkdir %s", fullPATH)
stdout, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "create guest path")
if err != nil {
log.Printf("Failed to create guest path. fullPATH:%s\n", fullPATH)
log.Printf("[guestCREATE] Failed to create guest path. fullPATH:%s\n", fullPATH)
return "", fmt.Errorf("Failed to create guest path. fullPATH:%s\n", fullPATH)
}
}
Expand Down Expand Up @@ -167,20 +168,20 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
if err != nil {
remote_cmd = fmt.Sprintf("rm -fr %s", fullPATH)
stdout, _ = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "cleanup guest path because of failed events")
log.Printf("Failed to vmkfstools (make boot disk):%s\n", err.Error())
log.Printf("[guestCREATE] Failed to vmkfstools (make boot disk):%s\n", err.Error())
return "", fmt.Errorf("Failed to vmkfstools (make boot disk):%s\n", err.Error())
}

poolID, err := getPoolID(c, resource_pool_name)
log.Println("[guestCREATE] DEBUG: " + poolID)
if err != nil {
log.Printf("Failed to use Resource Pool ID:%s\n", poolID)
log.Printf("[guestCREATE] Failed to use Resource Pool ID:%s\n", poolID)
return "", fmt.Errorf("Failed to use Resource Pool ID:%s\n", poolID)
}
remote_cmd = fmt.Sprintf("vim-cmd solo/registervm %s %s %s", dst_vmx_file, guest_name, poolID)
_, err = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "solo/registervm")
if err != nil {
log.Printf("Failed to register guest:%s\n", err.Error())
log.Printf("[guestCREATE] Failed to register guest:%s\n", err.Error())
remote_cmd = fmt.Sprintf("rm -fr %s", fullPATH)
stdout, _ = runRemoteSshCommand(esxiSSHinfo, remote_cmd, "cleanup guest path because of failed events")
return "", fmt.Errorf("Failed to register guest:%s\n", err.Error())
Expand All @@ -190,8 +191,22 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
// Build VM by ovftool

// Check if source file exist.
if !strings.HasPrefix(src_path, "vi://") {
if strings.HasPrefix(src_path, "http://") || strings.HasPrefix(src_path, "https://") {
log.Printf("[guestCREATE] Source is URL.\n")
resp, err := http.Get(src_path)
defer resp.Body.Close()
if (err != nil) || (resp.StatusCode != 200) {
log.Printf("[guestCREATE] URL not accessible: %s\n", src_path)
log.Printf("[guestCREATE] URL StatusCode: %s\n", resp.StatusCode)
log.Printf("[guestCREATE] URL Error: %s\n", err.Error())
return "", fmt.Errorf("URL not accessible: %s\n%s", src_path, err.Error())
}
} else if strings.HasPrefix(src_path, "vi://") {
log.Printf("[guestCREATE] Source is Guest VM (vi).\n")
} else {
log.Printf("[guestCREATE] Source is local.\n")
if _, err := os.Stat(src_path); os.IsNotExist(err) {
log.Printf("[guestCREATE] File not found, Error: %s\n", err.Error())
return "", fmt.Errorf("File not found: %s\n", src_path)
}
}
Expand Down Expand Up @@ -275,7 +290,7 @@ func guestCREATE(c *Config, guest_name string, disk_store string,
log.Printf("[guestCREATE] ovftool output: %q\n", out.String())

if err != nil {
log.Printf("Failed, There was an ovftool Error: %s\n%s\n", out.String(), err.Error())
log.Printf("[guestCREATE] Failed, There was an ovftool Error: %s\n%s\n", out.String(), err.Error())
return "", fmt.Errorf("There was an ovftool Error: %s\n%s\n", out.String(), err.Error())
}
}
Expand Down
19 changes: 12 additions & 7 deletions esxi/guest-read.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ func resourceGUESTRead(d *schema.ResourceData, m interface{}) error {
d.Set("ip_address", ip_address)
d.Set("power", power)
d.Set("notes", notes)
d.Set("guestinfo", guestinfo)

if len(guestinfo) != 0 {
d.Set("guestinfo", guestinfo)
}

// Do network interfaces
log.Printf("virtual_networks: %q\n", virtual_networks)
Expand Down Expand Up @@ -223,16 +226,18 @@ func guestREAD(c *Config, vmid string, guest_startup_timeout int) (string, strin
isGeneratedMAC[index] = true
}

case "generatedAddress":
if isGeneratedMAC[index] == true {
virtual_networks[index][1] = results[3]
log.Printf("[guestREAD] %s : %s\n", results[0], results[3])
}
// Done't save generatedAddress... It should not be saved because it
// should be considered dynamic & is breaks the update MAC address code.
//case "generatedAddress":
// if isGeneratedMAC[index] == true {
// virtual_networks[index][1] = results[3]
// log.Printf("[guestREAD] %s : %s\n", results[0], results[3])
// }

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

case "virtualDev":
Expand Down
21 changes: 18 additions & 3 deletions esxi/guest_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,15 @@ func updateVmx_contents(c *Config, vmid string, iscreate bool, memsize int, numv

if virtual_networks[i][0] == "" && strings.Contains(vmx_contents, "ethernet"+strconv.Itoa(i)) == true {
// This is Modify (Delete existing network configuration)
log.Printf("[updateVmx_contents] ethernet%d Delete existing.\n", i)
log.Printf("[updateVmx_contents] Modify ethernet%d - Delete existing.\n", i)
regexReplacement = fmt.Sprintf("")
re := regexp.MustCompile(fmt.Sprintf("ethernet%d.*\n", i))
vmx_contents = re.ReplaceAllString(vmx_contents, regexReplacement)
}

if virtual_networks[i][0] != "" && strings.Contains(vmx_contents, "ethernet"+strconv.Itoa(i)) == true {
// This is Modify
log.Printf("[updateVmx_contents] ethernet%d Modify existing.\n", i)
log.Printf("[updateVmx_contents] Modify ethernet%d - Modify existing.\n", i)

// Modify Network Name
re := regexp.MustCompile("ethernet" + strconv.Itoa(i) + ".networkName = \".*\"")
Expand All @@ -271,7 +271,22 @@ func updateVmx_contents(c *Config, vmid string, iscreate bool, memsize int, numv
regexReplacement = fmt.Sprintf("ethernet"+strconv.Itoa(i)+".virtualDev = \"%s\"", virtual_networks[i][2])
vmx_contents = re.ReplaceAllString(vmx_contents, regexReplacement)

// Modify MAC todo
// Modify MAC (dynamic to static only. static to dynamic is not implemented)
if virtual_networks[i][1] != "" {
log.Printf("[updateVmx_contents] ethernet%d Modify MAC: %s\n", i, virtual_networks[i][0])

re = regexp.MustCompile("ethernet" + strconv.Itoa(i) + ".[a-zA-Z]*ddress = \".*\"")
regexReplacement = fmt.Sprintf("ethernet"+strconv.Itoa(i)+".address = \"%s\"", virtual_networks[i][1])
vmx_contents = re.ReplaceAllString(vmx_contents, regexReplacement)

re = regexp.MustCompile("ethernet" + strconv.Itoa(i) + ".addressType = \".*\"")
regexReplacement = fmt.Sprintf("ethernet" + strconv.Itoa(i) + ".addressType = \"static\"")
vmx_contents = re.ReplaceAllString(vmx_contents, regexReplacement)

re = regexp.MustCompile("ethernet" + strconv.Itoa(i) + ".generatedAddressOffset = \".*\"")
regexReplacement = fmt.Sprintf("")
vmx_contents = re.ReplaceAllString(vmx_contents, regexReplacement)
}
}

if virtual_networks[i][0] != "" && strings.Contains(vmx_contents, "ethernet"+strconv.Itoa(i)) == false {
Expand Down
10 changes: 6 additions & 4 deletions esxi/resource_guest.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func resourceGUEST() *schema.Resource {
Optional: true,
Computed: true,
Description: "The amount of guest uptime, in seconds, to wait for an available IP address on this virtual machine.",
ValidateFunc: validation.IntBetween(1, 600),
ValidateFunc: validation.IntBetween(0, 600),
},
"guest_shutdown_timeout": {
Type: schema.TypeInt,
Expand Down Expand Up @@ -246,18 +246,20 @@ func resourceGUESTCreate(d *schema.ResourceData, m interface{}) error {
notes := d.Get("notes").(string)
power := d.Get("power").(string)

if d.Get("guest_startup_timeout").(int) > 0 {
if d.Get("guest_startup_timeout").(int) >= 0 {
d.Set("guest_startup_timeout", d.Get("guest_startup_timeout").(int))
} else {
d.Set("guest_startup_timeout", 120)
}
if d.Get("guest_shutdown_timeout").(int) > 0 {

if d.Get("guest_shutdown_timeout").(int) >= 0 {
d.Set("guest_shutdown_timeout", d.Get("guest_shutdown_timeout").(int))
guest_shutdown_timeout = d.Get("guest_shutdown_timeout").(int)
} else {
d.Set("guest_shutdown_timeout", 20)
}
if d.Get("ovf_properties_timer").(int) > 0 {

if d.Get("ovf_properties_timer").(int) >= 0 {
d.Set("ovf_properties_timer", d.Get("ovf_properties_timer").(int))
ovf_properties_timer = d.Get("ovf_properties_timer").(int)
} else {
Expand Down
4 changes: 2 additions & 2 deletions examples-legacy/05 CloudInit and Templates/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ provider "esxi" {
#########################################
# cloud-init for vmware!
# You must install it on your source VM before cloning it!
# See https://github.com/akutz/cloud-init-vmware-guestinfo for more details.
# See https://github.com/vmware/cloud-init-vmware-guestinfo for more details.
# and https://cloudinit.readthedocs.io/en/latest/topics/examples.html#
#
#
# yum install https://github.com/akutz/cloud-init-vmware-guestinfo/releases/download/v1.1.0/cloud-init-vmware-guestinfo-1.1.0-1.el7.noarch.rpm
# yum install https://github.com/vmware/cloud-init-vmware-guestinfo/releases/download/v1.1.0/cloud-init-vmware-guestinfo-1.1.0-1.el7.noarch.rpm
# cloud-init clean
#########################################

Expand Down
5 changes: 2 additions & 3 deletions examples/05 CloudInit and Templates/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ provider "esxi" {
#########################################
# cloud-init for vmware!
# You must install it on your source VM before cloning it!
# See https://github.com/akutz/cloud-init-vmware-guestinfo for more details.
# See https://github.com/vmware/cloud-init-vmware-guestinfo for more details.
# and https://cloudinit.readthedocs.io/en/latest/topics/examples.html#
#
#
# yum install https://github.com/akutz/cloud-init-vmware-guestinfo/releases/download/v1.1.0/cloud-init-vmware-guestinfo-1.1.0-1.el7.noarch.rpm
# yum install https://github.com/vmware/cloud-init-vmware-guestinfo/releases/download/v1.1.0/cloud-init-vmware-guestinfo-1.1.0-1.el7.noarch.rpm
# cloud-init clean
#########################################

Expand Down Expand Up @@ -52,4 +52,3 @@ resource "esxi_guest" "Default" {
"userdata" = base64gzip(data.template_file.Default.rendered)
}
}

43 changes: 2 additions & 41 deletions examples/06 OVF Properties/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,13 @@ data "template_file" "userdata_default" {
}

resource "esxi_guest" "vmtest" {
# guest_name - Required - The Guest name.
guest_name = "vmtest"
# guestos # Optional - Default will be taken from cloned source
notes = "ProjectX" # Optional - The Guest notes (annotation).
disk_store = var.disk_store # Required - esxi Disk Store where guest vm will be created
boot_disk_type = "thin" # Optional - Guest boot disk type. Default 'thin'. Available thin, zeroedthick, eagerzeroedthick
boot_disk_size = "30" # Optional - Specify boot disk size or grow cloned vm to this size.
memsize = "4096" # Optional - Memory size in MB. (ie, 1024 == 1GB). See esxi documentation for limits. - Default 512 or default taken from cloned source
numvcpus = "1" # Optional - Number of virtual cpus. See esxi documentation for limits. - Default 1 or default taken from cloned source.
virthwver = "8" # Optional - esxi guest virtual HW version. See esxi documentation for compatible values. - Default 8 or taken from cloned source.
power = "on" # Optional - on, off.
guest_startup_timeout = "90"
guest_name = var.vm_hostname
disk_store = var.disk_store

network_interfaces {
virtual_network = var.virtual_network
}


guestinfo = {
"userdata.encoding" = "gzip+base64"
"userdata" = base64gzip(data.template_file.userdata_default.rendered)
Expand All @@ -60,32 +49,4 @@ resource "esxi_guest" "vmtest" {
key = "user-data"
value = base64encode(data.template_file.userdata_default.rendered)
}


#Array of upto 10 network interfaces.
#virtual_network - Required for each Guest NIC - This is the esxi virtual network name configured on esxi host.
#mac_address - Optional - If not set, mac_address will be generated by esxi.
#nic_type - Optional - See esxi documentation for compatibility list. - Default "e1000" or taken from cloned source.

# Other optionals

# resource_pool_name - Optional - Any existing or terraform managed resource pool name. - Default "/"
# virtual_disks - Optional - Array of additional storage to be added to the guest.
# virtual_disk_id - Required - virtual_disk.id from esxi_virtual_disk resource.
# slot - Required - SCSI_Ctrl:SCSI_id. Range '0:1' to '3:15'. SCSI_id 7 is not allowed.
# guest_startup_timeout - Optional - The amount of guest uptime, in seconds, to wait for an available IP address on this virtual machine.
# guest_shutdown_timeout - Optional - The amount of time, in seconds, to wait for a graceful shutdown before doing a forced power off.

# guestinfo - Optional - The Guestinfo root
# metadata - Optional - A JSON string containing the cloud-init metadata.
# metadata.encoding - Optional - The encoding type for guestinfo.metadata. (base64 or gzip+base64)
# userdata - Optional - A YAML document containing the cloud-init user data.
# userdata.encoding - Optional - The encoding type for guestinfo.userdata. (base64 or gzip+base64)
# vendordata - Optional - A YAML document containing the cloud-init vendor data.
# vendordata.encoding - Optional - The encoding type for guestinfo.vendordata (base64 or gzip+base64)

# /Other optionals

# OUTPUTS
# ip_address - Computed - The IP address reported by VMware tools.
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module terraform-provider-esxi

require (
github.com/hashicorp/terraform v0.12.2
github.com/josenk/terraform-provider-esxi v1.6.0
github.com/josenk/terraform-provider-esxi v1.6.1
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.6.0
v1.6.1

0 comments on commit 9242a42

Please sign in to comment.