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  }