github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/restoring_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/rpc"
    11  	"github.com/juju/juju/rpc/rpcreflect"
    12  )
    13  
    14  var aboutToRestoreError = errors.New("juju restore is in progress - Juju functionality is limited to avoid data loss")
    15  var restoreInProgressError = errors.New("juju restore is in progress - Juju api is off to prevent data loss")
    16  
    17  // aboutToRestoreRoot a root that will only allow a limited
    18  // set of methods to run, defined in allowedMethodsAboutToRestore.
    19  type aboutToRestoreRoot struct {
    20  	rpc.MethodFinder
    21  }
    22  
    23  // restoreRoot a root that will not allow calls whatsoever during restore.
    24  type restoreInProgressRoot struct {
    25  	rpc.MethodFinder
    26  }
    27  
    28  // newAboutToRestoreRoot creates a root where all API calls
    29  // but restore will fail with aboutToRestoreError.
    30  func newAboutToRestoreRoot(finder rpc.MethodFinder) *aboutToRestoreRoot {
    31  	return &aboutToRestoreRoot{
    32  		MethodFinder: finder,
    33  	}
    34  }
    35  
    36  // newRestoreInProressRoot creates a root where all API calls
    37  // but restore will fail with restoreInProgressError.
    38  func newRestoreInProgressRoot(finder rpc.MethodFinder) *restoreInProgressRoot {
    39  	return &restoreInProgressRoot{
    40  		MethodFinder: finder,
    41  	}
    42  }
    43  
    44  // FindMethod extended srvRoot.FindMethod. It returns aboutToRestoreError
    45  // for all API calls except Client.Restore
    46  // for use while Juju is preparing to restore a backup.
    47  func (r *aboutToRestoreRoot) FindMethod(rootName string, version int, methodName string) (rpcreflect.MethodCaller, error) {
    48  	caller, err := r.MethodFinder.FindMethod(rootName, version, methodName)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	if !isMethodAllowedAboutToRestore(rootName, methodName) {
    53  		return nil, aboutToRestoreError
    54  	}
    55  	return caller, nil
    56  }
    57  
    58  var allowedMethodsAboutToRestore = set.NewStrings(
    59  	"Client.FullStatus",     // for "juju status"
    60  	"Client.ModelGet",       // for "juju ssh"
    61  	"Client.PrivateAddress", // for "juju ssh"
    62  	"Client.PublicAddress",  // for "juju ssh"
    63  	"Client.WatchDebugLog",  // for "juju debug-log"
    64  	"Backups.Restore",       // for "juju backups restore"
    65  	"Backups.FinishRestore", // for "juju backups restore"
    66  )
    67  
    68  // isMethodAllowedAboutToRestore return true if this method is allowed when the server is in state.RestorePreparing mode
    69  // at present only Backups.Restore is.
    70  func isMethodAllowedAboutToRestore(rootName, methodName string) bool {
    71  	fullName := rootName + "." + methodName
    72  	return allowedMethodsAboutToRestore.Contains(fullName)
    73  }
    74  
    75  // FindMethod extended srvRoot.FindMethod. It returns restoreInProgressError
    76  // for all API calls.
    77  // for use while Juju is restoring a backup.
    78  func (r *restoreInProgressRoot) FindMethod(rootName string, version int, methodName string) (rpcreflect.MethodCaller, error) {
    79  	_, err := r.MethodFinder.FindMethod(rootName, version, methodName)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	return nil, restoreInProgressError
    84  }