github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/facade" 11 "github.com/juju/juju/apiserver/params" 12 "github.com/juju/juju/state" 13 ) 14 15 // ModelStatusAPI implements the ModelStatus() API. 16 type ModelStatusAPI struct { 17 authorizer facade.Authorizer 18 apiUser names.UserTag 19 backend ModelManagerBackend 20 } 21 22 // NewModelStatusAPI creates an implementation providing the ModelStatus() API. 23 func NewModelStatusAPI(backend ModelManagerBackend, authorizer facade.Authorizer, apiUser names.UserTag) *ModelStatusAPI { 24 return &ModelStatusAPI{ 25 authorizer: authorizer, 26 apiUser: apiUser, 27 backend: backend, 28 } 29 } 30 31 // ModelStatus returns a summary of the model. 32 func (c *ModelStatusAPI) ModelStatus(req params.Entities) (params.ModelStatusResults, error) { 33 models := req.Entities 34 status := make([]params.ModelStatus, len(models)) 35 for i, model := range models { 36 modelStatus, err := c.modelStatus(model.Tag) 37 if err != nil { 38 status[i].Error = ServerError(err) 39 continue 40 } 41 status[i] = modelStatus 42 } 43 return params.ModelStatusResults{Results: status}, nil 44 } 45 46 func (c *ModelStatusAPI) modelStatus(tag string) (params.ModelStatus, error) { 47 var status params.ModelStatus 48 modelTag, err := names.ParseModelTag(tag) 49 if err != nil { 50 return status, errors.Trace(err) 51 } 52 st := c.backend 53 if modelTag != c.backend.ModelTag() { 54 otherSt, releaser, err := c.backend.GetBackend(modelTag.Id()) 55 if err != nil { 56 return status, errors.Trace(err) 57 } 58 defer releaser() 59 st = otherSt 60 } 61 62 model, err := st.Model() 63 if err != nil { 64 return status, errors.Trace(err) 65 } 66 isAdmin, err := HasModelAdmin(c.authorizer, c.apiUser, c.backend.ControllerTag(), model) 67 if err != nil { 68 return status, errors.Trace(err) 69 } 70 if !isAdmin { 71 return status, ErrPerm 72 } 73 74 machines, err := st.AllMachines() 75 if err != nil { 76 return status, errors.Trace(err) 77 } 78 79 var hostedMachines []Machine 80 for _, m := range machines { 81 if !m.IsManager() { 82 hostedMachines = append(hostedMachines, m) 83 } 84 } 85 86 applications, err := st.AllApplications() 87 if err != nil { 88 return status, errors.Trace(err) 89 } 90 91 modelMachines, err := ModelMachineInfo(st) 92 if err != nil { 93 return status, errors.Trace(err) 94 } 95 96 result := params.ModelStatus{ 97 ModelTag: tag, 98 OwnerTag: model.Owner().String(), 99 Life: params.Life(model.Life().String()), 100 HostedMachineCount: len(hostedMachines), 101 ApplicationCount: len(applications), 102 Machines: modelMachines, 103 } 104 105 volumes, err := st.AllVolumes() 106 if err != nil { 107 return status, errors.Trace(err) 108 } 109 result.Volumes = ModelVolumeInfo(volumes) 110 111 filesystems, err := st.AllFilesystems() 112 if err != nil { 113 return status, errors.Trace(err) 114 } 115 result.Filesystems = ModelFilesystemInfo(filesystems) 116 return result, nil 117 } 118 119 // ModelFilesystemInfo returns information about filesystems in the model. 120 func ModelFilesystemInfo(in []state.Filesystem) []params.ModelFilesystemInfo { 121 out := make([]params.ModelFilesystemInfo, len(in)) 122 for i, in := range in { 123 var statusString string 124 status, err := in.Status() 125 if err != nil { 126 statusString = err.Error() 127 } else { 128 statusString = string(status.Status) 129 } 130 var providerId string 131 if info, err := in.Info(); err == nil { 132 providerId = info.FilesystemId 133 } 134 out[i] = params.ModelFilesystemInfo{ 135 Id: in.Tag().Id(), 136 ProviderId: providerId, 137 Status: statusString, 138 Message: status.Message, 139 Detachable: in.Detachable(), 140 } 141 } 142 return out 143 } 144 145 // ModelVolumeInfo returns information about volumes in the model. 146 func ModelVolumeInfo(in []state.Volume) []params.ModelVolumeInfo { 147 out := make([]params.ModelVolumeInfo, len(in)) 148 for i, in := range in { 149 var statusString string 150 status, err := in.Status() 151 if err != nil { 152 statusString = err.Error() 153 } else { 154 statusString = string(status.Status) 155 } 156 var providerId string 157 if info, err := in.Info(); err == nil { 158 providerId = info.VolumeId 159 } 160 out[i] = params.ModelVolumeInfo{ 161 Id: in.Tag().Id(), 162 ProviderId: providerId, 163 Status: statusString, 164 Message: status.Message, 165 Detachable: in.Detachable(), 166 } 167 } 168 return out 169 }