func expandVAppConfig(d *schema.ResourceData, client *govmomi.Client) (*types.VmConfigSpec, error) {
	if !d.HasChange("vapp") {
		return nil, nil
	}

	// Many vApp config values, such as IP address, will require a
	// restart of the machine to properly apply. We don't necessarily
	// know which ones they are, so we will restart for every change.
	d.Set("reboot_required", true)

	var props []types.VAppPropertySpec

	_, new := d.GetChange("vapp")
	newMap := make(map[string]interface{})

	newVApps := new.([]interface{})
	if newVApps != nil && len(newVApps) > 0 && newVApps[0] != nil {
		newVApp := newVApps[0].(map[string]interface{})
		if props, ok := newVApp["properties"].(map[string]interface{}); ok {
			newMap = props
		}
	}

	uuid := d.Id()
	if uuid == "" {
		// No virtual machine has been created, this usually means that this is a
		// brand new virtual machine. vApp properties are not supported on this
		// workflow, so if there are any defined, return an error indicating such.
		// Return with a no-op otherwise.
		if len(newMap) > 0 {
			return nil, fmt.Errorf("vApp properties can only be set on cloned virtual machines")
		}
		return nil, nil
	}
	vm, _ := virtualmachine.FromUUID(client, d.Id())
	vmProps, _ := virtualmachine.Properties(vm)
	if vmProps.Config.VAppConfig == nil {
		return nil, fmt.Errorf("this VM lacks a vApp configuration and cannot have vApp properties set on it")
	}
	allProperties := vmProps.Config.VAppConfig.GetVmConfigInfo().Property

	for _, p := range allProperties {
		defaultValue := " "
		if p.DefaultValue != "" {
			defaultValue = p.DefaultValue
		}
		prop := types.VAppPropertySpec{
			ArrayUpdateSpec: types.ArrayUpdateSpec{
				Operation: types.ArrayUpdateOperationEdit,
			},
			Info: &types.VAppPropertyInfo{
				Key:   p.Key,
				Id:    p.Id,
				Value: defaultValue,
			},
		}

		newValue, ok := newMap[p.Id]
		if ok {
			prop.Info.Value = newValue.(string)
			delete(newMap, p.Id)
		}
		props = append(props, prop)
	}

	if len(newMap) > 0 {
		return nil, fmt.Errorf("unsupported vApp properties in vapp.properties: %+v", reflect.ValueOf(newMap).MapKeys())
	}

	return &types.VmConfigSpec{
		Property: props,
	}, nil
}
func expandVAppConfig(d *schema.ResourceData, client *govmomi.Client) (*types.VmConfigSpec, error) {
	if !d.HasChange("vapp") {
		return nil, nil
	}

	
	
	
	d.Set("reboot_required", true)

	var props []types.VAppPropertySpec

	_, new := d.GetChange("vapp")
	newMap := make(map[string]interface{})

	newVApps := new.([]interface{})
	if newVApps != nil && len(newVApps) > 0 && newVApps[0] != nil {
		newVApp := newVApps[0].(map[string]interface{})
		if props, ok := newVApp["properties"].(map[string]interface{}); ok {
			newMap = props
		}
	}

	uuid := d.Id()
	if uuid == "" {
		
		
		
		
		if len(newMap) > 0 {
			return nil, fmt.Errorf("vApp properties can only be set on cloned virtual machines")
		}
		return nil, nil
	}
	vm, _ := virtualmachine.FromUUID(client, d.Id())
	vmProps, _ := virtualmachine.Properties(vm)
	if vmProps.Config.VAppConfig == nil {
		return nil, fmt.Errorf("this VM lacks a vApp configuration and cannot have vApp properties set on it")
	}
	allProperties := vmProps.Config.VAppConfig.GetVmConfigInfo().Property

	for _, p := range allProperties {
		defaultValue := " "
		if p.DefaultValue != "" {
			defaultValue = p.DefaultValue
		}
		prop := types.VAppPropertySpec{
			ArrayUpdateSpec: types.ArrayUpdateSpec{
				Operation: types.ArrayUpdateOperationEdit,
			},
			Info: &types.VAppPropertyInfo{
				Key:   p.Key,
				Id:    p.Id,
				Value: defaultValue,
			},
		}

		newValue, ok := newMap[p.Id]
		if ok {
			prop.Info.Value = newValue.(string)
			delete(newMap, p.Id)
		}
		props = append(props, prop)
	}

	if len(newMap) > 0 {
		return nil, fmt.Errorf("unsupported vApp properties in vapp.properties: %+v", reflect.ValueOf(newMap).MapKeys())
	}

	return &types.VmConfigSpec{
		Property: props,
	}, nil
}
func expandVAppConfig ( d * schema . ResourceData , client * govmomi . Client ) ( * types . VmConfigSpec , error ) { if ! d . HasChange ( " " ) { return nil , nil } // Many vApp config values, such as IP address, will require a // restart of the machine to properly apply. We don't necessarily // know which ones they are, so we will restart for every change. d . Set ( " " , true ) var props [ ] types . VAppPropertySpec _ , new := d . GetChange ( " " ) newMap := make ( map [ string ] interface { } ) newVApps := new . ( [ ] interface { } ) if newVApps != nil && len ( newVApps ) > 0 && newVApps [ 0 ] != nil { newVApp := newVApps [ 0 ] . ( map [ string ] interface { } ) if props , ok := newVApp [ " " ] . ( map [ string ] interface { } ) ; ok { newMap = props } } uuid := d . Id ( ) if uuid == " " { // No virtual machine has been created, this usually means that this is a // brand new virtual machine. vApp properties are not supported on this // workflow, so if there are any defined, return an error indicating such. // Return with a no-op otherwise. if len ( newMap ) > 0 { return nil , fmt . Errorf ( " " ) } return nil , nil } vm , _ := virtualmachine . FromUUID ( client , d . Id ( ) ) vmProps , _ := virtualmachine . Properties ( vm ) if vmProps . Config . VAppConfig == nil { return nil , fmt . Errorf ( " " ) } allProperties := vmProps . Config . VAppConfig . GetVmConfigInfo ( ) . Property for _ , p := range allProperties { defaultValue := " " if p . DefaultValue != " " { defaultValue = p . DefaultValue } prop := types . VAppPropertySpec { ArrayUpdateSpec : types . ArrayUpdateSpec { Operation : types . ArrayUpdateOperationEdit , } , Info : & types . VAppPropertyInfo { Key : p . Key , Id : p . Id , Value : defaultValue , } , } newValue , ok := newMap [ p . Id ] if ok { prop . Info . Value = newValue . ( string ) delete ( newMap , p . Id ) } props = append ( props , prop ) } if len ( newMap ) > 0 { return nil , fmt . Errorf ( " " , reflect . ValueOf ( newMap ) . MapKeys ( ) ) } return & types . VmConfigSpec { Property : props , } , nil }
// expandVAppConfig reads in all the vapp key/value pairs and returns
// the appropriate VmConfigSpec.
//
// We track changes to keys to determine if any have been removed from
// configuration - if they have, we add them with an empty value to ensure
// they are removed from vAppConfig on the update.
expandVAppConfig reads in all the vapp key / value pairs and returns the appropriate VmConfigSpec . We track changes to keys to determine if any have been removed from configuration - if they have we add them with an empty value to ensure they are removed from vAppConfig on the update .