github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/instancepoller/instancepoller.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package instancepoller 5 6 import ( 7 "fmt" 8 9 "github.com/juju/loggo" 10 "github.com/juju/names" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/state" 15 ) 16 17 func init() { 18 common.RegisterStandardFacade("InstancePoller", 1, NewInstancePollerAPI) 19 } 20 21 var logger = loggo.GetLogger("juju.apiserver.instancepoller") 22 23 // InstancePollerAPI provides access to the InstancePoller API facade. 24 type InstancePollerAPI struct { 25 *common.LifeGetter 26 *common.EnvironWatcher 27 *common.EnvironMachinesWatcher 28 *common.InstanceIdGetter 29 *common.StatusGetter 30 31 st StateInterface 32 resources *common.Resources 33 authorizer common.Authorizer 34 accessMachine common.GetAuthFunc 35 } 36 37 // NewInstancePollerAPI creates a new server-side InstancePoller API 38 // facade. 39 func NewInstancePollerAPI( 40 st *state.State, 41 resources *common.Resources, 42 authorizer common.Authorizer, 43 ) (*InstancePollerAPI, error) { 44 45 if !authorizer.AuthEnvironManager() { 46 // InstancePoller must run as environment manager. 47 return nil, common.ErrPerm 48 } 49 accessMachine := common.AuthFuncForTagKind(names.MachineTagKind) 50 sti := getState(st) 51 52 // Life() is supported for machines. 53 lifeGetter := common.NewLifeGetter( 54 sti, 55 accessMachine, 56 ) 57 // EnvironConfig() and WatchForEnvironConfigChanges() are allowed 58 // with unrestriced access. 59 environWatcher := common.NewEnvironWatcher( 60 sti, 61 resources, 62 authorizer, 63 ) 64 // WatchEnvironMachines() is allowed with unrestricted access. 65 machinesWatcher := common.NewEnvironMachinesWatcher( 66 sti, 67 resources, 68 authorizer, 69 ) 70 // InstanceId() is supported for machines. 71 instanceIdGetter := common.NewInstanceIdGetter( 72 sti, 73 accessMachine, 74 ) 75 // Status() is supported for machines. 76 statusGetter := common.NewStatusGetter( 77 sti, 78 accessMachine, 79 ) 80 81 return &InstancePollerAPI{ 82 LifeGetter: lifeGetter, 83 EnvironWatcher: environWatcher, 84 EnvironMachinesWatcher: machinesWatcher, 85 InstanceIdGetter: instanceIdGetter, 86 StatusGetter: statusGetter, 87 st: sti, 88 resources: resources, 89 authorizer: authorizer, 90 accessMachine: accessMachine, 91 }, nil 92 } 93 94 func (a *InstancePollerAPI) getOneMachine(tag string, canAccess common.AuthFunc) (StateMachine, error) { 95 machineTag, err := names.ParseMachineTag(tag) 96 if err != nil { 97 return nil, err 98 } 99 if !canAccess(machineTag) { 100 return nil, common.ErrPerm 101 } 102 entity, err := a.st.FindEntity(machineTag) 103 if err != nil { 104 return nil, err 105 } 106 machine, ok := entity.(StateMachine) 107 if !ok { 108 return nil, common.NotSupportedError( 109 machineTag, fmt.Sprintf("expected machine, got %T", entity), 110 ) 111 } 112 return machine, nil 113 } 114 115 // ProviderAddresses returns the list of all known provider addresses 116 // for each given entity. Only machine tags are accepted. 117 func (a *InstancePollerAPI) ProviderAddresses(args params.Entities) (params.MachineAddressesResults, error) { 118 result := params.MachineAddressesResults{ 119 Results: make([]params.MachineAddressesResult, len(args.Entities)), 120 } 121 canAccess, err := a.accessMachine() 122 if err != nil { 123 return result, err 124 } 125 for i, arg := range args.Entities { 126 machine, err := a.getOneMachine(arg.Tag, canAccess) 127 if err == nil { 128 addrs := machine.ProviderAddresses() 129 result.Results[i].Addresses = params.FromNetworkAddresses(addrs) 130 } 131 result.Results[i].Error = common.ServerError(err) 132 } 133 return result, nil 134 } 135 136 // SetProviderAddresses updates the list of known provider addresses 137 // for each given entity. Only machine tags are accepted. 138 func (a *InstancePollerAPI) SetProviderAddresses(args params.SetMachinesAddresses) (params.ErrorResults, error) { 139 result := params.ErrorResults{ 140 Results: make([]params.ErrorResult, len(args.MachineAddresses)), 141 } 142 canAccess, err := a.accessMachine() 143 if err != nil { 144 return result, err 145 } 146 for i, arg := range args.MachineAddresses { 147 machine, err := a.getOneMachine(arg.Tag, canAccess) 148 if err == nil { 149 addrsToSet := params.NetworkAddresses(arg.Addresses) 150 err = machine.SetProviderAddresses(addrsToSet...) 151 } 152 result.Results[i].Error = common.ServerError(err) 153 } 154 return result, nil 155 } 156 157 // InstanceStatus returns the instance status for each given entity. 158 // Only machine tags are accepted. 159 func (a *InstancePollerAPI) InstanceStatus(args params.Entities) (params.StringResults, error) { 160 result := params.StringResults{ 161 Results: make([]params.StringResult, len(args.Entities)), 162 } 163 canAccess, err := a.accessMachine() 164 if err != nil { 165 return result, err 166 } 167 for i, arg := range args.Entities { 168 machine, err := a.getOneMachine(arg.Tag, canAccess) 169 if err == nil { 170 result.Results[i].Result, err = machine.InstanceStatus() 171 } 172 result.Results[i].Error = common.ServerError(err) 173 } 174 return result, nil 175 } 176 177 // SetInstanceStatus updates the instance status for each given 178 // entity. Only machine tags are accepted. 179 func (a *InstancePollerAPI) SetInstanceStatus(args params.SetInstancesStatus) (params.ErrorResults, error) { 180 result := params.ErrorResults{ 181 Results: make([]params.ErrorResult, len(args.Entities)), 182 } 183 canAccess, err := a.accessMachine() 184 if err != nil { 185 return result, err 186 } 187 for i, arg := range args.Entities { 188 machine, err := a.getOneMachine(arg.Tag, canAccess) 189 if err == nil { 190 err = machine.SetInstanceStatus(arg.Status) 191 } 192 result.Results[i].Error = common.ServerError(err) 193 } 194 return result, nil 195 } 196 197 // AreManuallyProvisioned returns whether each given entity is 198 // manually provisioned or not. Only machine tags are accepted. 199 func (a *InstancePollerAPI) AreManuallyProvisioned(args params.Entities) (params.BoolResults, error) { 200 result := params.BoolResults{ 201 Results: make([]params.BoolResult, len(args.Entities)), 202 } 203 canAccess, err := a.accessMachine() 204 if err != nil { 205 return result, err 206 } 207 for i, arg := range args.Entities { 208 machine, err := a.getOneMachine(arg.Tag, canAccess) 209 if err == nil { 210 result.Results[i].Result, err = machine.IsManual() 211 } 212 result.Results[i].Error = common.ServerError(err) 213 } 214 return result, nil 215 }