github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/meterstatus/meterstatus.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // Package meterstatus provides the meter status API facade.
     5  package meterstatus
     6  
     7  import (
     8  	"github.com/juju/loggo"
     9  	"github.com/juju/names"
    10  
    11  	"github.com/juju/juju/apiserver/common"
    12  	"github.com/juju/juju/apiserver/params"
    13  	"github.com/juju/juju/state"
    14  	"github.com/juju/juju/state/watcher"
    15  )
    16  
    17  var (
    18  	logger = loggo.GetLogger("juju.apiserver.meterstatus")
    19  )
    20  
    21  func init() {
    22  	common.RegisterStandardFacade("MeterStatus", 1, NewMeterStatusAPI)
    23  }
    24  
    25  // MeterStatus defines the methods exported by the meter status API facade.
    26  type MeterStatus interface {
    27  	GetMeterStatus(args params.Entities) (params.MeterStatusResults, error)
    28  	WatchMeterStatus(args params.Entities) (params.NotifyWatchResults, error)
    29  }
    30  
    31  // MeterStatusAPI implements the MeterStatus interface and is the concrete implementation
    32  // of the API endpoint.
    33  type MeterStatusAPI struct {
    34  	state      *state.State
    35  	accessUnit common.GetAuthFunc
    36  	resources  *common.Resources
    37  }
    38  
    39  var _ MeterStatus = (*MeterStatusAPI)(nil)
    40  
    41  // NewMeterStatusAPI creates a new API endpoint for dealing with unit meter status.
    42  func NewMeterStatusAPI(
    43  	st *state.State,
    44  	resources *common.Resources,
    45  	authorizer common.Authorizer,
    46  ) (*MeterStatusAPI, error) {
    47  	if !authorizer.AuthUnitAgent() {
    48  		return nil, common.ErrPerm
    49  	}
    50  	return &MeterStatusAPI{
    51  		state: st,
    52  		accessUnit: func() (common.AuthFunc, error) {
    53  			return authorizer.AuthOwner, nil
    54  		},
    55  		resources: resources,
    56  	}, nil
    57  }
    58  
    59  // WatchMeterStatus returns a NotifyWatcher for observing changes
    60  // to each unit's meter status.
    61  func (m *MeterStatusAPI) WatchMeterStatus(args params.Entities) (params.NotifyWatchResults, error) {
    62  	result := params.NotifyWatchResults{
    63  		Results: make([]params.NotifyWatchResult, len(args.Entities)),
    64  	}
    65  	canAccess, err := m.accessUnit()
    66  	if err != nil {
    67  		return params.NotifyWatchResults{}, err
    68  	}
    69  	for i, entity := range args.Entities {
    70  		tag, err := names.ParseUnitTag(entity.Tag)
    71  		if err != nil {
    72  			result.Results[i].Error = common.ServerError(common.ErrPerm)
    73  			continue
    74  		}
    75  		err = common.ErrPerm
    76  		watcherId := ""
    77  		if canAccess(tag) {
    78  			watcherId, err = m.watchOneUnitMeterStatus(tag)
    79  		}
    80  		result.Results[i].NotifyWatcherId = watcherId
    81  		result.Results[i].Error = common.ServerError(err)
    82  	}
    83  	return result, nil
    84  }
    85  
    86  func (m *MeterStatusAPI) watchOneUnitMeterStatus(tag names.UnitTag) (string, error) {
    87  	unit, err := m.state.Unit(tag.Id())
    88  	if err != nil {
    89  		return "", err
    90  	}
    91  	watch := unit.WatchMeterStatus()
    92  	if _, ok := <-watch.Changes(); ok {
    93  		return m.resources.Register(watch), nil
    94  	}
    95  	return "", watcher.EnsureErr(watch)
    96  }
    97  
    98  // GetMeterStatus returns meter status information for each unit.
    99  func (m *MeterStatusAPI) GetMeterStatus(args params.Entities) (params.MeterStatusResults, error) {
   100  	result := params.MeterStatusResults{
   101  		Results: make([]params.MeterStatusResult, len(args.Entities)),
   102  	}
   103  	canAccess, err := m.accessUnit()
   104  	if err != nil {
   105  		return params.MeterStatusResults{}, common.ErrPerm
   106  	}
   107  	for i, entity := range args.Entities {
   108  		unitTag, err := names.ParseUnitTag(entity.Tag)
   109  		if err != nil {
   110  			result.Results[i].Error = common.ServerError(common.ErrPerm)
   111  			continue
   112  		}
   113  		err = common.ErrPerm
   114  		var status state.MeterStatus
   115  		if canAccess(unitTag) {
   116  			var unit *state.Unit
   117  			unit, err = m.state.Unit(unitTag.Id())
   118  			if err == nil {
   119  				status, err = MeterStatusWrapper(unit.GetMeterStatus)
   120  			}
   121  			result.Results[i].Code = status.Code.String()
   122  			result.Results[i].Info = status.Info
   123  		}
   124  		result.Results[i].Error = common.ServerError(err)
   125  	}
   126  	return result, nil
   127  }