github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/common/modelstatus.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common
     5  
     6  import (
     7  	"gopkg.in/juju/names.v2"
     8  
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/apiserver/facade"
    12  	"github.com/juju/juju/apiserver/params"
    13  	"github.com/juju/juju/permission"
    14  )
    15  
    16  // ModelStatusAPI implements the ModelStatus() API.
    17  type ModelStatusAPI struct {
    18  	authorizer facade.Authorizer
    19  	apiUser    names.UserTag
    20  	backend    ModelManagerBackend
    21  }
    22  
    23  // NewModelStatusAPI creates an implementation providing the ModelStatus() API.
    24  func NewModelStatusAPI(st ModelManagerBackend, authorizer facade.Authorizer, apiUser names.UserTag) *ModelStatusAPI {
    25  	return &ModelStatusAPI{
    26  		authorizer: authorizer,
    27  		apiUser:    apiUser,
    28  		backend:    st,
    29  	}
    30  }
    31  
    32  func (s *ModelStatusAPI) checkHasAdmin() error {
    33  	isAdmin, err := s.authorizer.HasPermission(permission.SuperuserAccess, s.backend.ControllerTag())
    34  	if err != nil {
    35  		return errors.Trace(err)
    36  	}
    37  	if !isAdmin {
    38  		return ServerError(ErrPerm)
    39  	}
    40  	return nil
    41  }
    42  
    43  // modelAuthCheck checks if the user is acting on their own behalf, or if they
    44  // are an administrator acting on behalf of another user.
    45  func (s *ModelStatusAPI) modelAuthCheck(modelTag names.ModelTag, owner names.UserTag) error {
    46  	if err := s.checkHasAdmin(); err == nil {
    47  		logger.Tracef("%q is a controller admin", s.apiUser.Id())
    48  		return nil
    49  	}
    50  	if s.apiUser == owner {
    51  		return nil
    52  	}
    53  	isAdmin, err := s.authorizer.HasPermission(permission.AdminAccess, modelTag)
    54  	if err != nil {
    55  		return errors.Trace(err)
    56  	}
    57  	if isAdmin {
    58  		return nil
    59  	}
    60  	return ErrPerm
    61  }
    62  
    63  // ModelStatus returns a summary of the model.
    64  func (c *ModelStatusAPI) ModelStatus(req params.Entities) (params.ModelStatusResults, error) {
    65  	models := req.Entities
    66  	results := params.ModelStatusResults{}
    67  
    68  	status := make([]params.ModelStatus, len(models))
    69  	for i, model := range models {
    70  		modelStatus, err := c.modelStatus(model.Tag)
    71  		if err != nil {
    72  			return results, errors.Trace(err)
    73  		}
    74  		status[i] = modelStatus
    75  	}
    76  	results.Results = status
    77  	return results, nil
    78  }
    79  
    80  func (c *ModelStatusAPI) modelStatus(tag string) (params.ModelStatus, error) {
    81  	var status params.ModelStatus
    82  	modelTag, err := names.ParseModelTag(tag)
    83  	if err != nil {
    84  		return status, errors.Trace(err)
    85  	}
    86  	st := c.backend
    87  	if modelTag != c.backend.ModelTag() {
    88  		if st, err = c.backend.ForModel(modelTag); err != nil {
    89  			return status, errors.Trace(err)
    90  		}
    91  		defer st.Close()
    92  	}
    93  
    94  	model, err := st.Model()
    95  	if err != nil {
    96  		return status, errors.Trace(err)
    97  	}
    98  	if err := c.modelAuthCheck(modelTag, model.Owner()); err != nil {
    99  		return status, errors.Trace(err)
   100  	}
   101  
   102  	machines, err := st.AllMachines()
   103  	if err != nil {
   104  		return status, errors.Trace(err)
   105  	}
   106  
   107  	var hostedMachines []Machine
   108  	for _, m := range machines {
   109  		if !m.IsManager() {
   110  			hostedMachines = append(hostedMachines, m)
   111  		}
   112  	}
   113  
   114  	applications, err := st.AllApplications()
   115  	if err != nil {
   116  		return status, errors.Trace(err)
   117  	}
   118  
   119  	modelMachines, err := ModelMachineInfo(st)
   120  	if err != nil {
   121  		return status, errors.Trace(err)
   122  	}
   123  
   124  	return params.ModelStatus{
   125  		ModelTag:           tag,
   126  		OwnerTag:           model.Owner().String(),
   127  		Life:               params.Life(model.Life().String()),
   128  		HostedMachineCount: len(hostedMachines),
   129  		ApplicationCount:   len(applications),
   130  		Machines:           modelMachines,
   131  	}, nil
   132  }