github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/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/collections/transform" 8 "github.com/juju/errors" 9 "github.com/juju/names/v5" 10 11 "github.com/juju/juju/api/base" 12 "github.com/juju/juju/core/model" 13 "github.com/juju/juju/rpc/params" 14 ) 15 16 // ModelStatusAPI provides common client-side API functions 17 // to call into apiserver.common.ModelStatusAPI. 18 type ModelStatusAPI struct { 19 facade base.FacadeCaller 20 } 21 22 // NewModelStatusAPI creates a ModelStatusAPI on the specified facade, 23 // and uses this name when calling through the caller. 24 func NewModelStatusAPI(facade base.FacadeCaller) *ModelStatusAPI { 25 return &ModelStatusAPI{facade} 26 } 27 28 // ModelStatus returns a status summary for each model tag passed in. 29 func (c *ModelStatusAPI) ModelStatus(tags ...names.ModelTag) ([]base.ModelStatus, error) { 30 result := params.ModelStatusResults{} 31 models := make([]params.Entity, len(tags)) 32 for i, tag := range tags { 33 models[i] = params.Entity{Tag: tag.String()} 34 } 35 req := params.Entities{ 36 Entities: models, 37 } 38 if err := c.facade.FacadeCall("ModelStatus", req, &result); err != nil { 39 return nil, err 40 } 41 if len(result.Results) != len(tags) { 42 return nil, errors.Errorf("%d results, expected %d", len(result.Results), len(tags)) 43 } 44 return c.processModelStatusResults(result.Results) 45 } 46 47 func (c *ModelStatusAPI) processModelStatusResults(rs []params.ModelStatus) ([]base.ModelStatus, error) { 48 results := make([]base.ModelStatus, len(rs)) 49 for i, r := range rs { 50 if r.Error != nil { 51 // cope with typed error 52 results[i].Error = errors.Trace(r.Error) 53 continue 54 } 55 aModel, err := names.ParseModelTag(r.ModelTag) 56 if err != nil { 57 results[i].Error = errors.Trace(err) 58 continue 59 } 60 owner, err := names.ParseUserTag(r.OwnerTag) 61 if err != nil { 62 results[i].Error = errors.Trace(err) 63 continue 64 } 65 results[i] = constructModelStatus(aModel, owner, r) 66 } 67 return results, nil 68 } 69 70 func constructModelStatus(m names.ModelTag, owner names.UserTag, r params.ModelStatus) base.ModelStatus { 71 volumes := make([]base.Volume, len(r.Volumes)) 72 for i, in := range r.Volumes { 73 volumes[i] = base.Volume{ 74 Id: in.Id, 75 ProviderId: in.ProviderId, 76 Status: in.Status, 77 Message: in.Message, 78 Detachable: in.Detachable, 79 } 80 } 81 82 filesystems := make([]base.Filesystem, len(r.Filesystems)) 83 for i, in := range r.Filesystems { 84 filesystems[i] = base.Filesystem{ 85 Id: in.Id, 86 ProviderId: in.ProviderId, 87 Status: in.Status, 88 Message: in.Message, 89 Detachable: in.Detachable, 90 } 91 } 92 93 result := base.ModelStatus{ 94 UUID: m.Id(), 95 Life: r.Life, 96 Owner: owner.Id(), 97 ModelType: model.ModelType(r.Type), 98 HostedMachineCount: r.HostedMachineCount, 99 ApplicationCount: r.ApplicationCount, 100 UnitCount: r.UnitCount, 101 TotalMachineCount: len(r.Machines), 102 Volumes: volumes, 103 Filesystems: filesystems, 104 } 105 result.Machines = make([]base.Machine, len(r.Machines)) 106 for j, mm := range r.Machines { 107 if mm.Hardware != nil && mm.Hardware.Cores != nil { 108 result.CoreCount += int(*mm.Hardware.Cores) 109 } 110 result.Machines[j] = base.Machine{ 111 Id: mm.Id, 112 InstanceId: mm.InstanceId, 113 DisplayName: mm.DisplayName, 114 HasVote: mm.HasVote, 115 WantsVote: mm.WantsVote, 116 Status: mm.Status, 117 Message: mm.Message, 118 HAPrimary: mm.HAPrimary, 119 } 120 } 121 result.Applications = transform.Slice(r.Applications, func(app params.ModelApplicationInfo) base.Application { 122 return base.Application{Name: app.Name} 123 }) 124 return result 125 }