github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/machineundertaker/undertaker.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package machineundertaker
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  
    10  	"github.com/juju/juju/api/base"
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/network"
    13  	"github.com/juju/juju/watcher"
    14  )
    15  
    16  // NewWatcherFunc exists to let us test WatchMachineRemovals.
    17  type NewWatcherFunc func(base.APICaller, params.NotifyWatchResult) watcher.NotifyWatcher
    18  
    19  // API provides access to the machine undertaker API facade.
    20  type API struct {
    21  	facade     base.FacadeCaller
    22  	modelTag   names.ModelTag
    23  	newWatcher NewWatcherFunc
    24  }
    25  
    26  // NewAPI creates a new client-side machine undertaker facade.
    27  func NewAPI(caller base.APICaller, newWatcher NewWatcherFunc) (*API, error) {
    28  	modelTag, ok := caller.ModelTag()
    29  	if !ok {
    30  		return nil, errors.New("machine undertaker client requires a model API connection")
    31  	}
    32  	api := API{
    33  		facade:     base.NewFacadeCaller(caller, "MachineUndertaker"),
    34  		modelTag:   modelTag,
    35  		newWatcher: newWatcher,
    36  	}
    37  	return &api, nil
    38  }
    39  
    40  // AllMachineRemovals returns all the machines that have been marked
    41  // ready to clean up.
    42  func (api *API) AllMachineRemovals() ([]names.MachineTag, error) {
    43  	var results params.EntitiesResults
    44  	args := wrapEntities(api.modelTag)
    45  	err := api.facade.FacadeCall("AllMachineRemovals", &args, &results)
    46  	if err != nil {
    47  		return nil, errors.Trace(err)
    48  	}
    49  	if len(results.Results) != 1 {
    50  		return nil, errors.Errorf("expected one result, got %d", len(results.Results))
    51  	}
    52  	result := results.Results[0]
    53  	if result.Error != nil {
    54  		return nil, errors.Trace(result.Error)
    55  	}
    56  	machines := make([]names.MachineTag, len(result.Entities))
    57  	for i, entity := range result.Entities {
    58  		tag, err := names.ParseMachineTag(entity.Tag)
    59  		if err != nil {
    60  			return nil, errors.Trace(err)
    61  		}
    62  		machines[i] = tag
    63  	}
    64  	return machines, nil
    65  }
    66  
    67  // GetProviderInterfaceInfo gets the provider details for all of the
    68  // interfaces for one machine.
    69  func (api *API) GetProviderInterfaceInfo(machine names.MachineTag) ([]network.ProviderInterfaceInfo, error) {
    70  	var result params.ProviderInterfaceInfoResults
    71  	args := wrapEntities(machine)
    72  	err := api.facade.FacadeCall("GetMachineProviderInterfaceInfo", &args, &result)
    73  	if err != nil {
    74  		return nil, errors.Trace(err)
    75  	}
    76  	if len(result.Results) != 1 {
    77  		return nil, errors.Errorf("expected one result, got %d", len(result.Results))
    78  	}
    79  	item := result.Results[0]
    80  	if item.MachineTag != machine.String() {
    81  		return nil, errors.Errorf("expected interface info for %s but got %s", machine, item.MachineTag)
    82  	}
    83  	infos := make([]network.ProviderInterfaceInfo, len(item.Interfaces))
    84  	for i, info := range item.Interfaces {
    85  		infos[i].InterfaceName = info.InterfaceName
    86  		infos[i].MACAddress = info.MACAddress
    87  		infos[i].ProviderId = network.Id(info.ProviderId)
    88  	}
    89  	return infos, nil
    90  }
    91  
    92  // CompleteRemoval finishes the removal of the machine in the database
    93  // after any provider resources are cleaned up.
    94  func (api *API) CompleteRemoval(machine names.MachineTag) error {
    95  	args := wrapEntities(machine)
    96  	return api.facade.FacadeCall("CompleteMachineRemovals", &args, nil)
    97  }
    98  
    99  // WatchMachineRemovals registers to be notified when a machine
   100  // removal is requested.
   101  func (api *API) WatchMachineRemovals() (watcher.NotifyWatcher, error) {
   102  	var results params.NotifyWatchResults
   103  	args := wrapEntities(api.modelTag)
   104  	err := api.facade.FacadeCall("WatchMachineRemovals", &args, &results)
   105  	if err != nil {
   106  		return nil, errors.Trace(err)
   107  	}
   108  	if len(results.Results) != 1 {
   109  		return nil, errors.Errorf("expected one result, got %d", len(results.Results))
   110  	}
   111  	result := results.Results[0]
   112  	if err := result.Error; err != nil {
   113  		return nil, errors.Trace(result.Error)
   114  	}
   115  	w := api.newWatcher(api.facade.RawAPICaller(), result)
   116  	return w, nil
   117  }
   118  
   119  func wrapEntities(tag names.Tag) params.Entities {
   120  	return params.Entities{Entities: []params.Entity{{Tag: tag.String()}}}
   121  }