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