func ExpandVirtualMachineCloneSpec(d *schema.ResourceData, c *govmomi.Client) (types.VirtualMachineCloneSpec, *object.VirtualMachine, error) {
	var spec types.VirtualMachineCloneSpec
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Preparing clone spec for VM")

	// Populate the datastore only if we have a datastore ID. The ID may not be
	// specified in the event a datastore cluster is specified instead.
	if dsID, ok := d.GetOk("datastore_id"); ok {
		ds, err := datastore.FromID(c, dsID.(string))
		if err != nil {
			return spec, nil, fmt.Errorf("error locating datastore for VM: %s", err)
		}
		spec.Location.Datastore = types.NewReference(ds.Reference())
	}

	tUUID := d.Get("clone.0.template_uuid").(string)
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Cloning from UUID: %s", tUUID)
	vm, err := virtualmachine.FromUUID(c, tUUID)
	if err != nil {
		return spec, nil, fmt.Errorf("cannot locate virtual machine or template with UUID %q: %s", tUUID, err)
	}
	vprops, err := virtualmachine.Properties(vm)
	if err != nil {
		return spec, nil, fmt.Errorf("error fetching virtual machine or template properties: %s", err)
	}
	// If we are creating a linked clone, grab the current snapshot of the
	// source, and populate the appropriate field. This should have already been
	// validated, but just in case, validate it again here.
	if d.Get("clone.0.linked_clone").(bool) {
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Clone type is a linked clone")
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Fetching snapshot for VM/template UUID %s", tUUID)
		if err := validateCloneSnapshots(vprops); err != nil {
			return spec, nil, err
		}
		spec.Snapshot = vprops.Snapshot.CurrentSnapshot
		spec.Location.DiskMoveType = string(types.VirtualMachineRelocateDiskMoveOptionsCreateNewChildDiskBacking)
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Snapshot for clone: %s", vprops.Snapshot.CurrentSnapshot.Value)
	}

	// Set the target host system and resource pool.
	poolID := d.Get("resource_pool_id").(string)
	pool, err := resourcepool.FromID(c, poolID)
	if err != nil {
		return spec, nil, fmt.Errorf("could not find resource pool ID %q: %s", poolID, err)
	}
	var hs *object.HostSystem
	if v, ok := d.GetOk("host_system_id"); ok {
		hsID := v.(string)
		var err error
		if hs, err = hostsystem.FromID(c, hsID); err != nil {
			return spec, nil, fmt.Errorf("error locating host system at ID %q: %s", hsID, err)
		}
	}
	// Validate that the host is part of the resource pool before proceeding
	if err := resourcepool.ValidateHost(c, pool, hs); err != nil {
		return spec, nil, err
	}
	poolRef := pool.Reference()
	spec.Location.Pool = &poolRef
	if hs != nil {
		hsRef := hs.Reference()
		spec.Location.Host = &hsRef
	}

	// Grab the relocate spec for the disks.
	l := object.VirtualDeviceList(vprops.Config.Hardware.Device)
	relocators, err := virtualdevice.DiskCloneRelocateOperation(d, c, l)
	if err != nil {
		return spec, nil, err
	}
	spec.Location.Disk = relocators
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Clone spec prep complete")
	return spec, vm, nil
}
func ExpandVirtualMachineCloneSpec(d *schema.ResourceData, c *govmomi.Client) (types.VirtualMachineCloneSpec, *object.VirtualMachine, error) {
	var spec types.VirtualMachineCloneSpec
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Preparing clone spec for VM")

	
	
	if dsID, ok := d.GetOk("datastore_id"); ok {
		ds, err := datastore.FromID(c, dsID.(string))
		if err != nil {
			return spec, nil, fmt.Errorf("error locating datastore for VM: %s", err)
		}
		spec.Location.Datastore = types.NewReference(ds.Reference())
	}

	tUUID := d.Get("clone.0.template_uuid").(string)
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Cloning from UUID: %s", tUUID)
	vm, err := virtualmachine.FromUUID(c, tUUID)
	if err != nil {
		return spec, nil, fmt.Errorf("cannot locate virtual machine or template with UUID %q: %s", tUUID, err)
	}
	vprops, err := virtualmachine.Properties(vm)
	if err != nil {
		return spec, nil, fmt.Errorf("error fetching virtual machine or template properties: %s", err)
	}
	
	
	
	if d.Get("clone.0.linked_clone").(bool) {
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Clone type is a linked clone")
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Fetching snapshot for VM/template UUID %s", tUUID)
		if err := validateCloneSnapshots(vprops); err != nil {
			return spec, nil, err
		}
		spec.Snapshot = vprops.Snapshot.CurrentSnapshot
		spec.Location.DiskMoveType = string(types.VirtualMachineRelocateDiskMoveOptionsCreateNewChildDiskBacking)
		log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Snapshot for clone: %s", vprops.Snapshot.CurrentSnapshot.Value)
	}

	
	poolID := d.Get("resource_pool_id").(string)
	pool, err := resourcepool.FromID(c, poolID)
	if err != nil {
		return spec, nil, fmt.Errorf("could not find resource pool ID %q: %s", poolID, err)
	}
	var hs *object.HostSystem
	if v, ok := d.GetOk("host_system_id"); ok {
		hsID := v.(string)
		var err error
		if hs, err = hostsystem.FromID(c, hsID); err != nil {
			return spec, nil, fmt.Errorf("error locating host system at ID %q: %s", hsID, err)
		}
	}
	
	if err := resourcepool.ValidateHost(c, pool, hs); err != nil {
		return spec, nil, err
	}
	poolRef := pool.Reference()
	spec.Location.Pool = &poolRef
	if hs != nil {
		hsRef := hs.Reference()
		spec.Location.Host = &hsRef
	}

	
	l := object.VirtualDeviceList(vprops.Config.Hardware.Device)
	relocators, err := virtualdevice.DiskCloneRelocateOperation(d, c, l)
	if err != nil {
		return spec, nil, err
	}
	spec.Location.Disk = relocators
	log.Printf("[DEBUG] ExpandVirtualMachineCloneSpec: Clone spec prep complete")
	return spec, vm, nil
}
func ExpandVirtualMachineCloneSpec ( d * schema . ResourceData , c * govmomi . Client ) ( types . VirtualMachineCloneSpec , * object . VirtualMachine , error ) { var spec types . VirtualMachineCloneSpec log . Printf ( " " ) // Populate the datastore only if we have a datastore ID. The ID may not be // specified in the event a datastore cluster is specified instead. if dsID , ok := d . GetOk ( " " ) ; ok { ds , err := datastore . FromID ( c , dsID . ( string ) ) if err != nil { return spec , nil , fmt . Errorf ( " " , err ) } spec . Location . Datastore = types . NewReference ( ds . Reference ( ) ) } tUUID := d . Get ( " " ) . ( string ) log . Printf ( " " , tUUID ) vm , err := virtualmachine . FromUUID ( c , tUUID ) if err != nil { return spec , nil , fmt . Errorf ( " " , tUUID , err ) } vprops , err := virtualmachine . Properties ( vm ) if err != nil { return spec , nil , fmt . Errorf ( " " , err ) } // If we are creating a linked clone, grab the current snapshot of the // source, and populate the appropriate field. This should have already been // validated, but just in case, validate it again here. if d . Get ( " " ) . ( bool ) { log . Printf ( " " ) log . Printf ( " " , tUUID ) if err := validateCloneSnapshots ( vprops ) ; err != nil { return spec , nil , err } spec . Snapshot = vprops . Snapshot . CurrentSnapshot spec . Location . DiskMoveType = string ( types . VirtualMachineRelocateDiskMoveOptionsCreateNewChildDiskBacking ) log . Printf ( " " , vprops . Snapshot . CurrentSnapshot . Value ) } // Set the target host system and resource pool. poolID := d . Get ( " " ) . ( string ) pool , err := resourcepool . FromID ( c , poolID ) if err != nil { return spec , nil , fmt . Errorf ( " " , poolID , err ) } var hs * object . HostSystem if v , ok := d . GetOk ( " " ) ; ok { hsID := v . ( string ) var err error if hs , err = hostsystem . FromID ( c , hsID ) ; err != nil { return spec , nil , fmt . Errorf ( " " , hsID , err ) } } // Validate that the host is part of the resource pool before proceeding if err := resourcepool . ValidateHost ( c , pool , hs ) ; err != nil { return spec , nil , err } poolRef := pool . Reference ( ) spec . Location . Pool = & poolRef if hs != nil { hsRef := hs . Reference ( ) spec . Location . Host = & hsRef } // Grab the relocate spec for the disks. l := object . VirtualDeviceList ( vprops . Config . Hardware . Device ) relocators , err := virtualdevice . DiskCloneRelocateOperation ( d , c , l ) if err != nil { return spec , nil , err } spec . Location . Disk = relocators log . Printf ( " " ) return spec , vm , nil }
// ExpandVirtualMachineCloneSpec creates a clone spec for an existing virtual machine.
//
// The clone spec built by this function for the clone contains the target
// datastore, the source snapshot in the event of linked clones, and a relocate
// spec that contains the new locations and configuration details of the new
// virtual disks.
ExpandVirtualMachineCloneSpec creates a clone spec for an existing virtual machine . The clone spec built by this function for the clone contains the target datastore the source snapshot in the event of linked clones and a relocate spec that contains the new locations and configuration details of the new virtual disks .