github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/apiserver/agent/agent.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // The machine package implements the API interfaces 5 // used by the machine agent. 6 package agent 7 8 import ( 9 "github.com/juju/juju/agent/mongo" 10 "github.com/juju/juju/state" 11 "github.com/juju/juju/state/api/params" 12 "github.com/juju/juju/state/apiserver/common" 13 ) 14 15 // API implements the API provided to an agent. 16 type API struct { 17 *common.PasswordChanger 18 19 st *state.State 20 auth common.Authorizer 21 } 22 23 // NewAPI returns an object implementing an agent API 24 // with the given authorizer representing the currently logged in client. 25 func NewAPI(st *state.State, auth common.Authorizer) (*API, error) { 26 // Agents are defined to be any user that's not a client user. 27 if !auth.AuthMachineAgent() && !auth.AuthUnitAgent() { 28 return nil, common.ErrPerm 29 } 30 getCanChange := func() (common.AuthFunc, error) { 31 return auth.AuthOwner, nil 32 } 33 return &API{ 34 PasswordChanger: common.NewPasswordChanger(st, getCanChange), 35 st: st, 36 auth: auth, 37 }, nil 38 } 39 40 func (api *API) GetEntities(args params.Entities) params.AgentGetEntitiesResults { 41 results := params.AgentGetEntitiesResults{ 42 Entities: make([]params.AgentGetEntitiesResult, len(args.Entities)), 43 } 44 for i, entity := range args.Entities { 45 result, err := api.getEntity(entity.Tag) 46 result.Error = common.ServerError(err) 47 results.Entities[i] = result 48 } 49 return results 50 } 51 52 func (api *API) getEntity(tag string) (result params.AgentGetEntitiesResult, err error) { 53 // Allow only for the owner agent. 54 // Note: having a bulk API call for this is utter madness, given that 55 // this check means we can only ever return a single object. 56 if !api.auth.AuthOwner(tag) { 57 err = common.ErrPerm 58 return 59 } 60 entity0, err := api.st.FindEntity(tag) 61 if err != nil { 62 return 63 } 64 entity, ok := entity0.(state.Lifer) 65 if !ok { 66 err = common.NotSupportedError(tag, "life cycles") 67 return 68 } 69 result.Life = params.Life(entity.Life().String()) 70 if machine, ok := entity.(*state.Machine); ok { 71 result.Jobs = stateJobsToAPIParamsJobs(machine.Jobs()) 72 result.ContainerType = machine.ContainerType() 73 } 74 return 75 } 76 77 func (api *API) StateServingInfo() (result params.StateServingInfo, err error) { 78 if !api.auth.AuthEnvironManager() { 79 err = common.ErrPerm 80 return 81 } 82 return api.st.StateServingInfo() 83 } 84 85 // MongoIsMaster is called by the IsMaster API call 86 // instead of mongo.IsMaster. It exists so it can 87 // be overridden by tests. 88 var MongoIsMaster = mongo.IsMaster 89 90 func (api *API) IsMaster() (params.IsMasterResult, error) { 91 if !api.auth.AuthEnvironManager() { 92 return params.IsMasterResult{}, common.ErrPerm 93 } 94 95 session := api.st.MongoSession() 96 machine := api.auth.GetAuthEntity().(*state.Machine) 97 98 isMaster, err := MongoIsMaster(session, machine) 99 return params.IsMasterResult{Master: isMaster}, err 100 } 101 102 func stateJobsToAPIParamsJobs(jobs []state.MachineJob) []params.MachineJob { 103 pjobs := make([]params.MachineJob, len(jobs)) 104 for i, job := range jobs { 105 pjobs[i] = params.MachineJob(job.String()) 106 } 107 return pjobs 108 }