func createHardDisk(client *govmomi.Client, size int, diskPath string, diskType string, adapterType string, dc string) error {
	var vDiskType string
	switch diskType {
	case "thin":
		vDiskType = "thin"
	case "eagerZeroedThick":
		vDiskType = "eagerZeroedThick"
	case "lazy":
		vDiskType = "preallocated"
	}

	virtualDiskManager := object.NewVirtualDiskManager(client.Client)
	spec := &types.FileBackedVirtualDiskSpec{
		VirtualDiskSpec: types.VirtualDiskSpec{
			AdapterType: adapterType,
			DiskType:    vDiskType,
		},
		CapacityKb: int64(1024 * 1024 * size),
	}
	datacenter, err := getDatacenter(client, dc)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Disk spec: %v", spec)

	task, err := virtualDiskManager.CreateVirtualDisk(context.TODO(), diskPath, datacenter, spec)
	if err != nil {
		return err
	}

	_, err = task.WaitForResult(context.TODO(), nil)
	if err != nil {
		log.Printf("[INFO] Failed to create disk:  %v", err)
		return err
	}
	log.Printf("[INFO] Created disk.")

	return nil
}

func createHardDisk ( client * govmomi . Client , size int , diskPath string , diskType string , adapterType string , dc string ) error { var vDiskType string switch diskType { case " " : vDiskType = " " case " " : vDiskType = " " case " " : vDiskType = " " } virtualDiskManager := object . NewVirtualDiskManager ( client . Client ) spec := & types . FileBackedVirtualDiskSpec { VirtualDiskSpec : types . VirtualDiskSpec { AdapterType : adapterType , DiskType : vDiskType , } , CapacityKb : int64 ( 1024 * 1024 * size ) , } datacenter , err := getDatacenter ( client , dc ) if err != nil { return err } log . Printf ( " " , spec ) task , err := virtualDiskManager . CreateVirtualDisk ( context . TODO ( ) , diskPath , datacenter , spec ) if err != nil { return err } _ , err = task . WaitForResult ( context . TODO ( ) , nil ) if err != nil { log . Printf ( " " , err ) return err } log . Printf ( " " ) return nil }

// createHardDisk creates a new Hard Disk.

createHardDisk creates a new Hard Disk .


func searchForDirectory(client *govmomi.Client, datacenter string, datastore string, directoryPath string) error {
	log.Printf("[DEBUG] Searching for Directory")
	finder := find.NewFinder(client.Client, true)

	dc, err := getDatacenter(client, datacenter)
	if err != nil {
		return fmt.Errorf("Error finding Datacenter: %s: %s", datacenter, err)
	}
	finder = finder.SetDatacenter(dc)

	ds, err := finder.Datastore(context.TODO(), datastore)
	if err != nil {
		return fmt.Errorf("Error finding Datastore: %s: %s", datastore, err)
	}

	ctx := context.TODO()
	b, err := ds.Browser(ctx)
	if err != nil {
		return err
	}

	spec := types.HostDatastoreBrowserSearchSpec{
		Query: []types.BaseFileQuery{&types.FolderFileQuery{}},
		Details: &types.FileQueryFlags{
			FileSize:     true,
			FileType:     true,
			Modification: true,
			FileOwner:    types.NewBool(true),
		},
		MatchPattern: []string{path.Base(directoryPath)},
	}

	dsPath := ds.Path(path.Dir(directoryPath))
	task, err := b.SearchDatastore(context.TODO(), dsPath, &spec)

	if err != nil {
		log.Printf("[DEBUG] searchForDirectory - could not search datastore for: %v", directoryPath)
		return err
	}

	info, err := task.WaitForResult(context.TODO(), nil)
	if err != nil {
		if info == nil || info.Error != nil {
			_, ok := info.Error.Fault.(*types.FileNotFound)
			if ok {
				log.Printf("[DEBUG] searchForDirectory - could not find: %v", directoryPath)
				return nil
			}
		}

		log.Printf("[DEBUG] searchForDirectory - could not search datastore for: %v", directoryPath)
		return err
	}

	res := info.Result.(types.HostDatastoreBrowserSearchResults)
	log.Printf("[DEBUG] num results: %d", len(res.File))
	if len(res.File) == 0 {
		log.Printf("[DEBUG] searchForDirectory - could not find: %v", directoryPath)
		return nil
	}

	if len(res.File) != 1 {
		return errors.New("Datastore search did not return exactly one result")
	}

	fileInfo := res.File[0]
	log.Printf("[DEBUG] searchForDirectory - fileinfo: %#v", fileInfo)

	return nil
}

func searchForDirectory ( client * govmomi . Client , datacenter string , datastore string , directoryPath string ) error { log . Printf ( " " ) finder := find . NewFinder ( client . Client , true ) dc , err := getDatacenter ( client , datacenter ) if err != nil { return fmt . Errorf ( " " , datacenter , err ) } finder = finder . SetDatacenter ( dc ) ds , err := finder . Datastore ( context . TODO ( ) , datastore ) if err != nil { return fmt . Errorf ( " " , datastore , err ) } ctx := context . TODO ( ) b , err := ds . Browser ( ctx ) if err != nil { return err } spec := types . HostDatastoreBrowserSearchSpec { Query : [ ] types . BaseFileQuery { & types . FolderFileQuery { } } , Details : & types . FileQueryFlags { FileSize : true , FileType : true , Modification : true , FileOwner : types . NewBool ( true ) , } , MatchPattern : [ ] string { path . Base ( directoryPath ) } , } dsPath := ds . Path ( path . Dir ( directoryPath ) ) task , err := b . SearchDatastore ( context . TODO ( ) , dsPath , & spec ) if err != nil { log . Printf ( " " , directoryPath ) return err } info , err := task . WaitForResult ( context . TODO ( ) , nil ) if err != nil { if info == nil || info . Error != nil { _ , ok := info . Error . Fault . ( * types . FileNotFound ) if ok { log . Printf ( " " , directoryPath ) return nil } } log . Printf ( " " , directoryPath ) return err } res := info . Result . ( types . HostDatastoreBrowserSearchResults ) log . Printf ( " " , len ( res . File ) ) if len ( res . File ) == 0 { log . Printf ( " " , directoryPath ) return nil } if len ( res . File ) != 1 { return errors . New ( " " ) } fileInfo := res . File [ 0 ] log . Printf ( " " , fileInfo ) return nil }

// Searches for the presence of a directory path.

Searches for the presence of a directory path .


func (p *nasDatastoreMountProcessor) processMountOperations() (*object.Datastore, error) {
	hosts := p.diffNewOld()
	if len(hosts) < 1 {
		// Nothing to do
		return p.ds, nil
	}
	// Validate we are vCenter if we are working with multiple hosts
	if len(hosts) > 1 {
		if err := viapi.ValidateVirtualCenter(p.client); err != nil {
			return p.ds, fmt.Errorf("cannot mount on multiple hosts: %s", err)
		}
	}
	for _, hsID := range hosts {
		dss, err := hostDatastoreSystemFromHostSystemID(p.client, hsID)
		if err != nil {
			return p.ds, fmt.Errorf("host %q: %s", hostsystem.NameOrID(p.client, hsID), err)
		}
		ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
		defer cancel()
		ds, err := dss.CreateNasDatastore(ctx, *p.volSpec)
		if err != nil {
			return p.ds, fmt.Errorf("host %q: %s", hostsystem.NameOrID(p.client, hsID), err)
		}
		if err := p.validateDatastore(ds); err != nil {
			return p.ds, fmt.Errorf("datastore validation error on host %q: %s", hostsystem.NameOrID(p.client, hsID), err)
		}
	}
	return p.ds, nil
}

// processMountOperations processes all pending mount operations by diffing old
// and new and adding any hosts that were not found in old. The datastore is
// returned, along with any error.

processMountOperations processes all pending mount operations by diffing old and new and adding any hosts that were not found in old . The datastore is returned along with any error .


func (p *nasDatastoreMountProcessor) processUnmountOperations() error {
	hosts := p.diffOldNew()
	if len(hosts) < 1 || p.ds == nil {
		// Nothing to do
		return nil
	}
	for _, hsID := range hosts {
		dss, err := hostDatastoreSystemFromHostSystemID(p.client, hsID)
		if err != nil {
			return fmt.Errorf("host %q: %s", hostsystem.NameOrID(p.client, hsID), err)
		}
		if err := removeDatastore(dss, p.ds); err != nil {
			return fmt.Errorf("host %q: %s", hostsystem.NameOrID(p.client, hsID), err)
		}
	}
	return nil
}

func
(
p
*
nasDatastoreMountProcessor
)
processUnmountOperations
(
)
error
{
hosts
:=
p
.
diffOldNew
(
)
if
len
(
hosts
)
<
1
||
p
.
ds
==
{
// Nothing to do
return
}
for
_
,
hsID
:=
range
hosts
{
dss
,
err
:=
hostDatastoreSystemFromHostSystemID
(
p
.
client
,
hsID
)
if
err
!=
{
return
fmt
.
Errorf
(
"
"
,
hostsystem
.
NameOrID
(
p
.
client
,
hsID
)
,
err
)
}
if
err
:=
removeDatastore
(
dss
,
p
.
ds
)
;
err
!=
{
return
fmt
.
Errorf
(
"
"
,
hostsystem
.
NameOrID
(
p
.
client
,
hsID
)
,
err
)
}
}
return
}

// processUnmountOperations processes all pending unmount operations by diffing old
// and new and removing any hosts that were not found in new. This operation
// only proceeds if the datastore field in the processor is populated.

processUnmountOperations processes all pending unmount operations by diffing old and new and removing any hosts that were not found in new . This operation only proceeds if the datastore field in the processor is populated .


func isEligibleTagEndpoint(client *govmomi.Client) bool {
	if err := viapi.ValidateVirtualCenter(client); err != nil {
		return false
	}
	clientVer := viapi.ParseVersionFromClient(client)
	if !clientVer.ProductEqual(tagsMinVersion) || clientVer.Older(tagsMinVersion) {
		return false
	}
	return true
}

func isEligibleTagEndpoint ( client * govmomi . Client ) bool { if err := viapi . ValidateVirtualCenter ( client ) ; err != nil { return false } clientVer := viapi . ParseVersionFromClient ( client ) if ! clientVer . ProductEqual ( tagsMinVersion ) || clientVer . Older ( tagsMinVersion ) { return false } return true }

// isEligibleTagEndpoint is a meta-validation that is used on login to see if
// the connected endpoint supports the CIS REST API, which we use for tags.

isEligibleTagEndpoint is a meta - validation that is used on login to see if the connected endpoint supports the CIS REST API which we use for tags .


func tagCategoryByName(client *tags.RestClient, name string) (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
	defer cancel()
	cats, err := client.GetCategoriesByName(ctx, name)
	if err != nil {
		return "", fmt.Errorf("could not get category for name %q: %s", name, err)
	}

	if len(cats) < 1 {
		return "", fmt.Errorf("category name %q not found", name)
	}
	if len(cats) > 1 {
		// Although GetCategoriesByName does not seem to think that tag categories
		// are unique, empirical observation via the console and API show that they
		// are. If for some reason the returned results includes more than one ID,
		// we give an error, indicating that this is a bug and the user should
		// submit an issue.
		return "", fmt.Errorf(vSphereTagCategorySearchErrMultiple, name)
	}

	return cats[0].ID, nil
}

// tagCategoryByName locates a tag category by name. It's used by the
// vsphere_tag_category data source, and the resource importer.

tagCategoryByName locates a tag category by name . It s used by the vsphere_tag_category data source and the resource importer .


func tagByName(client *tags.RestClient, name, categoryID string) (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
	defer cancel()
	tags, err := client.GetTagByNameForCategory(ctx, name, categoryID)
	if err != nil {
		return "", fmt.Errorf("could not get tag for name %q: %s", name, err)
	}

	if len(tags) < 1 {
		return "", fmt.Errorf("tag name %q not found in category ID %q", name, categoryID)
	}
	if len(tags) > 1 {
		// This situation is very similar to the one in tagCategoryByName. The API
		// docs even say that tags need to be unique in categories, yet
		// GetTagByNameForCategory still returns multiple results.
		return "", fmt.Errorf(vSphereTagSearchErrMultiple, name)
	}

	return tags[0].ID, nil
}

// tagByName locates a tag by it supplied name and category ID. Use
// tagCategoryByName to get the tag category ID if require the category ID as
// well.

tagByName locates a tag by it supplied name and category ID . Use tagCategoryByName to get the tag category ID if require the category ID as well .


func tagsSchema() *schema.Schema {
	return &schema.Schema{
		Type:        schema.TypeSet,
		Description: "A list of tag IDs to apply to this object.",
		Optional:    true,
		Elem:        &schema.Schema{Type: schema.TypeString},
	}
}

func tagsSchema ( ) * schema . Schema { return & schema . Schema { Type : schema . TypeSet , Description : " " , Optional : true , Elem : & schema . Schema { Type : schema . TypeString } , } }

// tagsSchema returns the schema for the tags configuration attribute for each
// resource that needs it.
//
// The key is usually "tags" and should be a list of tag IDs to associate with
// this resource.

tagsSchema returns the schema for the tags configuration attribute for each resource that needs it . The key is usually tags and should be a list of tag IDs to associate with this resource .


func tagTypeForObject(obj object.Reference) (string, error) {
	switch obj.(type) {
	case *object.VirtualMachine:
		return vSphereTagTypeVirtualMachine, nil
	case *object.Datastore:
		return vSphereTagTypeDatastore, nil
	case *object.Network:
		return vSphereTagTypeNetwork, nil
	case *object.Folder:
		return vSphereTagTypeFolder, nil
	case *object.VmwareDistributedVirtualSwitch:
		return vSphereTagTypeVmwareDistributedVirtualSwitch, nil
	case *object.DistributedVirtualSwitch:
		return vSphereTagTypeDistributedVirtualSwitch, nil
	case *object.DistributedVirtualPortgroup:
		return vSphereTagTypeDistributedVirtualPortgroup, nil
	case *object.Datacenter:
		return vSphereTagTypeDatacenter, nil
	case *object.ClusterComputeResource:
		return vSphereTagTypeClusterComputeResource, nil
	case *object.HostSystem:
		return vSphereTagTypeHostSystem, nil
	case *object.StoragePod:
		return vSphereTagTypeStoragePod, nil
	case *object.ResourcePool:
		return vSphereTagTypeResourcePool, nil
	case *object.VirtualApp:
		return vSphereTagTypeVirtualApp, nil
	}
	return "", fmt.Errorf("unsupported type for tagging: %T", obj)
}

// tagTypeForObject takes an object.Reference and returns the tag type based on
// its underlying type. If it's not in this list, we don't support it for
// tagging and we return an error.

tagTypeForObject takes an object . Reference and returns the tag type based on its underlying type . If it s not in this list we don t support it for tagging and we return an error .


func readTagsForResource(client *tags.RestClient, obj object.Reference, d *schema.ResourceData) error {
	log.Printf("[DEBUG] Reading tags for object %q", obj.Reference().Value)
	objID := obj.Reference().Value
	objType, err := tagTypeForObject(obj)
	if err != nil {
		return err
	}
	ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
	defer cancel()
	ids, err := client.ListAttachedTags(ctx, objID, objType)
	log.Printf("[DEBUG] Tags for object %q: %s", objID, strings.Join(ids, ","))
	if err != nil {
		return err
	}
	if err := d.Set(vSphereTagAttributeKey, ids); err != nil {
		return fmt.Errorf("error saving tag IDs to resource data: %s", err)
	}
	return nil
}

func readTagsForResource ( client * tags . RestClient , obj object . Reference , d * schema . ResourceData ) error { log . Printf ( " " , obj . Reference ( ) . Value ) objID := obj . Reference ( ) . Value objType , err := tagTypeForObject ( obj ) if err != nil { return err } ctx , cancel := context . WithTimeout ( context . Background ( ) , defaultAPITimeout ) defer cancel ( ) ids , err := client . ListAttachedTags ( ctx , objID , objType ) log . Printf ( " " , objID , strings . Join ( ids , " " ) ) if err != nil { return err } if err := d . Set ( vSphereTagAttributeKey , ids ) ; err != nil { return fmt . Errorf ( " " , err ) } return nil }

// readTagsForResource reads the tags for a given reference and saves the list
// in the supplied ResourceData. It returns an error if there was an issue
// reading the tags.

readTagsForResource reads the tags for a given reference and saves the list in the supplied ResourceData . It returns an error if there was an issue reading the tags .


func (p *tagDiffProcessor) diff(a, b []string) []string {
	var found bool
	c := make([]string, 0)
	for _, v1 := range a {
		for _, v2 := range b {
			if v1 == v2 {
				found = true
			}
		}
		if !found {
			c = append(c, v1)
		}
		found = false
	}
	return c
}

func ( p * tagDiffProcessor ) diff ( a , b [ ] string ) [ ] string { var found bool c := make ( [ ] string , 0 ) for _ , v1 := range a { for _ , v2 := range b { if v1 == v2 { found = true } } if ! found { c = append ( c , v1 ) } found = false } return c }

// diff is what diffOldNew and diffNewOld hand off to.

diff is what diffOldNew and diffNewOld hand off to .


func (p *tagDiffProcessor) processAttachOperations() error {
	tagIDs := p.diffNewOld()
	if len(tagIDs) < 1 {
		// Nothing to do
		return nil
	}
	for _, tagID := range tagIDs {
		objID := p.subject.Reference().Value
		objType, err := tagTypeForObject(p.subject)
		if err != nil {
			return err
		}
		ctx, cancel := context.WithTimeout(context.Background(), defaultAPITimeout)
		defer cancel()
		log.Printf("[DEBUG] Attaching tag %q for object %q", tagID, objID)
		if err := p.client.AttachTagToObject(ctx, tagID, objID, objType); err != nil {
			return err
		}
	}
	return nil
}

func
(
p
*
tagDiffProcessor
)
processAttachOperations
(
)
error
{
tagIDs
:=
p
.
diffNewOld
(
)
if
len
(
tagIDs
)
<
1
{
// Nothing to do
return
}
for
_
,
tagID
:=
range
tagIDs
{
objID
:=
p
.
subject
.
Reference
(
)
.
Value
objType
,
err
:=
tagTypeForObject
(
p
.
subject
)
if
err
!=
{
return
err
}
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(
)
,
defaultAPITimeout
)
defer
cancel
(
)
log
.
Printf
(
"
"
,
tagID
,
objID
)
if
err
:=
p
.
client
.
AttachTagToObject
(
ctx
,
tagID
,
objID
,
objType
)
;
err
!=
{
return
err
}
}
return
}

// processAttachOperations processes all pending attach operations by diffing old
// and new and adding any IDs that were not found in old.

processAttachOperations processes all pending attach operations by diffing old and new and adding any IDs that were not found in old .


func tagsClientIfDefined(d *schema.ResourceData, meta interface{}) (*tags.RestClient, error) {
	old, new := d.GetChange(vSphereTagAttributeKey)
	if len(old.(*schema.Set).List()) > 0 || len(new.(*schema.Set).List()) > 0 {
		log.Printf("[DEBUG] tagsClientIfDefined: Loading tagging client")
		client, err := meta.(*VSphereClient).TagsClient()
		if err != nil {
			return nil, err
		}
		return client, nil
	}
	log.Printf("[DEBUG] tagsClientIfDefined: No tags configured, skipping loading of tagging client")
	return nil, nil
}

func tagsClientIfDefined ( d * schema . ResourceData , meta interface { } ) ( * tags . RestClient , error ) { old , new := d . GetChange ( vSphereTagAttributeKey ) if len ( old . ( * schema . Set ) . List ( ) ) > 0 || len ( new . ( * schema . Set ) . List ( ) ) > 0 { log . Printf ( " " ) client , err := meta . ( * VSphereClient ) . TagsClient ( ) if err != nil { return nil , err } return client , nil } log . Printf ( " " ) return nil , nil }

// tagsClientIfDefined goes through the client validation process and returns
// the tags client only if there are tags defined in the supplied ResourceData.
//
// This should be used to fetch the tagging REST client on resources that
// support tags, usually closer to the beginning of a CRUD function to check to
// make sure it's worth proceeding with most of the operation. The returned
// client should be checked for nil before passing it to processTagDiff.

tagsClientIfDefined goes through the client validation process and returns the tags client only if there are tags defined in the supplied ResourceData . This should be used to fetch the tagging REST client on resources that support tags usually closer to the beginning of a CRUD function to check to make sure it s worth proceeding with most of the operation . The returned client should be checked for nil before passing it to processTagDiff .


func processTagDiff(client *tags.RestClient, d *schema.ResourceData, obj object.Reference) error {
	log.Printf("[DEBUG] Processing tags for object %q", obj.Reference().Value)
	old, new := d.GetChange(vSphereTagAttributeKey)
	tdp := &tagDiffProcessor{
		client:    client,
		subject:   obj,
		oldTagIDs: structure.SliceInterfacesToStrings(old.(*schema.Set).List()),
		newTagIDs: structure.SliceInterfacesToStrings(new.(*schema.Set).List()),
	}
	if err := tdp.processDetachOperations(); err != nil {
		return fmt.Errorf("error detaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	if err := tdp.processAttachOperations(); err != nil {
		return fmt.Errorf("error attaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	return nil
}

func processTagDiff ( client * tags . RestClient , d * schema . ResourceData , obj object . Reference ) error { log . Printf ( " " , obj . Reference ( ) . Value ) old , new := d . GetChange ( vSphereTagAttributeKey ) tdp := & tagDiffProcessor { client : client , subject : obj , oldTagIDs : structure . SliceInterfacesToStrings ( old . ( * schema . Set ) . List ( ) ) , newTagIDs : structure . SliceInterfacesToStrings ( new . ( * schema . Set ) . List ( ) ) , } if err := tdp . processDetachOperations ( ) ; err != nil { return fmt . Errorf ( " " , obj . Reference ( ) . Value , err ) } if err := tdp . processAttachOperations ( ) ; err != nil { return fmt . Errorf ( " " , obj . Reference ( ) . Value , err ) } return nil }

// processTagDiff wraps the whole tag diffing operation into a nice clean
// function that resources can use.

processTagDiff wraps the whole tag diffing operation into a nice clean function that resources can use .


func expandDVSContactInfo(d *schema.ResourceData) *types.DVSContactInfo {
	obj := &types.DVSContactInfo{
		Name:    d.Get("contact_name").(string),
		Contact: d.Get("contact_detail").(string),
	}
	return obj
}

func expandDVSContactInfo ( d * schema . ResourceData ) * types . DVSContactInfo { obj := & types . DVSContactInfo { Name : d . Get ( " " ) . ( string ) , Contact : d . Get ( " " ) . ( string ) , } return obj }

// expandDVSContactInfo reads certain ResourceData keys and
// returns a DVSContactInfo.

expandDVSContactInfo reads certain ResourceData keys and returns a DVSContactInfo .


func flattenDVSContactInfo(d *schema.ResourceData, obj types.DVSContactInfo) error {
	d.Set("contact_name", obj.Name)
	d.Set("conatct_detail", obj.Contact)
	return nil
}

func flattenDVSContactInfo ( d * schema . ResourceData , obj types . DVSContactInfo ) error { d . Set ( " " , obj . Name ) d . Set ( " " , obj . Contact ) return nil }

// flattenDVSContactInfo reads various fields from a
// DVSContactInfo into the passed in ResourceData.

flattenDVSContactInfo reads various fields from a DVSContactInfo into the passed in ResourceData .


func expandDistributedVirtualSwitchHostMemberConfigSpec(d map[string]interface{}) types.DistributedVirtualSwitchHostMemberConfigSpec {
	hostRef := &types.ManagedObjectReference{
		Type:  "HostSystem",
		Value: d["host_system_id"].(string),
	}

	var pnSpecs []types.DistributedVirtualSwitchHostMemberPnicSpec
	nics := structure.SliceInterfacesToStrings(d["devices"].([]interface{}))
	for _, nic := range nics {
		pnSpec := types.DistributedVirtualSwitchHostMemberPnicSpec{
			PnicDevice: nic,
		}
		pnSpecs = append(pnSpecs, pnSpec)
	}
	backing := types.DistributedVirtualSwitchHostMemberPnicBacking{
		PnicSpec: pnSpecs,
	}

	obj := types.DistributedVirtualSwitchHostMemberConfigSpec{
		Host:    *hostRef,
		Backing: &backing,
	}
	return obj
}

// expandDistributedVirtualSwitchHostMemberConfigSpec reads certain keys from a
// Set object map and returns a DistributedVirtualSwitchHostMemberConfigSpec.


func flattenDistributedVirtualSwitchHostMember(obj types.DistributedVirtualSwitchHostMember) map[string]interface{} {
	d := make(map[string]interface{})
	d["host_system_id"] = obj.Config.Host.Value

	var devices []string
	backing := obj.Config.Backing.(*types.DistributedVirtualSwitchHostMemberPnicBacking)
	for _, spec := range backing.PnicSpec {
		devices = append(devices, spec.PnicDevice)
	}

	d["devices"] = devices

	return d
}

// flattenDistributedVirtualSwitchHostMemberConfigSpec reads various fields
// from a DistributedVirtualSwitchHostMemberConfigSpec and returns a Set object
// map.
//
// This is the flatten counterpart to
// expandDistributedVirtualSwitchHostMemberConfigSpec.


func expandSliceOfDistributedVirtualSwitchHostMemberConfigSpec(d *schema.ResourceData) []types.DistributedVirtualSwitchHostMemberConfigSpec {
	var specs []types.DistributedVirtualSwitchHostMemberConfigSpec
	o, n := d.GetChange("host")
	os := o.(*schema.Set)
	ns := n.(*schema.Set)

	// Make an intersection set. These hosts have not changed so we don't bother
	// with them.
	is := os.Intersection(ns)
	os = os.Difference(is)
	ns = ns.Difference(is)

	// Our old and new sets now have an accurate description of hosts that may
	// have been added, removed, or changed. Add removed and modified hosts
	// first.
	for _, oe := range os.List() {
		om := oe.(map[string]interface{})
		var found bool
		for _, ne := range ns.List() {
			nm := ne.(map[string]interface{})
			if nm["host_system_id"] == om["host_system_id"] {
				found = true
			}
		}
		if !found {
			spec := expandDistributedVirtualSwitchHostMemberConfigSpec(om)
			spec.Operation = string(types.ConfigSpecOperationRemove)
			specs = append(specs, spec)
		}
	}

	// Process new hosts now. These are ones that are only present in the new
	// set.
	for _, ne := range ns.List() {
		nm := ne.(map[string]interface{})
		var found bool
		for _, oe := range os.List() {
			om := oe.(map[string]interface{})
			if om["host_system_id"] == nm["host_system_id"] {
				found = true
			}
		}
		spec := expandDistributedVirtualSwitchHostMemberConfigSpec(nm)
		if !found {
			spec.Operation = string(types.ConfigSpecOperationAdd)
		} else {
			spec.Operation = string(types.ConfigSpecOperationEdit)
		}
		specs = append(specs, spec)
	}

	// Done!
	return specs
}

// expandSliceOfDistributedVirtualSwitchHostMemberConfigSpec expands all host
// entires for a VMware DVS, detecting if a host spec needs to be added,
// removed, or updated as well. The whole slice is returned.


func flattenSliceOfDistributedVirtualSwitchHostMember(d *schema.ResourceData, members []types.DistributedVirtualSwitchHostMember) error {
	var hosts []map[string]interface{}
	for _, m := range members {
		hosts = append(hosts, flattenDistributedVirtualSwitchHostMember(m))
	}
	if err := d.Set("host", hosts); err != nil {
		return err
	}
	return nil
}

// flattenSliceOfDistributedVirtualSwitchHostMember creates a set of all host
// entries for a supplied slice of DistributedVirtualSwitchHostMember.
//
// This is the flatten counterpart to
// expandSliceOfDistributedVirtualSwitchHostMemberConfigSpec.


func expandVMwareIpfixConfig(d *schema.ResourceData) *types.VMwareIpfixConfig {
	obj := &types.VMwareIpfixConfig{
		ActiveFlowTimeout:   int32(d.Get("netflow_active_flow_timeout").(int)),
		CollectorIpAddress:  d.Get("netflow_collector_ip_address").(string),
		CollectorPort:       int32(d.Get("netflow_collector_port").(int)),
		IdleFlowTimeout:     int32(d.Get("netflow_idle_flow_timeout").(int)),
		InternalFlowsOnly:   d.Get("netflow_internal_flows_only").(bool),
		ObservationDomainId: int64(d.Get("netflow_observation_domain_id").(int)),
		SamplingRate:        int32(d.Get("netflow_sampling_rate").(int)),
	}
	return obj
}

func expandVMwareIpfixConfig ( d * schema . ResourceData ) * types . VMwareIpfixConfig { obj := & types . VMwareIpfixConfig { ActiveFlowTimeout : int32 ( d . Get ( " " ) . ( int ) ) , CollectorIpAddress : d . Get ( " " ) . ( string ) , CollectorPort : int32 ( d . Get ( " " ) . ( int ) ) , IdleFlowTimeout : int32 ( d . Get ( " " ) . ( int ) ) , InternalFlowsOnly : d . Get ( " " ) . ( bool ) , ObservationDomainId : int64 ( d . Get ( " " ) . ( int ) ) , SamplingRate : int32 ( d . Get ( " " ) . ( int ) ) , } return obj }

// expandVMwareIpfixConfig reads certain ResourceData keys and
// returns a VMwareIpfixConfig.

expandVMwareIpfixConfig reads certain ResourceData keys and returns a VMwareIpfixConfig .


func flattenVMwareIpfixConfig(d *schema.ResourceData, obj *types.VMwareIpfixConfig) error {
	d.Set("netflow_active_flow_timeout", obj.ActiveFlowTimeout)
	d.Set("netflow_collector_ip_address", obj.CollectorIpAddress)
	d.Set("netflow_collector_port", obj.CollectorPort)
	d.Set("netflow_idle_flow_timeout", obj.IdleFlowTimeout)
	d.Set("netflow_internal_flows_only", obj.InternalFlowsOnly)
	d.Set("netflow_observation_domain_id", obj.ObservationDomainId)
	d.Set("netflow_sampling_rate", obj.SamplingRate)
	return nil
}

func flattenVMwareIpfixConfig ( d * schema . ResourceData , obj * types . VMwareIpfixConfig ) error { d . Set ( " " , obj . ActiveFlowTimeout ) d . Set ( " " , obj . CollectorIpAddress ) d . Set ( " " , obj . CollectorPort ) d . Set ( " " , obj . IdleFlowTimeout ) d . Set ( " " , obj . InternalFlowsOnly ) d . Set ( " " , obj . ObservationDomainId ) d . Set ( " " , obj . SamplingRate ) return nil }

// flattenVMwareIpfixConfig reads various fields from a
// VMwareIpfixConfig into the passed in ResourceData.

flattenVMwareIpfixConfig reads various fields from a VMwareIpfixConfig into the passed in ResourceData .


func flattenDvsHostInfrastructureTrafficResource(d *schema.ResourceData, obj types.DvsHostInfrastructureTrafficResource, key string) error {
	shareLevelKey := fmt.Sprintf("%s_share_level", strings.ToLower(key))
	shareCountKey := fmt.Sprintf("%s_share_count", strings.ToLower(key))
	maxMbitKey := fmt.Sprintf("%s_maximum_mbit", strings.ToLower(key))
	resMbitKey := fmt.Sprintf("%s_reservation_mbit", strings.ToLower(key))

	structure.SetInt64Ptr(d, maxMbitKey, obj.AllocationInfo.Limit)
	structure.SetInt64Ptr(d, resMbitKey, obj.AllocationInfo.Reservation)
	if obj.AllocationInfo.Shares != nil {
		d.Set(shareLevelKey, obj.AllocationInfo.Shares.Level)
		d.Set(shareCountKey, obj.AllocationInfo.Shares.Shares)
	}
	return nil
}

// flattenDvsHostInfrastructureTrafficResource reads various fields from a
// DvsHostInfrastructureTrafficResource and sets appropriate keys in the
// supplied ResourceData.


func expandDVSNameArrayUplinkPortPolicy(d *schema.ResourceData) *types.DVSNameArrayUplinkPortPolicy {
	obj := &types.DVSNameArrayUplinkPortPolicy{
		UplinkPortName: structure.SliceInterfacesToStrings(d.Get("uplinks").([]interface{})),
	}
	if structure.AllFieldsEmpty(obj) {
		return nil
	}
	return obj
}

func expandDVSNameArrayUplinkPortPolicy ( d * schema . ResourceData ) * types . DVSNameArrayUplinkPortPolicy { obj := & types . DVSNameArrayUplinkPortPolicy { UplinkPortName : structure . SliceInterfacesToStrings ( d . Get ( " " ) . ( [ ] interface { } ) ) , } if structure . AllFieldsEmpty ( obj ) { return nil } return obj }

// expandDVSNameArrayUplinkPortPolicy reads certain ResourceData keys and
// returns a DVSNameArrayUplinkPortPolicy.

expandDVSNameArrayUplinkPortPolicy reads certain ResourceData keys and returns a DVSNameArrayUplinkPortPolicy .


func flattenDVSNameArrayUplinkPortPolicy(d *schema.ResourceData, obj *types.DVSNameArrayUplinkPortPolicy) error {
	if err := d.Set("uplinks", obj.UplinkPortName); err != nil {
		return err
	}
	return nil
}

func flattenDVSNameArrayUplinkPortPolicy ( d * schema . ResourceData , obj * types . DVSNameArrayUplinkPortPolicy ) error { if err := d . Set ( " " , obj . UplinkPortName ) ; err != nil { return err } return nil }

// flattenDVSNameArrayUplinkPortPolicy reads various fields from a
// DVSNameArrayUplinkPortPolicy into the passed in ResourceData.

flattenDVSNameArrayUplinkPortPolicy reads various fields from a DVSNameArrayUplinkPortPolicy into the passed in ResourceData .


func expandVMwareDVSConfigSpec(d *schema.ResourceData) *types.VMwareDVSConfigSpec {
	obj := &types.VMwareDVSConfigSpec{
		DVSConfigSpec: types.DVSConfigSpec{
			Name:                                d.Get("name").(string),
			ConfigVersion:                       d.Get("config_version").(string),
			DefaultPortConfig:                   expandVMwareDVSPortSetting(d),
			Host:                                expandSliceOfDistributedVirtualSwitchHostMemberConfigSpec(d),
			Description:                         d.Get("description").(string),
			Contact:                             expandDVSContactInfo(d),
			SwitchIpAddress:                     d.Get("ipv4_address").(string),
			InfrastructureTrafficResourceConfig: expandSliceOfDvsHostInfrastructureTrafficResource(d),
			NetworkResourceControlVersion:       d.Get("network_resource_control_version").(string),
			UplinkPortPolicy:                    expandDVSNameArrayUplinkPortPolicy(d),
		},
		MaxMtu:                      int32(d.Get("max_mtu").(int)),
		LinkDiscoveryProtocolConfig: expandLinkDiscoveryProtocolConfig(d),
		IpfixConfig:                 expandVMwareIpfixConfig(d),
		LacpApiVersion:              d.Get("lacp_api_version").(string),
		MulticastFilteringMode:      d.Get("multicast_filtering_mode").(string),
	}
	return obj
}

// expandVMwareDVSConfigSpec reads certain ResourceData keys and
// returns a VMwareDVSConfigSpec.

expandVMwareDVSConfigSpec reads certain ResourceData keys and returns a VMwareDVSConfigSpec .


func flattenVMwareDVSConfigInfo(d *schema.ResourceData, obj *types.VMwareDVSConfigInfo) error {
	d.Set("name", obj.Name)
	d.Set("config_version", obj.ConfigVersion)
	d.Set("description", obj.Description)
	d.Set("ipv4_address", obj.SwitchIpAddress)
	d.Set("max_mtu", obj.MaxMtu)
	d.Set("lacp_api_version", obj.LacpApiVersion)
	d.Set("multicast_filtering_mode", obj.MulticastFilteringMode)
	d.Set("network_resource_control_version", obj.NetworkResourceControlVersion)
	// This is not available in ConfigSpec but is available in ConfigInfo, so
	// flatten it here.
	d.Set("network_resource_control_enabled", obj.NetworkResourceManagementEnabled)

	// Version is set in this object too as ConfigInfo has the productInfo
	// property that is outside of this ConfigSpec structure.
	d.Set("version", obj.ProductInfo.Version)

	if err := flattenDVSNameArrayUplinkPortPolicy(d, obj.UplinkPortPolicy.(*types.DVSNameArrayUplinkPortPolicy)); err != nil {
		return err
	}
	if err := flattenVMwareDVSPortSetting(d, obj.DefaultPortConfig.(*types.VMwareDVSPortSetting)); err != nil {
		return err
	}
	if err := flattenSliceOfDistributedVirtualSwitchHostMember(d, obj.Host); err != nil {
		return err
	}
	if err := flattenSliceOfDvsHostInfrastructureTrafficResource(d, obj.InfrastructureTrafficResourceConfig); err != nil {
		return err
	}
	if err := flattenDVSContactInfo(d, obj.Contact); err != nil {
		return err
	}
	if err := flattenLinkDiscoveryProtocolConfig(d, obj.LinkDiscoveryProtocolConfig); err != nil {
		return err
	}
	if err := flattenVMwareIpfixConfig(d, obj.IpfixConfig); err != nil {
		return err
	}
	return nil
}

// flattenVMwareDVSConfigInfo reads various fields from a
// VMwareDVSConfigInfo into the passed in ResourceData.
//
// This is the flatten counterpart to expandVMwareDVSConfigSpec, as the
// configuration info from a DVS comes back as this type instead of a specific
// ConfigSpec.

flattenVMwareDVSConfigInfo reads various fields from a VMwareDVSConfigInfo into the passed in ResourceData . This is the flatten counterpart to expandVMwareDVSConfigSpec as the configuration info from a DVS comes back as this type instead of a specific ConfigSpec .


func schemaDVSCreateSpec() map[string]*schema.Schema {
	s := map[string]*schema.Schema{
		// DistributedVirtualSwitchProductSpec
		"version": {
			Type:         schema.TypeString,
			Computed:     true,
			Description:  "The version of this virtual switch. Allowed versions are 6.5.0, 6.0.0, 5.5.0, 5.1.0, and 5.0.0.",
			Optional:     true,
			ValidateFunc: validation.StringInSlice(dvsVersions, false),
		},
	}
	structure.MergeSchema(s, schemaVMwareDVSConfigSpec())

	return s
}

func
schemaDVSCreateSpec
(
)
map
[
string
]
*
schema
.
Schema
{
s
:=
map
[
string
]
*
schema
.
Schema
{
// DistributedVirtualSwitchProductSpec
"
"
:
{
Type
:
schema
.
TypeString
,
Computed
:
true
,
Description
:
"
"
,
Optional
:
true
,
ValidateFunc
:
validation
.
StringInSlice
(
dvsVersions
,
false
)
,
}
,
}
structure
.
MergeSchema
(
s
,
schemaVMwareDVSConfigSpec
(
)
)
return
s
}

// schemaDVSCreateSpec returns schema items for resources that
// need to work with a DVSCreateSpec.

schemaDVSCreateSpec returns schema items for resources that need to work with a DVSCreateSpec .


func expandDVSCreateSpec(d *schema.ResourceData) types.DVSCreateSpec {
	// Since we are only working with the version string from the product spec,
	// we don't have a separate expander/flattener for it. Just do that here.
	obj := types.DVSCreateSpec{
		ProductInfo: &types.DistributedVirtualSwitchProductSpec{
			Version: d.Get("version").(string),
		},
		ConfigSpec: expandVMwareDVSConfigSpec(d),
	}
	return obj
}

// expandDVSCreateSpec reads certain ResourceData keys and
// returns a DVSCreateSpec.

expandDVSCreateSpec reads certain ResourceData keys and returns a DVSCreateSpec .


func getWithRestart(d *schema.ResourceData, key string) interface{} {
	if d.HasChange(key) {
		log.Printf("[DEBUG] %s: Resource argument %q requires a VM restart", resourceVSphereVirtualMachineIDString(d), key)
		d.Set("reboot_required", true)
	}
	return d.Get(key)
}

func getWithRestart ( d * schema . ResourceData , key string ) interface { } { if d . HasChange ( key ) { log . Printf ( " " , resourceVSphereVirtualMachineIDString ( d ) , key ) d . Set ( " " , true ) } return d . Get ( key ) }

// getWithRestart fetches the resoruce data specified at key. If the value has
// changed, a reboot is flagged in the virtual machine by setting
// reboot_required to true.

getWithRestart fetches the resoruce data specified at key . If the value has changed a reboot is flagged in the virtual machine by setting reboot_required to true .


func vAppSubresourceSchema() map[string]*schema.Schema {
	return map[string]*schema.Schema{
		"properties": {
			Type:        schema.TypeMap,
			Optional:    true,
			Description: "A map of customizable vApp properties and their values. Allows customization of VMs cloned from OVF templates which have customizable vApp properties.",
			Elem:        &schema.Schema{Type: schema.TypeString},
		},
	}
}

func vAppSubresourceSchema ( ) map [ string ] * schema . Schema { return map [ string ] * schema . Schema { " " : { Type : schema . TypeMap , Optional : true , Description : " " , Elem : & schema . Schema { Type : schema . TypeString } , } , } }

// vAppSubresourceSchema represents the schema for the vApp sub-resource.
//
// This sub-resource allows the customization of vApp properties
// on cloned VMs.

vAppSubresourceSchema represents the schema for the vApp sub - resource . This sub - resource allows the customization of vApp properties on cloned VMs .


func expandVirtualMachineBootOptions(d *schema.ResourceData, client *govmomi.Client) *types.VirtualMachineBootOptions {
	obj := &types.VirtualMachineBootOptions{
		BootDelay:        int64(d.Get("boot_delay").(int)),
		BootRetryEnabled: structure.GetBool(d, "boot_retry_enabled"),
		BootRetryDelay:   int64(d.Get("boot_retry_delay").(int)),
	}
	// Only set EFI secure boot if we are on vSphere 6.5 and higher
	version := viapi.ParseVersionFromClient(client)
	if version.Newer(viapi.VSphereVersion{Product: version.Product, Major: 6, Minor: 5}) {
		obj.EfiSecureBootEnabled = getBoolWithRestart(d, "efi_secure_boot_enabled")
	}
	return obj
}

// expandVirtualMachineBootOptions reads certain ResourceData keys and
// returns a VirtualMachineBootOptions.

expandVirtualMachineBootOptions reads certain ResourceData keys and returns a VirtualMachineBootOptions .


func flattenVirtualMachineBootOptions(d *schema.ResourceData, obj *types.VirtualMachineBootOptions) error {
	d.Set("boot_delay", obj.BootDelay)
	structure.SetBoolPtr(d, "efi_secure_boot_enabled", obj.EfiSecureBootEnabled)
	structure.SetBoolPtr(d, "boot_retry_enabled", obj.BootRetryEnabled)
	d.Set("boot_retry_delay", obj.BootRetryDelay)
	return nil
}

func flattenVirtualMachineBootOptions ( d * schema . ResourceData , obj * types . VirtualMachineBootOptions ) error { d . Set ( " " , obj . BootDelay ) structure . SetBoolPtr ( d , " " , obj . EfiSecureBootEnabled ) structure . SetBoolPtr ( d , " " , obj . BootRetryEnabled ) d . Set ( " " , obj . BootRetryDelay ) return nil }

// flattenVirtualMachineBootOptions reads various fields from a
// VirtualMachineBootOptions into the passed in ResourceData.

flattenVirtualMachineBootOptions reads various fields from a VirtualMachineBootOptions into the passed in ResourceData .


func expandVirtualMachineFlagInfo(d *schema.ResourceData) *types.VirtualMachineFlagInfo {
	obj := &types.VirtualMachineFlagInfo{
		DiskUuidEnabled:  getBoolWithRestart(d, "enable_disk_uuid"),
		VirtualExecUsage: getWithRestart(d, "hv_mode").(string),
		VirtualMmuUsage:  getWithRestart(d, "ept_rvi_mode").(string),
		EnableLogging:    getBoolWithRestart(d, "enable_logging"),
	}
	return obj
}

func expandVirtualMachineFlagInfo ( d * schema . ResourceData ) * types . VirtualMachineFlagInfo { obj := & types . VirtualMachineFlagInfo { DiskUuidEnabled : getBoolWithRestart ( d , " " ) , VirtualExecUsage : getWithRestart ( d , " " ) . ( string ) , VirtualMmuUsage : getWithRestart ( d , " " ) . ( string ) , EnableLogging : getBoolWithRestart ( d , " " ) , } return obj }

// expandVirtualMachineFlagInfo reads certain ResourceData keys and
// returns a VirtualMachineFlagInfo.

expandVirtualMachineFlagInfo reads certain ResourceData keys and returns a VirtualMachineFlagInfo .


func flattenVirtualMachineFlagInfo(d *schema.ResourceData, obj *types.VirtualMachineFlagInfo) error {
	d.Set("enable_disk_uuid", obj.DiskUuidEnabled)
	d.Set("hv_mode", obj.VirtualExecUsage)
	d.Set("ept_rvi_mode", obj.VirtualMmuUsage)
	d.Set("enable_logging", obj.EnableLogging)
	return nil
}

func flattenVirtualMachineFlagInfo ( d * schema . ResourceData , obj * types . VirtualMachineFlagInfo ) error { d . Set ( " " , obj . DiskUuidEnabled ) d . Set ( " " , obj . VirtualExecUsage ) d . Set ( " " , obj . VirtualMmuUsage ) d . Set ( " " , obj . EnableLogging ) return nil }

// flattenVirtualMachineFlagInfo reads various fields from a
// VirtualMachineFlagInfo into the passed in ResourceData.

flattenVirtualMachineFlagInfo reads various fields from a VirtualMachineFlagInfo into the passed in ResourceData .


func expandToolsConfigInfo(d *schema.ResourceData) *types.ToolsConfigInfo {
	obj := &types.ToolsConfigInfo{
		SyncTimeWithHost:    structure.GetBool(d, "sync_time_with_host"),
		AfterPowerOn:        getBoolWithRestart(d, "run_tools_scripts_after_power_on"),
		AfterResume:         getBoolWithRestart(d, "run_tools_scripts_after_resume"),
		BeforeGuestStandby:  getBoolWithRestart(d, "run_tools_scripts_before_guest_standby"),
		BeforeGuestShutdown: getBoolWithRestart(d, "run_tools_scripts_before_guest_shutdown"),
		BeforeGuestReboot:   getBoolWithRestart(d, "run_tools_scripts_before_guest_reboot"),
	}
	return obj
}

func expandToolsConfigInfo ( d * schema . ResourceData ) * types . ToolsConfigInfo { obj := & types . ToolsConfigInfo { SyncTimeWithHost : structure . GetBool ( d , " " ) , AfterPowerOn : getBoolWithRestart ( d , " " ) , AfterResume : getBoolWithRestart ( d , " " ) , BeforeGuestStandby : getBoolWithRestart ( d , " " ) , BeforeGuestShutdown : getBoolWithRestart ( d , " " ) , BeforeGuestReboot : getBoolWithRestart ( d , " " ) , } return obj }

// expandToolsConfigInfo reads certain ResourceData keys and
// returns a ToolsConfigInfo.

expandToolsConfigInfo reads certain ResourceData keys and returns a ToolsConfigInfo .


func flattenToolsConfigInfo(d *schema.ResourceData, obj *types.ToolsConfigInfo) error {
	d.Set("sync_time_with_host", obj.SyncTimeWithHost)
	d.Set("run_tools_scripts_after_power_on", obj.AfterPowerOn)
	d.Set("run_tools_scripts_after_resume", obj.AfterResume)
	d.Set("run_tools_scripts_before_guest_standby", obj.BeforeGuestStandby)
	d.Set("run_tools_scripts_before_guest_shutdown", obj.BeforeGuestShutdown)
	d.Set("run_tools_scripts_before_guest_reboot", obj.BeforeGuestReboot)
	return nil
}

func flattenToolsConfigInfo ( d * schema . ResourceData , obj * types . ToolsConfigInfo ) error { d . Set ( " " , obj . SyncTimeWithHost ) d . Set ( " " , obj . AfterPowerOn ) d . Set ( " " , obj . AfterResume ) d . Set ( " " , obj . BeforeGuestStandby ) d . Set ( " " , obj . BeforeGuestShutdown ) d . Set ( " " , obj . BeforeGuestReboot ) return nil }

// flattenToolsConfigInfo reads various fields from a
// ToolsConfigInfo into the passed in ResourceData.

flattenToolsConfigInfo reads various fields from a ToolsConfigInfo into the passed in ResourceData .


func schemaVirtualMachineResourceAllocation() map[string]*schema.Schema {
	s := make(map[string]*schema.Schema)
	shareLevelFmt := "The allocation level for %s resources. Can be one of high, low, normal, or custom."
	shareCountFmt := "The amount of shares to allocate to %s for a custom share level."
	limitFmt := "The maximum amount of memory (in MB) or CPU (in MHz) that this virtual machine can consume, regardless of available resources."
	reservationFmt := "The amount of memory (in MB) or CPU (in MHz) that this virtual machine is guaranteed."

	for _, t := range virtualMachineResourceAllocationTypeValues {
		shareLevelKey := fmt.Sprintf("%s_share_level", t)
		shareCountKey := fmt.Sprintf("%s_share_count", t)
		limitKey := fmt.Sprintf("%s_limit", t)
		reservationKey := fmt.Sprintf("%s_reservation", t)

		s[shareLevelKey] = &schema.Schema{
			Type:         schema.TypeString,
			Optional:     true,
			Default:      string(types.SharesLevelNormal),
			Description:  fmt.Sprintf(shareLevelFmt, t),
			ValidateFunc: validation.StringInSlice(sharesLevelAllowedValues, false),
		}
		s[shareCountKey] = &schema.Schema{
			Type:         schema.TypeInt,
			Optional:     true,
			Computed:     true,
			Description:  fmt.Sprintf(shareCountFmt, t),
			ValidateFunc: validation.IntAtLeast(0),
		}
		s[limitKey] = &schema.Schema{
			Type:         schema.TypeInt,
			Optional:     true,
			Default:      -1,
			Description:  fmt.Sprintf(limitFmt, t),
			ValidateFunc: validation.IntAtLeast(-1),
		}
		s[reservationKey] = &schema.Schema{
			Type:         schema.TypeInt,
			Optional:     true,
			Description:  fmt.Sprintf(reservationFmt, t),
			ValidateFunc: validation.IntAtLeast(0),
		}
	}

	return s
}

// schemaVirtualMachineResourceAllocation returns the respective schema keys
// for the various kinds of resource allocation settings available to a virtual
// machine. This is an abridged version of ResourceAllocationInfo with only the
// keys present that make sense for virtual machines.

schemaVirtualMachineResourceAllocation returns the respective schema keys for the various kinds of resource allocation settings available to a virtual machine . This is an abridged version of ResourceAllocationInfo with only the keys present that make sense for virtual machines .


func expandVirtualMachineResourceAllocation(d *schema.ResourceData, key string) *types.ResourceAllocationInfo {
	shareLevelKey := fmt.Sprintf("%s_share_level", key)
	shareCountKey := fmt.Sprintf("%s_share_count", key)
	limitKey := fmt.Sprintf("%s_limit", key)
	reservationKey := fmt.Sprintf("%s_reservation", key)

	obj := &types.ResourceAllocationInfo{
		Limit:       structure.GetInt64PtrEmptyZero(d, limitKey),
		Reservation: structure.GetInt64PtrEmptyZero(d, reservationKey),
	}
	shares := &types.SharesInfo{
		Level:  types.SharesLevel(d.Get(shareLevelKey).(string)),
		Shares: int32(d.Get(shareCountKey).(int)),
	}
	obj.Shares = shares
	return obj
}

func expandVirtualMachineResourceAllocation ( d * schema . ResourceData , key string ) * types . ResourceAllocationInfo { shareLevelKey := fmt . Sprintf ( " " , key ) shareCountKey := fmt . Sprintf ( " " , key ) limitKey := fmt . Sprintf ( " " , key ) reservationKey := fmt . Sprintf ( " " , key ) obj := & types . ResourceAllocationInfo { Limit : structure . GetInt64PtrEmptyZero ( d , limitKey ) , Reservation : structure . GetInt64PtrEmptyZero ( d , reservationKey ) , } shares := & types . SharesInfo { Level : types . SharesLevel ( d . Get ( shareLevelKey ) . ( string ) ) , Shares : int32 ( d . Get ( shareCountKey ) . ( int ) ) , } obj . Shares = shares return obj }

// expandVirtualMachineResourceAllocation reads the VM resource allocation
// resource data keys for the type supplied by key and returns an appropriate
// types.ResourceAllocationInfo reference.

expandVirtualMachineResourceAllocation reads the VM resource allocation resource data keys for the type supplied by key and returns an appropriate types . ResourceAllocationInfo reference .


func expandLatencySensitivity(d *schema.ResourceData) *types.LatencySensitivity {
	obj := &types.LatencySensitivity{
		Level: types.LatencySensitivitySensitivityLevel(d.Get("latency_sensitivity").(string)),
	}
	return obj
}

func expandLatencySensitivity ( d * schema . ResourceData ) * types . LatencySensitivity { obj := & types . LatencySensitivity { Level : types . LatencySensitivitySensitivityLevel ( d . Get ( " " ) . ( string ) ) , } return obj }

// expandLatencySensitivity reads certain ResourceData keys and returns a
// LatencySensitivity.

expandLatencySensitivity reads certain ResourceData keys and returns a LatencySensitivity .


func flattenLatencySensitivity(d *schema.ResourceData, obj *types.LatencySensitivity) error {
	if obj == nil {
		log.Printf("[WARN] Unable to read LatencySensitivity, skipping")
		return nil
	}
	return d.Set("latency_sensitivity", obj.Level)
}

func flattenLatencySensitivity ( d * schema . ResourceData , obj * types . LatencySensitivity ) error { if obj == nil { log . Printf ( " " ) return nil } return d . Set ( " " , obj . Level ) }

// flattenLatencySensitivity reads various fields from a LatencySensitivity and
// sets appropriate keys in the supplied ResourceData.

flattenLatencySensitivity reads various fields from a LatencySensitivity and sets appropriate keys in the supplied ResourceData .


func flattenVirtualMachineResourceAllocation(d *schema.ResourceData, obj *types.ResourceAllocationInfo, key string) error {
	shareLevelKey := fmt.Sprintf("%s_share_level", key)
	shareCountKey := fmt.Sprintf("%s_share_count", key)
	limitKey := fmt.Sprintf("%s_limit", key)
	reservationKey := fmt.Sprintf("%s_reservation", key)

	structure.SetInt64Ptr(d, limitKey, obj.Limit)
	structure.SetInt64Ptr(d, reservationKey, obj.Reservation)
	if obj.Shares != nil {
		d.Set(shareLevelKey, obj.Shares.Level)
		d.Set(shareCountKey, obj.Shares.Shares)
	}
	return nil
}

func flattenVirtualMachineResourceAllocation ( d * schema . ResourceData , obj * types . ResourceAllocationInfo , key string ) error { shareLevelKey := fmt . Sprintf ( " " , key ) shareCountKey := fmt . Sprintf ( " " , key ) limitKey := fmt . Sprintf ( " " , key ) reservationKey := fmt . Sprintf ( " " , key ) structure . SetInt64Ptr ( d , limitKey , obj . Limit ) structure . SetInt64Ptr ( d , reservationKey , obj . Reservation ) if obj . Shares != nil { d . Set ( shareLevelKey , obj . Shares . Level ) d . Set ( shareCountKey , obj . Shares . Shares ) } return nil }

// flattenVirtualMachineResourceAllocation reads various fields from a
// ResourceAllocationInfo and sets appropriate keys in the
// supplied ResourceData.

flattenVirtualMachineResourceAllocation reads various fields from a ResourceAllocationInfo and sets appropriate keys in the supplied ResourceData .


func flattenVAppConfig(d *schema.ResourceData, config types.BaseVmConfigInfo) error {
	if config == nil {
		d.Set("vapp_transport", []string{})
		return nil
	}
	// Set `vapp_config here while config is available to avoid extra API calls
	d.Set("vapp_transport", config.GetVmConfigInfo().OvfEnvironmentTransport)

	props := config.GetVmConfigInfo().Property
	if len(props) < 1 {
		// No props to read is a no-op
		return nil
	}
	vac := make(map[string]interface{})
	for _, v := range props {
		if v.Value != "" && v.Value != v.DefaultValue {
			vac[v.Id] = v.Value
		}
	}
	// Only set if properties exist to prevent creating an unnecessary diff
	if len(vac) > 0 {
		return d.Set("vapp", []interface{}{
			map[string]interface{}{
				"properties": vac,
			},
		})
	}
	return nil
}

// flattenVAppConfig reads in the vAppConfig from a running virtual machine
// and sets all keys in vapp.

flattenVAppConfig reads in the vAppConfig from a running virtual machine and sets all keys in vapp .


func expandVirtualMachineConfigSpec(d *schema.ResourceData, client *govmomi.Client) (types.VirtualMachineConfigSpec, error) {
	log.Printf("[DEBUG] %s: Building config spec", resourceVSphereVirtualMachineIDString(d))
	vappConfig, err := expandVAppConfig(d, client)
	if err != nil {
		return types.VirtualMachineConfigSpec{}, err
	}

	obj := types.VirtualMachineConfigSpec{
		Name:                         d.Get("name").(string),
		GuestId:                      getWithRestart(d, "guest_id").(string),
		AlternateGuestName:           getWithRestart(d, "alternate_guest_name").(string),
		Annotation:                   d.Get("annotation").(string),
		Tools:                        expandToolsConfigInfo(d),
		Flags:                        expandVirtualMachineFlagInfo(d),
		NumCPUs:                      expandCPUCountConfig(d),
		NumCoresPerSocket:            int32(getWithRestart(d, "num_cores_per_socket").(int)),
		MemoryMB:                     expandMemorySizeConfig(d),
		MemoryHotAddEnabled:          getBoolWithRestart(d, "memory_hot_add_enabled"),
		CpuHotAddEnabled:             getBoolWithRestart(d, "cpu_hot_add_enabled"),
		CpuHotRemoveEnabled:          getBoolWithRestart(d, "cpu_hot_remove_enabled"),
		CpuAllocation:                expandVirtualMachineResourceAllocation(d, "cpu"),
		MemoryAllocation:             expandVirtualMachineResourceAllocation(d, "memory"),
		MemoryReservationLockedToMax: getMemoryReservationLockedToMax(d),
		ExtraConfig:                  expandExtraConfig(d),
		SwapPlacement:                getWithRestart(d, "swap_placement_policy").(string),
		BootOptions:                  expandVirtualMachineBootOptions(d, client),
		VAppConfig:                   vappConfig,
		Firmware:                     getWithRestart(d, "firmware").(string),
		NestedHVEnabled:              getBoolWithRestart(d, "nested_hv_enabled"),
		VPMCEnabled:                  getBoolWithRestart(d, "cpu_performance_counters_enabled"),
		LatencySensitivity:           expandLatencySensitivity(d),
	}

	return obj, nil
}

func expandVirtualMachineConfigSpec ( d * schema . ResourceData , client * govmomi . Client ) ( types . VirtualMachineConfigSpec , error ) { log . Printf ( " " , resourceVSphereVirtualMachineIDString ( d ) ) vappConfig , err := expandVAppConfig ( d , client ) if err != nil { return types . VirtualMachineConfigSpec { } , err } obj := types . VirtualMachineConfigSpec { Name : d . Get ( " " ) . ( string ) , GuestId : getWithRestart ( d , " " ) . ( string ) , AlternateGuestName : getWithRestart ( d , " " ) . ( string ) , Annotation : d . Get ( " " ) . ( string ) , Tools : expandToolsConfigInfo ( d ) , Flags : expandVirtualMachineFlagInfo ( d ) , NumCPUs : expandCPUCountConfig ( d ) , NumCoresPerSocket : int32 ( getWithRestart ( d , " " ) . ( int ) ) , MemoryMB : expandMemorySizeConfig ( d ) , MemoryHotAddEnabled : getBoolWithRestart ( d , " " ) , CpuHotAddEnabled : getBoolWithRestart ( d , " " ) , CpuHotRemoveEnabled : getBoolWithRestart ( d , " " ) , CpuAllocation : expandVirtualMachineResourceAllocation ( d , " " ) , MemoryAllocation : expandVirtualMachineResourceAllocation ( d , " " ) , MemoryReservationLockedToMax : getMemoryReservationLockedToMax ( d ) , ExtraConfig : expandExtraConfig ( d ) , SwapPlacement : getWithRestart ( d , " " ) . ( string ) , BootOptions : expandVirtualMachineBootOptions ( d , client ) , VAppConfig : vappConfig , Firmware : getWithRestart ( d , " " ) . ( string ) , NestedHVEnabled : getBoolWithRestart ( d , " " ) , VPMCEnabled : getBoolWithRestart ( d , " " ) , LatencySensitivity : expandLatencySensitivity ( d ) , } return obj , nil }

// expandVirtualMachineConfigSpec reads certain ResourceData keys and
// returns a VirtualMachineConfigSpec.

expandVirtualMachineConfigSpec reads certain ResourceData keys and returns a VirtualMachineConfigSpec .


func flattenVirtualMachineConfigInfo(d *schema.ResourceData, obj *types.VirtualMachineConfigInfo) error {
	d.Set("name", obj.Name)
	d.Set("guest_id", obj.GuestId)
	d.Set("alternate_guest_name", obj.AlternateGuestName)
	d.Set("annotation", obj.Annotation)
	d.Set("num_cpus", obj.Hardware.NumCPU)
	d.Set("num_cores_per_socket", obj.Hardware.NumCoresPerSocket)
	d.Set("memory", obj.Hardware.MemoryMB)
	d.Set("memory_hot_add_enabled", obj.MemoryHotAddEnabled)
	d.Set("cpu_hot_add_enabled", obj.CpuHotAddEnabled)
	d.Set("cpu_hot_remove_enabled", obj.CpuHotRemoveEnabled)
	d.Set("swap_placement_policy", obj.SwapPlacement)
	d.Set("firmware", obj.Firmware)
	d.Set("nested_hv_enabled", obj.NestedHVEnabled)
	d.Set("cpu_performance_counters_enabled", obj.VPMCEnabled)
	d.Set("change_version", obj.ChangeVersion)
	d.Set("uuid", obj.Uuid)

	if err := flattenToolsConfigInfo(d, obj.Tools); err != nil {
		return err
	}
	if err := flattenVirtualMachineFlagInfo(d, &obj.Flags); err != nil {
		return err
	}
	if err := flattenVirtualMachineResourceAllocation(d, obj.CpuAllocation, "cpu"); err != nil {
		return err
	}
	if err := flattenVirtualMachineResourceAllocation(d, obj.MemoryAllocation, "memory"); err != nil {
		return err
	}
	if err := flattenExtraConfig(d, obj.ExtraConfig); err != nil {
		return err
	}
	if err := flattenVAppConfig(d, obj.VAppConfig); err != nil {
		return err
	}
	if err := flattenLatencySensitivity(d, obj.LatencySensitivity); err != nil {
		return err
	}

	// This method does not operate any different than the above method but we
	// return its error result directly to ensure there are no warnings in the
	// linter. It's awkward, but golint does not allow setting exceptions.
	return flattenVirtualMachineBootOptions(d, obj.BootOptions)
}

// flattenVirtualMachineConfigInfo reads various fields from a
// VirtualMachineConfigInfo into the passed in ResourceData.
//
// This is the flatten counterpart to expandVirtualMachineConfigSpec.

flattenVirtualMachineConfigInfo reads various fields from a VirtualMachineConfigInfo into the passed in ResourceData . This is the flatten counterpart to expandVirtualMachineConfigSpec .


func expandVirtualMachineConfigSpecChanged(d *schema.ResourceData, client *govmomi.Client, info *types.VirtualMachineConfigInfo) (types.VirtualMachineConfigSpec, bool, error) {
	// Create the fake ResourceData from the VM resource
	oldData := resourceVSphereVirtualMachine().Data(&terraform.InstanceState{})
	oldData.SetId(d.Id())
	// Flatten the old config info into it
	flattenVirtualMachineConfigInfo(oldData, info)
	// Read state back in. This is necessary to ensure GetChange calls work
	// correctly.
	oldData = resourceVSphereVirtualMachine().Data(oldData.State())
	// Get both specs.
	log.Printf("[DEBUG] %s: Expanding old config. Ignore reboot_required messages", resourceVSphereVirtualMachineIDString(d))
	oldSpec, err := expandVirtualMachineConfigSpec(oldData, client)
	if err != nil {
		return types.VirtualMachineConfigSpec{}, false, err
	}
	log.Printf("[DEBUG] %s: Expanding of old config complete", resourceVSphereVirtualMachineIDString(d))

	newSpec, err := expandVirtualMachineConfigSpec(d, client)
	if err != nil {
		return types.VirtualMachineConfigSpec{}, false, err
	}

	// Return the new spec and compare
	return newSpec, !reflect.DeepEqual(oldSpec, newSpec), nil
}

// expandVirtualMachineConfigSpecChanged compares an existing
// VirtualMachineConfigInfo with a VirtualMachineConfigSpec generated from
// existing resource data and compares them to see if there is a change. The new spec
//
// It does this be creating a fake ResourceData off of the VM resource schema,
// flattening the config info into that, and then expanding both ResourceData
// instances and comparing the resultant ConfigSpecs.

expandVirtualMachineConfigSpecChanged compares an existing VirtualMachineConfigInfo with a VirtualMachineConfigSpec generated from existing resource data and compares them to see if there is a change . The new spec It does this be creating a fake ResourceData off of the VM resource schema flattening the config info into that and then expanding both ResourceData instances and comparing the resultant ConfigSpecs .


func getMemoryReservationLockedToMax(d *schema.ResourceData) *bool {
	if d.Get("memory_reservation").(int) != d.Get("memory").(int) {
		return structure.BoolPtr(false)
	}
	return nil
}

func getMemoryReservationLockedToMax ( d * schema . ResourceData ) * bool { if d . Get ( " " ) . ( int ) != d . Get ( " " ) . ( int ) { return structure . BoolPtr ( false ) } return nil }

// getMemoryReservationLockedToMax determines if the memory_reservation is not
// set to be equal to memory. If they are not equal, then the memory
// reservation needs to be unlocked from the maximum. Rather than supporting
// the locking reservation to max option, we can set memory_reservation to
// memory in the configuration. Not supporting the option causes problems when
// cloning from a template that has it enabled. The solution is to set it to
// false when needed, but leave it alone when the change is not necessary.

getMemoryReservationLockedToMax determines if the memory_reservation is not set to be equal to memory . If they are not equal then the memory reservation needs to be unlocked from the maximum . Rather than supporting the locking reservation to max option we can set memory_reservation to memory in the configuration . Not supporting the option causes problems when cloning from a template that has it enabled . The solution is to set it to false when needed but leave it alone when the change is not necessary .


func FromPathOrDefault(client *govmomi.Client, name string, dc *object.Datacenter) (*object.ResourcePool, error) {
	finder := find.NewFinder(client.Client, false)

	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	t := client.ServiceContent.About.ApiType
	switch t {
	case "HostAgent":
		ddc, err := finder.DefaultDatacenter(ctx)
		if err != nil {
			return nil, err
		}
		finder.SetDatacenter(ddc)
		return finder.DefaultResourcePool(ctx)
	case "VirtualCenter":
		if dc != nil {
			finder.SetDatacenter(dc)
		}
		if name != "" {
			return finder.ResourcePool(ctx, name)
		}
		return finder.DefaultResourcePool(ctx)
	}
	return nil, fmt.Errorf("unsupported ApiType: %s", t)
}

func FromPathOrDefault ( client * govmomi . Client , name string , dc * object . Datacenter ) ( * object . ResourcePool , error ) { finder := find . NewFinder ( client . Client , false ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) t := client . ServiceContent . About . ApiType switch t { case " " : ddc , err := finder . DefaultDatacenter ( ctx ) if err != nil { return nil , err } finder . SetDatacenter ( ddc ) return finder . DefaultResourcePool ( ctx ) case " " : if dc != nil { finder . SetDatacenter ( dc ) } if name != " " { return finder . ResourcePool ( ctx , name ) } return finder . DefaultResourcePool ( ctx ) } return nil , fmt . Errorf ( " " , t ) }

// FromPathOrDefault returns a ResourcePool via its supplied path.

FromPathOrDefault returns a ResourcePool via its supplied path .


func Properties(obj *object.ResourcePool) (*mo.ResourcePool, error) {
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	var props mo.ResourcePool
	if err := obj.Properties(ctx, obj.Reference(), nil, &props); err != nil {
		return nil, err
	}
	return &props, nil
}

func Properties ( obj * object . ResourcePool ) ( * mo . ResourcePool , error ) { ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) var props mo . ResourcePool if err := obj . Properties ( ctx , obj . Reference ( ) , nil , & props ) ; err != nil { return nil , err } return & props , nil }

// Properties returns the ResourcePool managed object from its higher-level
// object.

Properties returns the ResourcePool managed object from its higher - level object .


func ValidateHost(client *govmomi.Client, pool *object.ResourcePool, host *object.HostSystem) error {
	if host == nil {
		// Nothing to validate here, move along
		log.Printf("[DEBUG] ValidateHost: no host supplied, nothing to do")
		return nil
	}
	log.Printf("[DEBUG] Validating that host %q is a member of resource pool %q", host.Reference().Value, pool.Reference().Value)
	pprops, err := Properties(pool)
	if err != nil {
		return err
	}
	cprops, err := computeresource.BasePropertiesFromReference(client, pprops.Owner)
	if err != nil {
		return err
	}
	for _, href := range cprops.Host {
		if href.Value == host.Reference().Value {
			log.Printf("[DEBUG] Validated that host %q is a member of resource pool %q.", host.Reference().Value, pool.Reference().Value)
			return nil
		}
	}
	return fmt.Errorf("host ID %q is not a member of resource pool %q", host.Reference().Value, pool.Reference().Value)
}

func
ValidateHost
(
client
*
govmomi
.
Client
,
pool
*
object
.
ResourcePool
,
host
*
object
.
HostSystem
)
error
{
if
host
==
{
// Nothing to validate here, move along
log
.
Printf
(
"
"
)
return
}
log
.
Printf
(
"
"
,
host
.
Reference
(
)
.
Value
,
pool
.
Reference
(
)
.
Value
)
pprops
,
err
:=
Properties
(
pool
)
if
err
!=
{
return
err
}
cprops
,
err
:=
computeresource
.
BasePropertiesFromReference
(
client
,
pprops
.
Owner
)
if
err
!=
{
return
err
}
for
_
,
href
:=
range
cprops
.
Host
{
if
href
.
Value
==
host
.
Reference
(
)
.
Value
{
log
.
Printf
(
"
"
,
host
.
Reference
(
)
.
Value
,
pool
.
Reference
(
)
.
Value
)
return
}
}
return
fmt
.
Errorf
(
"
"
,
host
.
Reference
(
)
.
Value
,
pool
.
Reference
(
)
.
Value
)
}

// ValidateHost checks to see if a HostSystem is a member of a ResourcePool
// through cluster membership, or if the HostSystem ID matches the ID of a
// standalone host ComputeResource. An error is returned if it is not a member
// of the cluster to which the resource pool belongs, or if there was some sort
// of other error with checking.
//
// This is used as an extra validation before a VM creation happens, or vMotion
// to a specific host is attempted.

ValidateHost checks to see if a HostSystem is a member of a ResourcePool through cluster membership or if the HostSystem ID matches the ID of a standalone host ComputeResource . An error is returned if it is not a member of the cluster to which the resource pool belongs or if there was some sort of other error with checking . This is used as an extra validation before a VM creation happens or vMotion to a specific host is attempted .


func OSFamily(client *govmomi.Client, pool *object.ResourcePool, guest string) (string, error) {
	log.Printf("[DEBUG] Looking for OS family for guest ID %q", guest)
	pprops, err := Properties(pool)
	if err != nil {
		return "", err
	}
	return computeresource.OSFamily(client, pprops.Owner, guest)
}

func OSFamily ( client * govmomi . Client , pool * object . ResourcePool , guest string ) ( string , error ) { log . Printf ( " " , guest ) pprops , err := Properties ( pool ) if err != nil { return " " , err } return computeresource . OSFamily ( client , pprops . Owner , guest ) }

// OSFamily uses the resource pool's environment browser to get the OS family
// for a specific guest ID.

OSFamily uses the resource pool s environment browser to get the OS family for a specific guest ID .


func Create(rp *object.ResourcePool, name string, spec *types.ResourceConfigSpec) (*object.ResourcePool, error) {
	log.Printf("[DEBUG] Creating resource pool %q", fmt.Sprintf("%s/%s", rp.InventoryPath, name))
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	nrp, err := rp.Create(ctx, name, *spec)
	if err != nil {
		return nil, err
	}
	return nrp, nil
}

func Create ( rp * object . ResourcePool , name string , spec * types . ResourceConfigSpec ) ( * object . ResourcePool , error ) { log . Printf ( " " , fmt . Sprintf ( " " , rp . InventoryPath , name ) ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) nrp , err := rp . Create ( ctx , name , * spec ) if err != nil { return nil , err } return nrp , nil }


func Update(rp *object.ResourcePool, name string, spec *types.ResourceConfigSpec) error {
	log.Printf("[DEBUG] Updating resource pool %q", fmt.Sprintf("%s", rp.InventoryPath))
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	return rp.UpdateConfig(ctx, name, spec)
}

func Update ( rp * object . ResourcePool , name string , spec * types . ResourceConfigSpec ) error { log . Printf ( " " , fmt . Sprintf ( " " , rp . InventoryPath ) ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) return rp . UpdateConfig ( ctx , name , spec ) }


func MoveIntoResourcePool(p *object.ResourcePool, c types.ManagedObjectReference) error {
	req := types.MoveIntoResourcePool{
		This: p.Reference(),
		List: []types.ManagedObjectReference{c},
	}
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	_, err := methods.MoveIntoResourcePool(ctx, p.Client(), &req)
	return err
}

func MoveIntoResourcePool ( p * object . ResourcePool , c types . ManagedObjectReference ) error { req := types . MoveIntoResourcePool { This : p . Reference ( ) , List : [ ] types . ManagedObjectReference { c } , } ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) _ , err := methods . MoveIntoResourcePool ( ctx , p . Client ( ) , & req ) return err }

// MoveIntoResourcePool moves a virtual machine, resource pool, or
// vApp into the specified ResourcePool.

MoveIntoResourcePool moves a virtual machine resource pool or vApp into the specified ResourcePool .


func expandClusterDasVMConfigInfo(
	d *schema.ResourceData,
	meta interface{},
	vm *object.VirtualMachine,
) (*types.ClusterDasVmConfigInfo, error) {
	client, err := resourceVSphereHAVMOverrideClient(meta)
	if err != nil {
		return nil, err
	}
	version := viapi.ParseVersionFromClient(client)

	obj := &types.ClusterDasVmConfigInfo{
		DasSettings: expandClusterDasVMSettings(d, version),
		Key:         vm.Reference(),
	}

	// Expand ha_vm_monitoring_use_cluster_defaults here as it's not included in
	// the base vsphere_compute_cluster resource.
	obj.DasSettings.VmToolsMonitoringSettings.ClusterSettings = structure.GetBool(d, "ha_vm_monitoring_use_cluster_defaults")

	return obj, nil
}

// expandClusterDasVMConfigInfo reads certain ResourceData keys and returns a
// ClusterDasVmConfigInfo.

expandClusterDasVMConfigInfo reads certain ResourceData keys and returns a ClusterDasVmConfigInfo .


func flattenClusterDasVMConfigInfo(d *schema.ResourceData, meta interface{}, obj *types.ClusterDasVmConfigInfo) error {
	client, err := resourceVSphereHAVMOverrideClient(meta)
	if err != nil {
		return err
	}
	version := viapi.ParseVersionFromClient(client)

	// Set ha_vm_monitoring_use_cluster_defaults here as it's not included in the
	// base vsphere_compute_cluster resource.
	if err := d.Set("ha_vm_monitoring_use_cluster_defaults", obj.DasSettings.VmToolsMonitoringSettings.ClusterSettings); err != nil {
		return err
	}
	return flattenClusterDasVMSettings(d, obj.DasSettings, version)
}

// flattenClusterDasVmConfigInfo saves a ClusterDasVmConfigInfo into the
// supplied ResourceData.

flattenClusterDasVmConfigInfo saves a ClusterDasVmConfigInfo into the supplied ResourceData .


func resourceVSphereHAVMOverrideFlattenID(cluster *object.ClusterComputeResource, vm *object.VirtualMachine) (string, error) {
	clusterID := cluster.Reference().Value
	props, err := virtualmachine.Properties(vm)
	if err != nil {
		return "", fmt.Errorf("cannot compute ID off of properties of virtual machine: %s", err)
	}
	vmID := props.Config.Uuid
	return strings.Join([]string{clusterID, vmID}, ":"), nil
}

func resourceVSphereHAVMOverrideFlattenID ( cluster * object . ClusterComputeResource , vm * object . VirtualMachine ) ( string , error ) { clusterID := cluster . Reference ( ) . Value props , err := virtualmachine . Properties ( vm ) if err != nil { return " " , fmt . Errorf ( " " , err ) } vmID := props . Config . Uuid return strings . Join ( [ ] string { clusterID , vmID } , " " ) , nil }

// resourceVSphereHAVMOverrideFlattenID makes an ID for the
// vsphere_ha_vm_override resource.

resourceVSphereHAVMOverrideFlattenID makes an ID for the vsphere_ha_vm_override resource .


func resourceVSphereHAVMOverrideFindEntry(
	cluster *object.ClusterComputeResource,
	vm *object.VirtualMachine,
) (*types.ClusterDasVmConfigInfo, error) {
	props, err := clustercomputeresource.Properties(cluster)
	if err != nil {
		return nil, fmt.Errorf("error fetching cluster properties: %s", err)
	}

	for _, info := range props.ConfigurationEx.(*types.ClusterConfigInfoEx).DasVmConfig {
		if info.Key == vm.Reference() {
			log.Printf("[DEBUG] Found HA config info for VM %q in cluster %q", vm.Name(), cluster.Name())
			return &info, nil
		}
	}

	log.Printf("[DEBUG] No HA config info found for VM %q in cluster %q", vm.Name(), cluster.Name())
	return nil, nil
}

func resourceVSphereHAVMOverrideFindEntry ( cluster * object . ClusterComputeResource , vm * object . VirtualMachine , ) ( * types . ClusterDasVmConfigInfo , error ) { props , err := clustercomputeresource . Properties ( cluster ) if err != nil { return nil , fmt . Errorf ( " " , err ) } for _ , info := range props . ConfigurationEx . ( * types . ClusterConfigInfoEx ) . DasVmConfig { if info . Key == vm . Reference ( ) { log . Printf ( " " , vm . Name ( ) , cluster . Name ( ) ) return & info , nil } } log . Printf ( " " , vm . Name ( ) , cluster . Name ( ) ) return nil , nil }

// resourceVSphereHAVMOverrideFindEntry attempts to locate an existing
// VM-specific HA config in a cluster's configuration. It's used by the
// resource's read functionality and tests. nil is returned if the entry cannot
// be found.

resourceVSphereHAVMOverrideFindEntry attempts to locate an existing VM - specific HA config in a cluster s configuration . It s used by the resource s read functionality and tests . nil is returned if the entry cannot be found .


func schemaHostPortGroupSpec() map[string]*schema.Schema {
	s := map[string]*schema.Schema{
		// HostPortGroupSpec
		"name": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "The name of the port group.",
			ForceNew:    true,
		},
		"vlan_id": {
			Type:         schema.TypeInt,
			Optional:     true,
			Description:  "The VLAN ID/trunk mode for this port group. An ID of 0 denotes no tagging, an ID of 1-4094 tags with the specific ID, and an ID of 4095 enables trunk mode, allowing the guest to manage its own tagging.",
			Default:      0,
			ValidateFunc: validation.IntBetween(0, 4095),
		},
		"virtual_switch_name": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "The name of the virtual switch to bind this port group to.",
			ForceNew:    true,
		},
	}
	structure.MergeSchema(s, schemaHostNetworkPolicy())
	return s
}

func
schemaHostPortGroupSpec
(
)
map
[
string
]
*
schema
.
Schema
{
s
:=
map
[
string
]
*
schema
.
Schema
{
// HostPortGroupSpec
"
"
:
{
Type
:
schema
.
TypeString
,
Required
:
true
,
Description
:
"
"
,
ForceNew
:
true
,
}
,
"
"
:
{
Type
:
schema
.
TypeInt
,
Optional
:
true
,
Description
:
"
"
,
Default
:
0
,
ValidateFunc
:
validation
.
IntBetween
(
0
,
4095
)
,
}
,
"
"
:
{
Type
:
schema
.
TypeString
,
Required
:
true
,
Description
:
"
"
,
ForceNew
:
true
,
}
,
}
structure
.
MergeSchema
(
s
,
schemaHostNetworkPolicy
(
)
)
return
s
}

// schemaHostPortGroupSpec returns schema items for resources that
// need to work with HostPortGroupSpec, such as port groups.

schemaHostPortGroupSpec returns schema items for resources that need to work with HostPortGroupSpec such as port groups .


func expandHostPortGroupSpec(d *schema.ResourceData) *types.HostPortGroupSpec {
	obj := &types.HostPortGroupSpec{
		Name:        d.Get("name").(string),
		VlanId:      int32(d.Get("vlan_id").(int)),
		VswitchName: d.Get("virtual_switch_name").(string),
		Policy:      *expandHostNetworkPolicy(d),
	}
	return obj
}

func expandHostPortGroupSpec ( d * schema . ResourceData ) * types . HostPortGroupSpec { obj := & types . HostPortGroupSpec { Name : d . Get ( " " ) . ( string ) , VlanId : int32 ( d . Get ( " " ) . ( int ) ) , VswitchName : d . Get ( " " ) . ( string ) , Policy : * expandHostNetworkPolicy ( d ) , } return obj }

// expandHostPortGroupSpec reads certain ResourceData keys and returns a
// HostPortGroupSpec.

expandHostPortGroupSpec reads certain ResourceData keys and returns a HostPortGroupSpec .


func flattenHostPortGroupSpec(d *schema.ResourceData, obj *types.HostPortGroupSpec) error {
	d.Set("vlan_id", obj.VlanId)
	if err := flattenHostNetworkPolicy(d, &obj.Policy); err != nil {
		return err
	}
	return nil
}

func flattenHostPortGroupSpec ( d * schema . ResourceData , obj * types . HostPortGroupSpec ) error { d . Set ( " " , obj . VlanId ) if err := flattenHostNetworkPolicy ( d , & obj . Policy ) ; err != nil { return err } return nil }

// flattenHostPortGroupSpec reads various fields from a HostPortGroupSpec into
// the passed in ResourceData.

flattenHostPortGroupSpec reads various fields from a HostPortGroupSpec into the passed in ResourceData .


func calculatePorts(ports []types.HostPortGroupPort) *schema.Set {
	s := make([]interface{}, 0)
	for _, port := range ports {
		m := make(map[string]interface{})
		m["key"] = port.Key
		m["mac_addresses"] = structure.SliceStringsToInterfaces(port.Mac)
		m["type"] = port.Type
		s = append(s, m)
	}
	return schema.NewSet(schema.HashResource(portGroupPortSchema()), s)
}

func calculatePorts ( ports [ ] types . HostPortGroupPort ) * schema . Set { s := make ( [ ] interface { } , 0 ) for _ , port := range ports { m := make ( map [ string ] interface { } ) m [ " " ] = port . Key m [ " " ] = structure . SliceStringsToInterfaces ( port . Mac ) m [ " " ] = port . Type s = append ( s , m ) } return schema . NewSet ( schema . HashResource ( portGroupPortSchema ( ) ) , s ) }

// calculatePorts is a utility function that returns a set of port data.

calculatePorts is a utility function that returns a set of port data .


func portGroupPortSchema() *schema.Resource {
	return &schema.Resource{
		Schema: map[string]*schema.Schema{
			"key": {
				Type:        schema.TypeString,
				Description: "The linkable identifier for this port entry.",
				Computed:    true,
			},
			"mac_addresses": {
				Type:        schema.TypeList,
				Description: "The MAC addresses of the network service of the virtual machine connected on this port.",
				Computed:    true,
				Elem:        &schema.Schema{Type: schema.TypeString},
			},
			"type": {
				Type:        schema.TypeString,
				Description: "Type type of the entity connected on this port. Possible values are host (VMKkernel), systemManagement (service console), virtualMachine, or unknown.",
				Computed:    true,
			},
		},
	}
}

func portGroupPortSchema ( ) * schema . Resource { return & schema . Resource { Schema : map [ string ] * schema . Schema { " " : { Type : schema . TypeString , Description : " " , Computed : true , } , " " : { Type : schema . TypeList , Description : " " , Computed : true , Elem : & schema . Schema { Type : schema . TypeString } , } , " " : { Type : schema . TypeString , Description : " " , Computed : true , } , } , } }

// portGroupPortSchema returns a sub-schema for a port group's connected ports.

portGroupPortSchema returns a sub - schema for a port group s connected ports .


func saveHostPortGroupID(d *schema.ResourceData, hsID, name string) {
	d.SetId(fmt.Sprintf("%s:%s:%s", hostPortGroupIDPrefix, hsID, name))
}

func saveHostPortGroupID ( d * schema . ResourceData , hsID , name string ) { d . SetId ( fmt . Sprintf ( " " , hostPortGroupIDPrefix , hsID , name ) ) }

// saveHostPortGroupID sets a special ID for a host virtual switch, composed of
// the MOID for the concerned HostSystem and the port group's key.

saveHostPortGroupID sets a special ID for a host virtual switch composed of the MOID for the concerned HostSystem and the port group s key .


func portGroupIDsFromResourceID(d *schema.ResourceData) (string, string, error) {
	return splitHostPortGroupID(d.Id())
}

func portGroupIDsFromResourceID ( d * schema . ResourceData ) ( string , string , error ) { return splitHostPortGroupID ( d . Id ( ) ) }

// portGroupIDsFromResourceID passes a resource's ID through
// splitHostPortGroupID.

portGroupIDsFromResourceID passes a resource s ID through splitHostPortGroupID .


func BaseFromPath(client *govmomi.Client, path string) (BaseComputeResource, error) {
	finder := find.NewFinder(client.Client, false)

	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	list, err := finder.ManagedObjectList(ctx, path, "ComputeResource", "ClusterComputeResource")
	if err != nil {
		return nil, err
	}
	if len(list) < 1 {
		return nil, fmt.Errorf("no compute resources found at path %q", path)
	}
	if len(list) > 1 {
		return nil, fmt.Errorf("multiple results returned for path %q", path)
	}
	if !strings.HasSuffix(list[0].Path, path) {
		return nil, fmt.Errorf("returned object path %q does not properly match search path %q", list[0].Path, path)
	}
	return BaseFromReference(client, list[0].Object.Reference())
}

func BaseFromPath ( client * govmomi . Client , path string ) ( BaseComputeResource , error ) { finder := find . NewFinder ( client . Client , false ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) list , err := finder . ManagedObjectList ( ctx , path , " " , " " ) if err != nil { return nil , err } if len ( list ) < 1 { return nil , fmt . Errorf ( " " , path ) } if len ( list ) > 1 { return nil , fmt . Errorf ( " " , path ) } if ! strings . HasSuffix ( list [ 0 ] . Path , path ) { return nil , fmt . Errorf ( " " , list [ 0 ] . Path , path ) } return BaseFromReference ( client , list [ 0 ] . Object . Reference ( ) ) }

// BaseFromPath returns a BaseComputeResource for a given path.

BaseFromPath returns a BaseComputeResource for a given path .


func BaseFromReference(client *govmomi.Client, ref types.ManagedObjectReference) (BaseComputeResource, error) {
	switch ref.Type {
	case "ComputeResource":
		return StandaloneFromID(client, ref.Value)
	case "ClusterComputeResource":
		return StandaloneFromID(client, ref.Value)
	}
	return nil, fmt.Errorf("unknown object type %s", ref.Type)
}

func BaseFromReference ( client * govmomi . Client , ref types . ManagedObjectReference ) ( BaseComputeResource , error ) { switch ref . Type { case " " : return StandaloneFromID ( client , ref . Value ) case " " : return StandaloneFromID ( client , ref . Value ) } return nil , fmt . Errorf ( " " , ref . Type ) }

// BaseFromReference returns a BaseComputeResource for a given managed object
// reference.

BaseFromReference returns a BaseComputeResource for a given managed object reference .


func BaseProperties(obj BaseComputeResource) (*mo.ComputeResource, error) {
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	var props mo.ComputeResource
	if err := obj.Properties(ctx, obj.Reference(), nil, &props); err != nil {
		return nil, err
	}
	return &props, nil
}

func BaseProperties ( obj BaseComputeResource ) ( * mo . ComputeResource , error ) { ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) var props mo . ComputeResource if err := obj . Properties ( ctx , obj . Reference ( ) , nil , & props ) ; err != nil { return nil , err } return & props , nil }

// BaseProperties returns the base-level ComputeResource managed object for a
// BaseComputeResource, an interface that any base-level ComputeResource and
// derivative object implements.
//
// Note that this does not return any cluster-level attributes.

BaseProperties returns the base - level ComputeResource managed object for a BaseComputeResource an interface that any base - level ComputeResource and derivative object implements . Note that this does not return any cluster - level attributes .


func BasePropertiesFromReference(client *govmomi.Client, ref types.ManagedObjectReference) (*mo.ComputeResource, error) {
	obj, err := BaseFromReference(client, ref)
	if err != nil {
		return nil, err
	}
	return BaseProperties(obj)
}

func BasePropertiesFromReference ( client * govmomi . Client , ref types . ManagedObjectReference ) ( * mo . ComputeResource , error ) { obj , err := BaseFromReference ( client , ref ) if err != nil { return nil , err } return BaseProperties ( obj ) }

// BasePropertiesFromReference combines BaseFromReference and BaseProperties to
// get a base-level ComputeResource managed object for a specific managed
// object reference.

BasePropertiesFromReference combines BaseFromReference and BaseProperties to get a base - level ComputeResource managed object for a specific managed object reference .


func DefaultDevicesFromReference(client *govmomi.Client, ref types.ManagedObjectReference, guest string) (object.VirtualDeviceList, error) {
	log.Printf("[DEBUG] Fetching default device list for object reference %q for OS type %q", ref.Value, guest)
	b, err := EnvironmentBrowserFromReference(client, ref)
	if err != nil {
		return nil, err
	}
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	return b.DefaultDevices(ctx, "", nil)
}

func DefaultDevicesFromReference ( client * govmomi . Client , ref types . ManagedObjectReference , guest string ) ( object . VirtualDeviceList , error ) { log . Printf ( " " , ref . Value , guest ) b , err := EnvironmentBrowserFromReference ( client , ref ) if err != nil { return nil , err } ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) return b . DefaultDevices ( ctx , " " , nil ) }

// DefaultDevicesFromReference fetches the default virtual device list for a
// specific compute resource from a supplied managed object reference.

DefaultDevicesFromReference fetches the default virtual device list for a specific compute resource from a supplied managed object reference .


func OSFamily(client *govmomi.Client, ref types.ManagedObjectReference, guest string) (string, error) {
	b, err := EnvironmentBrowserFromReference(client, ref)
	if err != nil {
		return "", err
	}
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	return b.OSFamily(ctx, guest)
}

func OSFamily ( client * govmomi . Client , ref types . ManagedObjectReference , guest string ) ( string , error ) { b , err := EnvironmentBrowserFromReference ( client , ref ) if err != nil { return " " , err } ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) return b . OSFamily ( ctx , guest ) }

// OSFamily uses the compute resource's environment browser to get the OS family
// for a specific guest ID.

OSFamily uses the compute resource s environment browser to get the OS family for a specific guest ID .


func EnvironmentBrowserFromReference(client *govmomi.Client, ref types.ManagedObjectReference) (*envbrowse.EnvironmentBrowser, error) {
	cr, err := BaseFromReference(client, ref)
	if err != nil {
		return nil, err
	}
	props, err := BaseProperties(cr)
	if err != nil {
		return nil, err
	}
	if props.EnvironmentBrowser == nil {
		return nil, fmt.Errorf(
			"compute resource %q is missing an Environment Browser. Check host, cluster, and vSphere license health of all associated resources and try again",
			cr,
		)
	}
	return envbrowse.NewEnvironmentBrowser(client.Client, *props.EnvironmentBrowser), nil
}

func EnvironmentBrowserFromReference ( client * govmomi . Client , ref types . ManagedObjectReference ) ( * envbrowse . EnvironmentBrowser , error ) { cr , err := BaseFromReference ( client , ref ) if err != nil { return nil , err } props , err := BaseProperties ( cr ) if err != nil { return nil , err } if props . EnvironmentBrowser == nil { return nil , fmt . Errorf ( " " , cr , ) } return envbrowse . NewEnvironmentBrowser ( client . Client , * props . EnvironmentBrowser ) , nil }

// EnvironmentBrowserFromReference loads an environment browser for the
// specific compute resource reference. The reference can be either a
// standalone host or cluster.
//
// As an added safety feature if the compute resource properties come back with
// an unset environmentBrowser attribute, this function will return an error.
// This is to protect against cases where this may come up such as licensing
// issues or clusters without hosts.

EnvironmentBrowserFromReference loads an environment browser for the specific compute resource reference . The reference can be either a standalone host or cluster . As an added safety feature if the compute resource properties come back with an unset environmentBrowser attribute this function will return an error . This is to protect against cases where this may come up such as licensing issues or clusters without hosts .


func Properties(cluster *object.ClusterComputeResource) (*mo.ClusterComputeResource, error) {
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	var props mo.ClusterComputeResource
	if err := cluster.Properties(ctx, cluster.Reference(), nil, &props); err != nil {
		return nil, err
	}
	return &props, nil
}

func Properties ( cluster * object . ClusterComputeResource ) ( * mo . ClusterComputeResource , error ) { ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) var props mo . ClusterComputeResource if err := cluster . Properties ( ctx , cluster . Reference ( ) , nil , & props ) ; err != nil { return nil , err } return & props , nil }

// Properties is a convenience method that wraps fetching the
// ClusterComputeResource MO from its higher-level object.

Properties is a convenience method that wraps fetching the ClusterComputeResource MO from its higher - level object .


func Create(f *object.Folder, name string, spec types.ClusterConfigSpecEx) (*object.ClusterComputeResource, error) {
	log.Printf("[DEBUG] Creating compute cluster %q", fmt.Sprintf("%s/%s", f.InventoryPath, name))
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	cluster, err := f.CreateCluster(ctx, name, spec)
	if err != nil {
		return nil, err
	}
	return cluster, nil
}

func Create ( f * object . Folder , name string , spec types . ClusterConfigSpecEx ) ( * object . ClusterComputeResource , error ) { log . Printf ( " " , fmt . Sprintf ( " " , f . InventoryPath , name ) ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) cluster , err := f . CreateCluster ( ctx , name , spec ) if err != nil { return nil , err } return cluster , nil }

// Create creates a ClusterComputeResource in a supplied folder. The resulting
// ClusterComputeResource is returned.

Create creates a ClusterComputeResource in a supplied folder . The resulting ClusterComputeResource is returned .


func MoveToFolder(client *govmomi.Client, cluster *object.ClusterComputeResource, relative string) error {
	f, err := folder.HostFolderFromObject(client, cluster, relative)
	if err != nil {
		return err
	}
	return folder.MoveObjectTo(cluster.Reference(), f)
}

func MoveToFolder ( client * govmomi . Client , cluster * object . ClusterComputeResource , relative string ) error { f , err := folder . HostFolderFromObject ( client , cluster , relative ) if err != nil { return err } return folder . MoveObjectTo ( cluster . Reference ( ) , f ) }

// MoveToFolder is a complex method that moves a ClusterComputeResource to a given relative
// compute folder path. "Relative" here means relative to a datacenter, which
// is discovered from the current ClusterComputeResource path.

MoveToFolder is a complex method that moves a ClusterComputeResource to a given relative compute folder path . Relative here means relative to a datacenter which is discovered from the current ClusterComputeResource path .


func Reconfigure(cluster *object.ClusterComputeResource, spec *types.ClusterConfigSpecEx) error {
	return computeresource.Reconfigure(cluster, spec)
}

func Reconfigure ( cluster * object . ClusterComputeResource , spec * types . ClusterConfigSpecEx ) error { return computeresource . Reconfigure ( cluster , spec ) }

// Reconfigure reconfigures a cluster. This just gets dispatched to
// computeresource as both methods are the same.

Reconfigure reconfigures a cluster . This just gets dispatched to computeresource as both methods are the same .


func Delete(cluster *object.ClusterComputeResource) error {
	log.Printf("[DEBUG] Deleting compute cluster %q", cluster.InventoryPath)
	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	task, err := cluster.Destroy(ctx)
	if err != nil {
		return err
	}
	return task.Wait(ctx)
}

func Delete ( cluster * object . ClusterComputeResource ) error { log . Printf ( " " , cluster . InventoryPath ) ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) task , err := cluster . Destroy ( ctx ) if err != nil { return err } return task . Wait ( ctx ) }

// Delete destroys a ClusterComputeResource.

Delete destroys a ClusterComputeResource .


func IsMember(cluster *object.ClusterComputeResource, host *object.HostSystem) (bool, error) {
	hprops, err := hostsystem.Properties(host)
	if err != nil {
		return false, fmt.Errorf("error getting properties for cluster %q: %s", host.Name(), err)
	}
	if hprops.Parent == nil {
		return false, nil
	}
	if *hprops.Parent != cluster.Reference() {
		return false, nil
	}
	return true, nil
}

func IsMember ( cluster * object . ClusterComputeResource , host * object . HostSystem ) ( bool , error ) { hprops , err := hostsystem . Properties ( host ) if err != nil { return false , fmt . Errorf ( " " , host . Name ( ) , err ) } if hprops . Parent == nil { return false , nil } if * hprops . Parent != cluster . Reference ( ) { return false , nil } return true , nil }

// IsMember checks to see if a host is a member of the compute cluster
// in question.
//
// This is a pretty basic operation that checks that the parent of the
// compute is the ClusterComputeResource.

IsMember checks to see if a host is a member of the compute cluster in question . This is a pretty basic operation that checks that the parent of the compute is the ClusterComputeResource .


func MoveHostsInto(cluster *object.ClusterComputeResource, hosts []*object.HostSystem) error {
	var hsNames []string
	var hsRefs []types.ManagedObjectReference
	for _, hs := range hosts {
		hsNames = append(hsNames, hs.Name())
		hsRefs = append(hsRefs, hs.Reference())
	}
	log.Printf("[DEBUG] Adding hosts into cluster %q: %s", cluster.Name(), strings.Join(hsNames, ", "))

	req := types.MoveInto_Task{
		This: cluster.Reference(),
		Host: hsRefs,
	}

	ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
	defer cancel()
	resp, err := methods.MoveInto_Task(ctx, cluster.Client(), &req)
	if err != nil {
		return err
	}

	task := object.NewTask(cluster.Client(), resp.Returnval)
	return task.Wait(ctx)
}

func MoveHostsInto ( cluster * object . ClusterComputeResource , hosts [ ] * object . HostSystem ) error { var hsNames [ ] string var hsRefs [ ] types . ManagedObjectReference for _ , hs := range hosts { hsNames = append ( hsNames , hs . Name ( ) ) hsRefs = append ( hsRefs , hs . Reference ( ) ) } log . Printf ( " " , cluster . Name ( ) , strings . Join ( hsNames , " " ) ) req := types . MoveInto_Task { This : cluster . Reference ( ) , Host : hsRefs , } ctx , cancel := context . WithTimeout ( context . Background ( ) , provider . DefaultAPITimeout ) defer cancel ( ) resp , err := methods . MoveInto_Task ( ctx , cluster . Client ( ) , & req ) if err != nil { return err } task := object . NewTask ( cluster . Client ( ) , resp . Returnval ) return task . Wait ( ctx ) }

// MoveHostsInto moves all of the supplied hosts into the cluster. All virtual
// machines are moved to the cluster's root resource pool and any resource
// pools on the host itself are deleted.

MoveHostsInto moves all of the supplied hosts into the cluster . All virtual machines are moved to the cluster s root resource pool and any resource pools on the host itself are deleted .


func MoveHostsOutOf(cluster *object.ClusterComputeResource, hosts []*object.HostSystem, timeout int) error {
	for _, host := range hosts {
		if err := moveHostOutOf(cluster, host, timeout); err != nil {
			return err
		}
	}
	return nil
}

func MoveHostsOutOf ( cluster * object . ClusterComputeResource , hosts [ ] * object . HostSystem , timeout int ) error { for _ , host := range hosts { if err := moveHostOutOf ( cluster , host , timeout ) ; err != nil { return err } } return nil }

// MoveHostsOutOf moves a supplied list of hosts out of the specified cluster.
// The host is moved to the root host folder for the datacenter that the
// cluster is in.
//
// The host is placed into maintenance mode with evacuate flagged on, ensuring
// that as many VMs as possible are moved out of the host before removing it
// from the cluster. The effectiveness of this operation is dictated by the
// cluster's DRS settings, which also affects if this means that the task will
// block and require manual intervention. The supplied timeout is passed to the
// maintenance mode operations, and represents the timeout in seconds.
//
// Individual hosts are taken out of maintenance mode after its operation is
// complete.

MoveHostsOutOf moves a supplied list of hosts out of the specified cluster . The host is moved to the root host folder for the datacenter that the cluster is in . The host is placed into maintenance mode with evacuate flagged on ensuring that as many VMs as possible are moved out of the host before removing it from the cluster . The effectiveness of this operation is dictated by the cluster s DRS settings which also affects if this means that the task will block and require manual intervention . The supplied timeout is passed to the maintenance mode operations and represents the timeout in seconds . Individual hosts are taken out of maintenance mode after its operation is complete .


func expandVmwareDistributedVirtualSwitchVlanIDSpec(d *schema.ResourceData) *types.VmwareDistributedVirtualSwitchVlanIdSpec {
	obj := &types.VmwareDistributedVirtualSwitchVlanIdSpec{
		VlanId: int32(d.Get("vlan_id").(int)),
	}
	return obj
}

// expandVmwareDistributedVirtualSwitchVlanIDSpec reads certain ResourceData keys and
// returns a VmwareDistributedVirtualSwitchVlanIdSpec.


func flattenVmwareDistributedVirtualSwitchVlanIDSpec(d *schema.ResourceData, obj *types.VmwareDistributedVirtualSwitchVlanIdSpec) error {
	d.Set("vlan_id", obj.VlanId)
	return nil
}

// flattenVmwareDistributedVirtualSwitchVlanIDSpec reads various fields from a
// VmwareDistributedVirtualSwitchVlanIdSpec into the passed in ResourceData.