github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/provider/vmware/client.go (about)

     1  package vmware
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/juju/errors"
     7  	"github.com/vmware/govmomi"
     8  	"github.com/vmware/govmomi/find"
     9  	"github.com/vmware/govmomi/vim25/mo"
    10  
    11  	"github.com/juju/juju/instance"
    12  )
    13  
    14  const (
    15  	metadataKeyIsState = "juju-is-state"
    16  )
    17  
    18  type client struct {
    19  	connection   *govmomi.Client
    20  	datacenter   *govmomi.Datacenter
    21  	datastore    *govmomi.Datastore
    22  	resourcePool *govmomi.ResourcePool
    23  	finder       *find.Finder
    24  }
    25  
    26  func newClient(ecfg *environConfig) (*client, error) {
    27  	url, err := ecfg.url()
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  	connection, err := govmomi.NewClient(*url, true)
    32  	if err != nil {
    33  		return nil, errors.Trace(err)
    34  	}
    35  
    36  	finder := find.NewFinder(connection, true)
    37  	datacenter, err := finder.Datacenter(ecfg.datacenter())
    38  	if err != nil {
    39  		return nil, errors.Trace(err)
    40  	}
    41  	finder.SetDatacenter(datacenter)
    42  	datastore, err := finder.Datastore(ecfg.datastore())
    43  	if err != nil {
    44  		return nil, errors.Trace(err)
    45  	}
    46  	resourcePool, err := finder.ResourcePool(ecfg.resourcePool())
    47  	if err != nil {
    48  		return nil, errors.Trace(err)
    49  	}
    50  	return &client{
    51  		connection:   connection,
    52  		datacenter:   datacenter,
    53  		datastore:    datastore,
    54  		resourcePool: resourcePool,
    55  		finder:       finder,
    56  	}, nil
    57  }
    58  
    59  func (c *client) CreateInstance(machineID string, hwc *instance.HardwareCharacteristics, img *OvfFileMetadata, userData []byte, sshKey string, isState bool) (*mo.VirtualMachine, error) {
    60  
    61  	manager := &ovfImportManager{client: c}
    62  	vm, err := manager.importOvf(machineID, hwc, img, userData, sshKey, isState)
    63  	if err != nil {
    64  		return nil, errors.Annotatef(err, "Failed to import ovf file")
    65  	}
    66  	task, err := vm.PowerOn()
    67  	if err != nil {
    68  		return nil, errors.Trace(err)
    69  	}
    70  	taskInfo, err := task.WaitForResult(nil)
    71  	if err != nil {
    72  		return nil, errors.Trace(err)
    73  	}
    74  	var res mo.VirtualMachine
    75  	err = c.connection.Properties(*taskInfo.Entity, nil, &res)
    76  	if err != nil {
    77  		return nil, errors.Trace(err)
    78  	}
    79  	return &res, nil
    80  }
    81  
    82  func (c *client) RemoveInstances(ids ...string) error {
    83  	var firstError error
    84  	tasks := make([]*govmomi.Task, len(ids))
    85  	for _, id := range ids {
    86  		vm, err := c.finder.VirtualMachine(id)
    87  		if err != nil && firstError == nil {
    88  			firstError = err
    89  			continue
    90  		}
    91  		task, err := vm.Destroy()
    92  		if err != nil && firstError == nil {
    93  			firstError = err
    94  			continue
    95  		}
    96  		//We don't wait for task completeon here. Instead we want to run all tasks as soon as posible
    97  		//and then wait for them all. such aproach will run all tasks in parallel
    98  		tasks = append(tasks, task)
    99  	}
   100  
   101  	for _, task := range tasks {
   102  		_, err := task.WaitForResult(nil)
   103  		if err != nil && firstError == nil {
   104  			firstError = err
   105  			continue
   106  		}
   107  	}
   108  	return errors.Annotatef(firstError, "Failed while remowing instances")
   109  }
   110  
   111  func (c *client) Instances(prefix string) ([]*mo.VirtualMachine, error) {
   112  	items, err := c.finder.VirtualMachineList("*")
   113  	if err != nil {
   114  		return nil, errors.Trace(err)
   115  	}
   116  
   117  	var vms []*mo.VirtualMachine
   118  	vms = make([]*mo.VirtualMachine, len(vms))
   119  	for _, item := range items {
   120  		var vm mo.VirtualMachine
   121  		err = c.connection.Properties(item.Reference(), nil, &vm)
   122  		if err != nil {
   123  			return nil, errors.Trace(err)
   124  		}
   125  		if vm.Config != nil && strings.HasPrefix(vm.Config.Name, prefix) {
   126  			vms = append(vms, &vm)
   127  		}
   128  	}
   129  
   130  	return vms, nil
   131  }
   132  
   133  func (c *client) Refresh(v *mo.VirtualMachine) error {
   134  	item, err := c.finder.VirtualMachine(v.Config.Name)
   135  	if err != nil {
   136  		return errors.Trace(err)
   137  	}
   138  	var vm mo.VirtualMachine
   139  	err = c.connection.Properties(item.Reference(), nil, &vm)
   140  	if err != nil {
   141  		return errors.Trace(err)
   142  	}
   143  	*v = vm
   144  	return nil
   145  }