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  }