github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/upgrading_root.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiserver
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/utils/set"
     9  
    10  	"github.com/juju/juju/apiserver/params"
    11  	"github.com/juju/juju/rpc"
    12  	"github.com/juju/juju/rpc/rpcreflect"
    13  )
    14  
    15  // upgradingRoot restricts API calls to those supported during an upgrade.
    16  type upgradingRoot struct {
    17  	rpc.MethodFinder
    18  }
    19  
    20  // newUpgradingRoot returns a new upgradingRoot.
    21  func newUpgradingRoot(finder rpc.MethodFinder) *upgradingRoot {
    22  	return &upgradingRoot{finder}
    23  }
    24  
    25  // allowedMethodsDuringUpgrades stores api calls
    26  // that are not blocked during the upgrade process
    27  // as well as  their respective facade names.
    28  // When needed, at some future point, this solution
    29  // will need to be adjusted to cater for different
    30  // facade versions as well.
    31  var allowedMethodsDuringUpgrades = map[string]set.Strings{
    32  	"Client": set.NewStrings(
    33  		"FullStatus",          // for "juju status"
    34  		"ModelGet",            // for "juju ssh"
    35  		"PrivateAddress",      // for "juju ssh"
    36  		"PublicAddress",       // for "juju ssh"
    37  		"FindTools",           // for "juju upgrade-juju", before we can reset upgrade to re-run
    38  		"AbortCurrentUpgrade", // for "juju upgrade-juju", so that we can reset upgrade to re-run
    39  	),
    40  	"Pinger": set.NewStrings(
    41  		"Ping",
    42  	),
    43  }
    44  
    45  func IsMethodAllowedDuringUpgrade(rootName, methodName string) bool {
    46  	methods, ok := allowedMethodsDuringUpgrades[rootName]
    47  	if !ok {
    48  		return false
    49  	}
    50  	return methods.Contains(methodName)
    51  }
    52  
    53  // FindMethod returns UpgradeInProgressError for most API calls except those that are
    54  // deemed safe or important for use while Juju is upgrading.
    55  func (r *upgradingRoot) FindMethod(rootName string, version int, methodName string) (rpcreflect.MethodCaller, error) {
    56  	caller, err := r.MethodFinder.FindMethod(rootName, version, methodName)
    57  	if err != nil {
    58  		return nil, errors.Trace(err)
    59  	}
    60  	if !IsMethodAllowedDuringUpgrade(rootName, methodName) {
    61  		logger.Debugf("Facade (%v) method (%v) was called during the upgrade but it was blocked.", rootName, methodName)
    62  		return nil, params.UpgradeInProgressError
    63  	}
    64  	return caller, nil
    65  }