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 }