github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/api/common/leadership.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/api/base" 11 "github.com/juju/juju/apiserver/params" 12 ) 13 14 const leadershipFacade = "LeadershipPinning" 15 16 // LeadershipPinningAPI provides common client-side API functions 17 // for manipulating and querying application leadership pinning. 18 type LeadershipPinningAPI struct { 19 facade base.FacadeCaller 20 } 21 22 // NewLeadershipPinningAPI creates and returns a new leadership API client. 23 func NewLeadershipPinningAPI(caller base.APICaller) *LeadershipPinningAPI { 24 facadeCaller := base.NewFacadeCaller( 25 caller, 26 leadershipFacade, 27 ) 28 return NewLeadershipPinningAPIFromFacade(facadeCaller) 29 } 30 31 // NewLeadershipPinningAPIFromFacade creates and returns a new leadership API 32 // client based on the input client facade and facade caller. 33 func NewLeadershipPinningAPIFromFacade(facade base.FacadeCaller) *LeadershipPinningAPI { 34 return &LeadershipPinningAPI{ 35 facade: facade, 36 } 37 } 38 39 // PinnedLeadership returns a collection of application names for which 40 // leadership is currently pinned, with the entities requiring each 41 // application's pinned behaviour. 42 func (a *LeadershipPinningAPI) PinnedLeadership() (map[string][]names.Tag, error) { 43 var callResult params.PinnedLeadershipResult 44 err := a.facade.FacadeCall("PinnedLeadership", nil, &callResult) 45 if err != nil { 46 return nil, errors.Trace(err) 47 } 48 49 pinned := make(map[string][]names.Tag, len(callResult.Result)) 50 for app, entities := range callResult.Result { 51 entityTags := make([]names.Tag, len(entities)) 52 for i, e := range entities { 53 tag, err := names.ParseTag(e) 54 if err != nil { 55 return nil, errors.Trace(err) 56 } 57 entityTags[i] = tag 58 } 59 60 pinned[app] = entityTags 61 } 62 return pinned, nil 63 } 64 65 // PinMachineApplications pins leadership for applications represented by units 66 // running on the local machine. 67 // If the caller is not a machine agent, an error will be returned. 68 // The return is a collection of applications determined to be running on the 69 // machine, with the result of each individual pin operation. 70 func (a *LeadershipPinningAPI) PinMachineApplications() (map[string]error, error) { 71 res, err := a.pinMachineAppsOps("PinMachineApplications") 72 return res, errors.Trace(err) 73 } 74 75 // UnpinMachineApplications pins leadership for applications represented by 76 // units running on the local machine. 77 // If the caller is not a machine agent, an error will be returned. 78 // The return is a collection of applications determined to be running on the 79 // machine, with the result of each individual unpin operation. 80 func (a *LeadershipPinningAPI) UnpinMachineApplications() (map[string]error, error) { 81 res, err := a.pinMachineAppsOps("UnpinMachineApplications") 82 return res, errors.Trace(err) 83 } 84 85 // pinMachineAppsOps makes a facade call to the input method name and 86 // transforms the response into map. 87 func (a *LeadershipPinningAPI) pinMachineAppsOps(callName string) (map[string]error, error) { 88 var callResult params.PinApplicationsResults 89 err := a.facade.FacadeCall(callName, nil, &callResult) 90 if err != nil { 91 return nil, errors.Trace(err) 92 } 93 94 callResults := callResult.Results 95 result := make(map[string]error, len(callResults)) 96 for _, res := range callResults { 97 var appErr error 98 if res.Error != nil { 99 appErr = res.Error 100 } 101 result[res.ApplicationName] = appErr 102 } 103 return result, nil 104 }