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 }