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 }