github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/agent/agent_v0.go (about)

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