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 }