github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/controller/applicationscaler/facade.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package applicationscaler
     5  
     6  import (
     7  	"github.com/juju/errors"
     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  // Backend exposes functionality required by Facade.
    18  type Backend interface {
    19  
    20  	// WatchScaledServices returns a watcher that sends service ids
    21  	// that might not have enough units.
    22  	WatchScaledServices() state.StringsWatcher
    23  
    24  	// RescaleService ensures that the named service has at least its
    25  	// configured minimum unit count.
    26  	RescaleService(name string) error
    27  }
    28  
    29  // Facade allows model-manager clients to watch and rescale services.
    30  type Facade struct {
    31  	backend   Backend
    32  	resources facade.Resources
    33  }
    34  
    35  // NewFacade creates a new authorized Facade.
    36  func NewFacade(backend Backend, res facade.Resources, auth facade.Authorizer) (*Facade, error) {
    37  	if !auth.AuthController() {
    38  		return nil, common.ErrPerm
    39  	}
    40  	return &Facade{
    41  		backend:   backend,
    42  		resources: res,
    43  	}, nil
    44  }
    45  
    46  // Watch returns a watcher that sends the names of services whose
    47  // unit count may be below their configured minimum.
    48  func (facade *Facade) Watch() (params.StringsWatchResult, error) {
    49  	watch := facade.backend.WatchScaledServices()
    50  	if changes, ok := <-watch.Changes(); ok {
    51  		id := facade.resources.Register(watch)
    52  		return params.StringsWatchResult{
    53  			StringsWatcherId: id,
    54  			Changes:          changes,
    55  		}, nil
    56  	}
    57  	return params.StringsWatchResult{}, watcher.EnsureErr(watch)
    58  }
    59  
    60  // Rescale causes any supplied services to be scaled up to their
    61  // minimum size.
    62  func (facade *Facade) Rescale(args params.Entities) params.ErrorResults {
    63  	result := params.ErrorResults{
    64  		Results: make([]params.ErrorResult, len(args.Entities)),
    65  	}
    66  	for i, entity := range args.Entities {
    67  		err := facade.rescaleOne(entity.Tag)
    68  		result.Results[i].Error = common.ServerError(err)
    69  	}
    70  	return result
    71  }
    72  
    73  // rescaleOne scales up the supplied service, if necessary; or returns a
    74  // suitable error.
    75  func (facade *Facade) rescaleOne(tagString string) error {
    76  	tag, err := names.ParseTag(tagString)
    77  	if err != nil {
    78  		return errors.Trace(err)
    79  	}
    80  	ApplicationTag, ok := tag.(names.ApplicationTag)
    81  	if !ok {
    82  		return common.ErrPerm
    83  	}
    84  	return facade.backend.RescaleService(ApplicationTag.Id())
    85  }