Skip to content

Commit

Permalink
[fix #1604]Add support for applying existing customization specs to r…
Browse files Browse the repository at this point in the history
…/virtual_machine

- added `vsphere_guest_os_customization` data source for existing customization specs
- added `vsphere_guest_os_customization` resource for CRUD operations on
  customization specs
- added customization_spec attribute to VirtualMachineCloneSchema to
  enable `vsphere_guest_os_customization` usage on VM clone
- virtual machine customization and guest os customization are using the
  same code for expanding/flattening specs sent to API
- deleted the file containing the common code regarding guest OS
  customizations shared between VM and customizations
- created e2e tests
- added documentation for `d/vsphere_guest_os_customization` and `r/vsphere_guest_os_customization`

Testing done:
 - `make build`

 - Verified that the folowing e2e tests pass:
   - TestAccResourceVSphereVirtualMachine_cloneWithDifferentHostname
   - TestAccResourceVSphereVirtualMachine_cloneCustomizeWithNewResourcePool
   - TestAccResourceVSphereVirtualMachine_cloneWithDifferentTimezone
   - TestAccResourceVSphereVirtualMachine_cloneCustomizeForceNewWithDatastore
 - Verified that the newly introduced e2e tests pass

Signed-off-by: Vasil Atanasov <[email protected]>
  • Loading branch information
vasilsatanasov committed Nov 3, 2023
1 parent 9b4a81d commit 4bc9d9f
Show file tree
Hide file tree
Showing 11 changed files with 1,176 additions and 178 deletions.
218 changes: 218 additions & 0 deletions vsphere/data_source_vsphere_guest_os_customization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package vsphere

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/guestoscustomizations"
)

func dataSourceVSphereGuestOSCustomization() *schema.Resource {
return &schema.Resource{
Read: dataSourceVSphereGuestCustomizationRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the Guest OS Customization spec - unique identifier",
},
"type": {
Type: schema.TypeString,
Computed: true,
Description: "The type of the Guest OS Customization spec: Windows/Linux",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "The description of the Guest OS Customization spec",
},
"last_update_time": {
Type: schema.TypeString,
Computed: true,
Description: "The time of last modification of the Guest OS Customization spec",
},
"change_version": {
Type: schema.TypeString,
Computed: true,
Description: "The number of last change version of the Guest OS Customization spec",
},
"spec": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_server_list": {
Type: schema.TypeList,
Computed: true,
Description: "The list of DNS servers for a virtual network adapter with a static IP address.",
Elem: &schema.Schema{Type: schema.TypeString},
},
"dns_suffix_list": {
Type: schema.TypeList,
Computed: true,
Description: "A list of DNS search domains to add to the DNS configuration on the virtual machine.",
Elem: &schema.Schema{Type: schema.TypeString},
},
"linux_options": {
Type: schema.TypeList,
Computed: true,
Description: "A list of configuration options specific to Linux virtual machines.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain": {
Type: schema.TypeString,
Computed: true,
Description: "The domain name for this virtual machine.",
},
"host_name": {
Type: schema.TypeString,
Computed: true,
Description: "The hostname for this virtual machine.",
},
"hw_clock_utc": {
Type: schema.TypeBool,
Computed: true,
Description: "Specifies whether or not the hardware clock should be in UTC or not.",
},
"script_text": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
Description: "The customization script to run before and or after guest customization",
},
"time_zone": {
Type: schema.TypeString,
Computed: true,
Description: "Customize the time zone on the VM. This should be a time zone-style entry, like America/Los_Angeles.",
},
},
},
},
"windows_options": {
Type: schema.TypeList,
Computed: true,
Description: "A list of configuration options specific to Windows virtual machines.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"run_once_command_list": {
Type: schema.TypeList,
Computed: true,
Description: "A list of commands to run at first user logon, after guest customization.",
Elem: &schema.Schema{Type: schema.TypeString},
},
// CustomizationGuiUnattended
"auto_logon": {
Type: schema.TypeBool,
Computed: true,
Description: "Specifies whether or not the VM automatically logs on as Administrator.",
},
"auto_logon_count": {
Type: schema.TypeInt,
Computed: true,
Description: "Specifies how many times the VM should auto-logon the Administrator account when auto_logon is true.",
},
"admin_password": {
Type: schema.TypeString,
Computed: true,
Description: "The new administrator password for this virtual machine.",
},
"time_zone": {
Type: schema.TypeInt,
Computed: true,
Description: "The new time zone for the virtual machine. This is a sysprep-dictated timezone code.",
},

// CustomizationIdentification
"join_domain": {
Type: schema.TypeString,
Computed: true,
Description: "The domain that the virtual machine should join.",
},
"domain_admin_user": {
Type: schema.TypeString,
Computed: true,
Description: "The user account of the domain administrator used to join this virtual machine to the domain.",
},
"domain_admin_password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
Description: "The password of the domain administrator used to join this virtual machine to the domain.",
},

"workgroup": {
Type: schema.TypeString,
Computed: true,
Description: "The workgroup for this virtual machine if not joining a domain.",
},
"computer_name": {
Type: schema.TypeString,
Computed: true,
Description: "The hostname for this virtual machine.",
},
},
},
},
"windows_sysprep_text": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
Description: "Use this option to specify a windows sysprep file directly.",
},
"network_interface": {
Type: schema.TypeList,
Computed: true,
Description: "A specification of network interface configuration options.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_server_list": {
Type: schema.TypeList,
Computed: true,
Description: "Network-interface specific DNS settings for Windows operating systems. Ignored on Linux.",
Elem: &schema.Schema{Type: schema.TypeString},
},
"dns_domain": {
Type: schema.TypeString,
Computed: true,
Description: "A DNS search domain to add to the DNS configuration on the virtual machine.",
},
"ipv4_address": {
Type: schema.TypeString,
Computed: true,
Description: "The IPv4 address assigned to this network adapter. If left blank, DHCP is used.",
},
"ipv4_netmask": {
Type: schema.TypeInt,
Computed: true,
Description: "The IPv4 CIDR netmask for the supplied IP address. Ignored if DHCP is selected.",
},
"ipv6_address": {
Type: schema.TypeString,
Computed: true,
Description: "The IPv6 address assigned to this network adapter. If left blank, default auto-configuration is used.",
},
"ipv6_netmask": {
Type: schema.TypeInt,
Computed: true,
Description: "The IPv6 CIDR netmask for the supplied IP address. Ignored if auto-configuration is selected.",
},
},
},
},
},
},
},
},
}
}

func dataSourceVSphereGuestCustomizationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client).vimClient
name := d.Get("name").(string)
specItem, err := guestoscustomizations.FromName(client, name)
if err != nil {
return err
}

d.SetId(name)

return guestoscustomizations.FlattenGuestOsCustomizationSpec(d, specItem)
}
44 changes: 44 additions & 0 deletions vsphere/data_source_vsphere_guest_os_customization_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package vsphere

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"testing"
)

func TestAccDataSourceVSphereGOSC_basic(t *testing.T) {
goscName := acctest.RandomWithPrefix("lin")
resource.Test(t, resource.TestCase{
PreCheck: func() {
RunSweepers()
testAccPreCheck(t)
testAccDataSourceVSphereHostPreCheck(t)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceVSphereGOSCConfig(goscName),
Check: resource.TestCheckResourceAttr("data.vsphere_guest_os_customization.gosc1", "id", goscName),
},
},
})
}

func testAccDataSourceVSphereGOSCConfig(goscName string) string {
return fmt.Sprintf(`
resource "vsphere_guest_os_customization" "source" {
name = %q
type = "Linux"
spec {
linux_options {
domain = "Linux-Host-Domain"
host_name = "Linux-Host-Name"
}
}
}
data "vsphere_guest_os_customization" "gosc1" {
name = vsphere_guest_os_customization.source.id
}
`, goscName)
}
Loading

0 comments on commit 4bc9d9f

Please sign in to comment.