LEFT | RIGHT |
1 // Copyright 2012, 2013 Canonical Ltd. | 1 // Copyright 2012, 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package provisioner | 4 package provisioner |
5 | 5 |
6 import ( | 6 import ( |
7 "launchpad.net/juju-core/constraints" | 7 "launchpad.net/juju-core/constraints" |
8 "launchpad.net/juju-core/instance" | 8 "launchpad.net/juju-core/instance" |
9 "launchpad.net/juju-core/names" | 9 "launchpad.net/juju-core/names" |
10 "launchpad.net/juju-core/state" | 10 "launchpad.net/juju-core/state" |
(...skipping 10 matching lines...) Expand all Loading... |
21 *common.DeadEnsurer | 21 *common.DeadEnsurer |
22 *common.PasswordChanger | 22 *common.PasswordChanger |
23 *common.LifeGetter | 23 *common.LifeGetter |
24 *common.StateAddresser | 24 *common.StateAddresser |
25 *common.APIAddresser | 25 *common.APIAddresser |
26 *common.ToolsGetter | 26 *common.ToolsGetter |
27 *common.EnvironWatcher | 27 *common.EnvironWatcher |
28 *common.EnvironMachinesWatcher | 28 *common.EnvironMachinesWatcher |
29 *common.InstanceIdGetter | 29 *common.InstanceIdGetter |
30 | 30 |
31 » st *state.State | 31 » st *state.State |
32 » resources *common.Resources | 32 » resources *common.Resources |
33 » authorizer common.Authorizer | 33 » authorizer common.Authorizer |
34 » getAuthFunc common.GetAuthFunc | 34 » getAuthFunc common.GetAuthFunc |
| 35 » getCanWatchMachines common.GetAuthFunc |
35 } | 36 } |
36 | 37 |
37 // NewProvisionerAPI creates a new server-side ProvisionerAPI facade. | 38 // NewProvisionerAPI creates a new server-side ProvisionerAPI facade. |
38 func NewProvisionerAPI( | 39 func NewProvisionerAPI( |
39 st *state.State, | 40 st *state.State, |
40 resources *common.Resources, | 41 resources *common.Resources, |
41 authorizer common.Authorizer, | 42 authorizer common.Authorizer, |
42 ) (*ProvisionerAPI, error) { | 43 ) (*ProvisionerAPI, error) { |
43 if !authorizer.AuthMachineAgent() && !authorizer.AuthEnvironManager() { | 44 if !authorizer.AuthMachineAgent() && !authorizer.AuthEnvironManager() { |
44 return nil, common.ErrPerm | 45 return nil, common.ErrPerm |
(...skipping 27 matching lines...) Expand all Loading... |
72 getCanWatch := common.AuthAlways(true) | 73 getCanWatch := common.AuthAlways(true) |
73 // Only the environment provisioner can read secrets. | 74 // Only the environment provisioner can read secrets. |
74 getCanReadSecrets := common.AuthAlways(authorizer.AuthEnvironManager()) | 75 getCanReadSecrets := common.AuthAlways(authorizer.AuthEnvironManager()) |
75 return &ProvisionerAPI{ | 76 return &ProvisionerAPI{ |
76 Remover: common.NewRemover(st, false, getAuthFunc
), | 77 Remover: common.NewRemover(st, false, getAuthFunc
), |
77 StatusSetter: common.NewStatusSetter(st, getAuthFunc), | 78 StatusSetter: common.NewStatusSetter(st, getAuthFunc), |
78 DeadEnsurer: common.NewDeadEnsurer(st, getAuthFunc), | 79 DeadEnsurer: common.NewDeadEnsurer(st, getAuthFunc), |
79 PasswordChanger: common.NewPasswordChanger(st, getAuthFun
c), | 80 PasswordChanger: common.NewPasswordChanger(st, getAuthFun
c), |
80 LifeGetter: common.NewLifeGetter(st, getAuthFunc), | 81 LifeGetter: common.NewLifeGetter(st, getAuthFunc), |
81 StateAddresser: common.NewStateAddresser(st), | 82 StateAddresser: common.NewStateAddresser(st), |
82 » » APIAddresser: common.NewAPIAddresser(st), | 83 » » APIAddresser: common.NewAPIAddresser(st, resources), |
83 ToolsGetter: common.NewToolsGetter(st, getAuthFunc), | 84 ToolsGetter: common.NewToolsGetter(st, getAuthFunc), |
84 EnvironWatcher: common.NewEnvironWatcher(st, resources,
getCanWatch, getCanReadSecrets), | 85 EnvironWatcher: common.NewEnvironWatcher(st, resources,
getCanWatch, getCanReadSecrets), |
85 EnvironMachinesWatcher: common.NewEnvironMachinesWatcher(st, res
ources, getCanReadSecrets), | 86 EnvironMachinesWatcher: common.NewEnvironMachinesWatcher(st, res
ources, getCanReadSecrets), |
86 InstanceIdGetter: common.NewInstanceIdGetter(st, getAuthFu
nc), | 87 InstanceIdGetter: common.NewInstanceIdGetter(st, getAuthFu
nc), |
87 st: st, | 88 st: st, |
88 resources: resources, | 89 resources: resources, |
89 authorizer: authorizer, | 90 authorizer: authorizer, |
90 getAuthFunc: getAuthFunc, | 91 getAuthFunc: getAuthFunc, |
| 92 getCanWatchMachines: getCanReadSecrets, |
91 }, nil | 93 }, nil |
92 } | 94 } |
93 | 95 |
94 func (p *ProvisionerAPI) getMachine(canAccess common.AuthFunc, tag string) (*sta
te.Machine, error) { | 96 func (p *ProvisionerAPI) getMachine(canAccess common.AuthFunc, tag string) (*sta
te.Machine, error) { |
95 if !canAccess(tag) { | 97 if !canAccess(tag) { |
96 return nil, common.ErrPerm | 98 return nil, common.ErrPerm |
97 } | 99 } |
98 entity, err := p.st.FindEntity(tag) | 100 entity, err := p.st.FindEntity(tag) |
99 if err != nil { | 101 if err != nil { |
100 return nil, err | 102 return nil, err |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 Results: make([]params.StatusResult, len(args.Entities)), | 210 Results: make([]params.StatusResult, len(args.Entities)), |
209 } | 211 } |
210 canAccess, err := p.getAuthFunc() | 212 canAccess, err := p.getAuthFunc() |
211 if err != nil { | 213 if err != nil { |
212 return result, err | 214 return result, err |
213 } | 215 } |
214 for i, entity := range args.Entities { | 216 for i, entity := range args.Entities { |
215 machine, err := p.getMachine(canAccess, entity.Tag) | 217 machine, err := p.getMachine(canAccess, entity.Tag) |
216 if err == nil { | 218 if err == nil { |
217 r := &result.Results[i] | 219 r := &result.Results[i] |
218 » » » r.Status, r.Info, _, err = machine.Status() | 220 » » » r.Status, r.Info, r.Data, err = machine.Status() |
219 » » } | 221 » » } |
220 » » result.Results[i].Error = common.ServerError(err) | 222 » » result.Results[i].Error = common.ServerError(err) |
221 » } | 223 » } |
222 » return result, nil | 224 » return result, nil |
| 225 } |
| 226 |
| 227 // MachinesWithTransientErrors returns status data for machines with provisionin
g |
| 228 // errors which are transient. |
| 229 func (p *ProvisionerAPI) MachinesWithTransientErrors() (params.StatusResults, er
ror) { |
| 230 » results := params.StatusResults{} |
| 231 » canAccessFunc, err := p.getAuthFunc() |
| 232 » if err != nil { |
| 233 » » return results, err |
| 234 » } |
| 235 » // TODO (wallyworld) - add state.State API for more efficient machines q
uery |
| 236 » machines, err := p.st.AllMachines() |
| 237 » if err != nil { |
| 238 » » return results, err |
| 239 » } |
| 240 » for _, machine := range machines { |
| 241 » » if !canAccessFunc(machine.Tag()) { |
| 242 » » » continue |
| 243 » » } |
| 244 » » if _, provisionedErr := machine.InstanceId(); provisionedErr ==
nil { |
| 245 » » » // Machine may have been provisioned but machiner hasn't
set the |
| 246 » » » // status to Started yet. |
| 247 » » » continue |
| 248 » » } |
| 249 » » result := params.StatusResult{} |
| 250 » » if result.Status, result.Info, result.Data, err = machine.Status
(); err != nil { |
| 251 » » » continue |
| 252 » » } |
| 253 » » if result.Status != params.StatusError { |
| 254 » » » continue |
| 255 » » } |
| 256 » » // Transient errors are marked as such in the status data. |
| 257 » » if transient, ok := result.Data["transient"].(bool); !ok || !tra
nsient { |
| 258 » » » continue |
| 259 » » } |
| 260 » » result.Id = machine.Id() |
| 261 » » result.Life = params.Life(machine.Life().String()) |
| 262 » » results.Results = append(results.Results, result) |
| 263 » } |
| 264 » return results, nil |
223 } | 265 } |
224 | 266 |
225 // Series returns the deployed series for each given machine entity. | 267 // Series returns the deployed series for each given machine entity. |
226 func (p *ProvisionerAPI) Series(args params.Entities) (params.StringResults, err
or) { | 268 func (p *ProvisionerAPI) Series(args params.Entities) (params.StringResults, err
or) { |
227 result := params.StringResults{ | 269 result := params.StringResults{ |
228 Results: make([]params.StringResult, len(args.Entities)), | 270 Results: make([]params.StringResult, len(args.Entities)), |
229 } | 271 } |
230 canAccess, err := p.getAuthFunc() | 272 canAccess, err := p.getAuthFunc() |
231 if err != nil { | 273 if err != nil { |
232 return result, err | 274 return result, err |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 cons, err = machine.Constraints() | 400 cons, err = machine.Constraints() |
359 if err == nil { | 401 if err == nil { |
360 result.Results[i].Constraints = cons | 402 result.Results[i].Constraints = cons |
361 } | 403 } |
362 } | 404 } |
363 result.Results[i].Error = common.ServerError(err) | 405 result.Results[i].Error = common.ServerError(err) |
364 } | 406 } |
365 return result, nil | 407 return result, nil |
366 } | 408 } |
367 | 409 |
| 410 // Networks returns the networks for each given machine entity. |
| 411 func (p *ProvisionerAPI) Networks(args params.Entities) (params.NetworksResults,
error) { |
| 412 result := params.NetworksResults{ |
| 413 Results: make([]params.NetworkResult, len(args.Entities)), |
| 414 } |
| 415 canAccess, err := p.getAuthFunc() |
| 416 if err != nil { |
| 417 return result, err |
| 418 } |
| 419 for i, entity := range args.Entities { |
| 420 machine, err := p.getMachine(canAccess, entity.Tag) |
| 421 if err == nil { |
| 422 var includeNetworks []string |
| 423 var excludeNetworks []string |
| 424 includeNetworks, excludeNetworks, err = machine.Networks
() |
| 425 if err == nil { |
| 426 result.Results[i].IncludeNetworks = includeNetwo
rks |
| 427 result.Results[i].ExcludeNetworks = excludeNetwo
rks |
| 428 } |
| 429 } |
| 430 result.Results[i].Error = common.ServerError(err) |
| 431 } |
| 432 return result, nil |
| 433 } |
| 434 |
368 // SetProvisioned sets the provider specific machine id, nonce and | 435 // SetProvisioned sets the provider specific machine id, nonce and |
369 // metadata for each given machine. Once set, the instance id cannot | 436 // metadata for each given machine. Once set, the instance id cannot |
370 // be changed. | 437 // be changed. |
371 func (p *ProvisionerAPI) SetProvisioned(args params.SetProvisioned) (params.Erro
rResults, error) { | 438 func (p *ProvisionerAPI) SetProvisioned(args params.SetProvisioned) (params.Erro
rResults, error) { |
372 result := params.ErrorResults{ | 439 result := params.ErrorResults{ |
373 Results: make([]params.ErrorResult, len(args.Machines)), | 440 Results: make([]params.ErrorResult, len(args.Machines)), |
374 } | 441 } |
375 canAccess, err := p.getAuthFunc() | 442 canAccess, err := p.getAuthFunc() |
376 if err != nil { | 443 if err != nil { |
377 return result, err | 444 return result, err |
378 } | 445 } |
379 for i, arg := range args.Machines { | 446 for i, arg := range args.Machines { |
380 machine, err := p.getMachine(canAccess, arg.Tag) | 447 machine, err := p.getMachine(canAccess, arg.Tag) |
381 if err == nil { | 448 if err == nil { |
382 err = machine.SetProvisioned(arg.InstanceId, arg.Nonce,
arg.Characteristics) | 449 err = machine.SetProvisioned(arg.InstanceId, arg.Nonce,
arg.Characteristics) |
383 } | 450 } |
384 result.Results[i].Error = common.ServerError(err) | 451 result.Results[i].Error = common.ServerError(err) |
385 } | 452 } |
386 return result, nil | 453 return result, nil |
387 } | 454 } |
| 455 |
| 456 // WatchMachineErrorRetry returns a NotifyWatcher that notifies when |
| 457 // the provisioner should retry provisioning machines with transient errors. |
| 458 func (p *ProvisionerAPI) WatchMachineErrorRetry() (params.NotifyWatchResult, err
or) { |
| 459 result := params.NotifyWatchResult{} |
| 460 canWatch, err := p.getCanWatchMachines() |
| 461 if err != nil { |
| 462 return params.NotifyWatchResult{}, err |
| 463 } |
| 464 if !canWatch("") { |
| 465 return result, common.ErrPerm |
| 466 } |
| 467 watch := newWatchMachineErrorRetry() |
| 468 // Consume any initial event and forward it to the result. |
| 469 if _, ok := <-watch.Changes(); ok { |
| 470 result.NotifyWatcherId = p.resources.Register(watch) |
| 471 } else { |
| 472 return result, watcher.MustErr(watch) |
| 473 } |
| 474 return result, nil |
| 475 } |
LEFT | RIGHT |