github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/block/protection.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package block
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/loggo"
    11  
    12  	apiblock "github.com/juju/juju/api/block"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/cmd/modelcmd"
    15  	"github.com/juju/juju/state/multiwatcher"
    16  )
    17  
    18  var logger = loggo.GetLogger("juju.cmd.juju.block")
    19  
    20  // blockArgs has all valid operations that can be
    21  // supplied to the command.
    22  // These operations do not necessarily correspond to juju commands
    23  // but are rather juju command groupings.
    24  var blockArgs = []string{"destroy-model", "remove-object", "all-changes"}
    25  
    26  // TypeFromOperation translates given operation string
    27  // such as destroy-model, remove-object, etc to
    28  // block type string as defined in multiwatcher.
    29  var TypeFromOperation = func(operation string) string {
    30  	for key, value := range blockTypes {
    31  		if value == operation {
    32  			return key
    33  		}
    34  	}
    35  	panic(fmt.Sprintf("unknown operation %v", operation))
    36  }
    37  
    38  var blockTypes = map[string]string{
    39  	string(multiwatcher.BlockDestroy): "destroy-model",
    40  	string(multiwatcher.BlockRemove):  "remove-object",
    41  	string(multiwatcher.BlockChange):  "all-changes",
    42  }
    43  
    44  // OperationFromType translates given block type as
    45  // defined in multiwatcher into the operation
    46  // such as destroy-model.
    47  var OperationFromType = func(blockType string) string {
    48  	return blockTypes[blockType]
    49  }
    50  
    51  // getBlockAPI returns a block api for block manipulation.
    52  func getBlockAPI(c *modelcmd.ModelCommandBase) (*apiblock.Client, error) {
    53  	root, err := c.NewAPIRoot()
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	return apiblock.NewClient(root), nil
    58  }
    59  
    60  // Block describes block type
    61  type Block int8
    62  
    63  const (
    64  	// BlockDestroy describes the block that
    65  	// blocks destroy- commands
    66  	BlockDestroy Block = iota
    67  
    68  	// BlockRemove describes the block that
    69  	// blocks remove- commands
    70  	BlockRemove
    71  
    72  	// BlockChange describes the block that
    73  	// blocks change commands
    74  	BlockChange
    75  )
    76  
    77  var blockedMessages = map[Block]string{
    78  	BlockDestroy: destroyMsg,
    79  	BlockRemove:  removeMsg,
    80  	BlockChange:  changeMsg,
    81  }
    82  
    83  // ProcessBlockedError ensures that correct and user-friendly message is
    84  // displayed to the user based on the block type.
    85  func ProcessBlockedError(err error, block Block) error {
    86  	if err == nil {
    87  		return nil
    88  	}
    89  	if params.IsCodeOperationBlocked(err) {
    90  		logger.Errorf("\n%v%v", err, blockedMessages[block])
    91  		return cmd.ErrSilent
    92  	}
    93  	return err
    94  }
    95  
    96  var removeMsg = `
    97  All operations that remove (or delete or terminate) machines, services, units or
    98  relations have been blocked for the current model.
    99  To unblock removal, run
   100  
   101      juju unblock remove-object
   102  
   103  `
   104  var destroyMsg = `
   105  destroy-model operation has been blocked for the current model.
   106  To remove the block run
   107  
   108      juju unblock destroy-model
   109  
   110  `
   111  var changeMsg = `
   112  All operations that change model have been blocked for the current model.
   113  To unblock changes, run
   114  
   115      juju unblock all-changes
   116  
   117  `