github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/machine/machiner.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // The machiner package implements the API interface 5 // used by the machiner worker. 6 package machine 7 8 import ( 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 "github.com/juju/names" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/state/multiwatcher" 17 ) 18 19 func init() { 20 common.RegisterStandardFacade("Machiner", 0, NewMachinerAPI) 21 } 22 23 var logger = loggo.GetLogger("juju.apiserver.machine") 24 25 // MachinerAPI implements the API used by the machiner worker. 26 type MachinerAPI struct { 27 *common.LifeGetter 28 *common.StatusSetter 29 *common.DeadEnsurer 30 *common.AgentEntityWatcher 31 *common.APIAddresser 32 33 st *state.State 34 auth common.Authorizer 35 getCanModify common.GetAuthFunc 36 getCanRead common.GetAuthFunc 37 } 38 39 // NewMachinerAPI creates a new instance of the Machiner API. 40 func NewMachinerAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*MachinerAPI, error) { 41 if !authorizer.AuthMachineAgent() { 42 return nil, common.ErrPerm 43 } 44 getCanModify := func() (common.AuthFunc, error) { 45 return authorizer.AuthOwner, nil 46 } 47 getCanRead := func() (common.AuthFunc, error) { 48 return authorizer.AuthOwner, nil 49 } 50 return &MachinerAPI{ 51 LifeGetter: common.NewLifeGetter(st, getCanRead), 52 StatusSetter: common.NewStatusSetter(st, getCanModify), 53 DeadEnsurer: common.NewDeadEnsurer(st, getCanModify), 54 AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, getCanRead), 55 APIAddresser: common.NewAPIAddresser(st, resources), 56 st: st, 57 auth: authorizer, 58 getCanModify: getCanModify, 59 getCanRead: getCanRead, 60 }, nil 61 } 62 63 func (api *MachinerAPI) getMachine(tag names.Tag) (*state.Machine, error) { 64 entity, err := api.st.FindEntity(tag) 65 if err != nil { 66 return nil, err 67 } 68 return entity.(*state.Machine), nil 69 } 70 71 func (api *MachinerAPI) SetMachineAddresses(args params.SetMachinesAddresses) (params.ErrorResults, error) { 72 results := params.ErrorResults{ 73 Results: make([]params.ErrorResult, len(args.MachineAddresses)), 74 } 75 canModify, err := api.getCanModify() 76 if err != nil { 77 return results, err 78 } 79 for i, arg := range args.MachineAddresses { 80 tag, err := names.ParseMachineTag(arg.Tag) 81 if err != nil { 82 results.Results[i].Error = common.ServerError(common.ErrPerm) 83 continue 84 } 85 err = common.ErrPerm 86 if canModify(tag) { 87 var m *state.Machine 88 m, err = api.getMachine(tag) 89 if err == nil { 90 addresses := params.NetworkAddresses(arg.Addresses) 91 err = m.SetMachineAddresses(addresses...) 92 } else if errors.IsNotFound(err) { 93 err = common.ErrPerm 94 } 95 } 96 results.Results[i].Error = common.ServerError(err) 97 } 98 return results, nil 99 } 100 101 // Jobs returns the jobs assigned to the given entities. 102 func (api *MachinerAPI) Jobs(args params.Entities) (params.JobsResults, error) { 103 result := params.JobsResults{ 104 Results: make([]params.JobsResult, len(args.Entities)), 105 } 106 107 canRead, err := api.getCanRead() 108 if err != nil { 109 return result, err 110 } 111 112 for i, agent := range args.Entities { 113 tag, err := names.ParseMachineTag(agent.Tag) 114 if err != nil { 115 result.Results[i].Error = common.ServerError(err) 116 continue 117 } 118 119 if !canRead(tag) { 120 result.Results[i].Error = common.ServerError(common.ErrPerm) 121 continue 122 } 123 124 machine, err := api.getMachine(tag) 125 if err != nil { 126 result.Results[i].Error = common.ServerError(err) 127 continue 128 } 129 machineJobs := machine.Jobs() 130 jobs := make([]multiwatcher.MachineJob, len(machineJobs)) 131 for i, job := range machineJobs { 132 jobs[i] = job.ToParams() 133 } 134 result.Results[i].Jobs = jobs 135 } 136 return result, nil 137 }