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  }