github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/common/instanceidgetter.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common
     5  
     6  import (
     7  	"github.com/juju/names/v5"
     8  
     9  	apiservererrors "github.com/juju/juju/apiserver/errors"
    10  	"github.com/juju/juju/core/instance"
    11  	"github.com/juju/juju/rpc/params"
    12  	"github.com/juju/juju/state"
    13  )
    14  
    15  // InstanceIdGetter implements a common InstanceId method for use by
    16  // various facades.
    17  type InstanceIdGetter struct {
    18  	st         state.EntityFinder
    19  	getCanRead GetAuthFunc
    20  }
    21  
    22  // NewInstanceIdGetter returns a new InstanceIdGetter. The GetAuthFunc
    23  // will be used on each invocation of InstanceId to determine current
    24  // permissions.
    25  func NewInstanceIdGetter(st state.EntityFinder, getCanRead GetAuthFunc) *InstanceIdGetter {
    26  	return &InstanceIdGetter{
    27  		st:         st,
    28  		getCanRead: getCanRead,
    29  	}
    30  }
    31  
    32  func (ig *InstanceIdGetter) getInstanceId(tag names.Tag) (instance.Id, error) {
    33  	entity0, err := ig.st.FindEntity(tag)
    34  	if err != nil {
    35  		return "", err
    36  	}
    37  	entity, ok := entity0.(state.InstanceIdGetter)
    38  	if !ok {
    39  		return "", apiservererrors.NotSupportedError(tag, "instance id")
    40  	}
    41  	return entity.InstanceId()
    42  }
    43  
    44  // InstanceId returns the provider specific instance id for each given
    45  // machine or an CodeNotProvisioned error, if not set.
    46  func (ig *InstanceIdGetter) InstanceId(args params.Entities) (params.StringResults, error) {
    47  	result := params.StringResults{
    48  		Results: make([]params.StringResult, len(args.Entities)),
    49  	}
    50  	canRead, err := ig.getCanRead()
    51  	if err != nil {
    52  		return result, err
    53  	}
    54  	for i, entity := range args.Entities {
    55  		tag, err := names.ParseTag(entity.Tag)
    56  		if err != nil {
    57  			result.Results[i].Error = apiservererrors.ServerError(apiservererrors.ErrPerm)
    58  			continue
    59  		}
    60  		err = apiservererrors.ErrPerm
    61  		if canRead(tag) {
    62  			var instanceId instance.Id
    63  			instanceId, err = ig.getInstanceId(tag)
    64  			if err == nil {
    65  				result.Results[i].Result = string(instanceId)
    66  			}
    67  		}
    68  		result.Results[i].Error = apiservererrors.ServerError(err)
    69  	}
    70  	return result, nil
    71  }