github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/juju/block/unblock.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package block
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"launchpad.net/gnuflag"
    13  
    14  	"github.com/juju/juju/cmd/envcmd"
    15  )
    16  
    17  // UnblockCommand removes the block from desired operation.
    18  type UnblockCommand struct {
    19  	envcmd.EnvCommandBase
    20  	operation string
    21  }
    22  
    23  var (
    24  	unblockDoc = `
    25  
    26  Juju allows to safeguard deployed environments from unintentional damage by preventing
    27  execution of operations that could alter environment.
    28  
    29  This is done by blocking certain commands from successful execution. Blocked commands
    30  must be manually unblocked to proceed.
    31  
    32  Some commands offer a --force option that can be used to bypass a block.
    33  
    34  Commands that can be unblocked are grouped based on logical operations as follows:
    35  
    36  destroy-environment includes command:
    37      destroy-environment
    38  
    39  remove-object includes termination commands:
    40      destroy-environment
    41      remove-machine
    42      remove-relation
    43      remove-service
    44      remove-unit
    45  
    46  all-changes includes all alteration commands
    47      add-machine
    48      add-relation
    49      add-unit
    50      authorised-keys add
    51      authorised-keys delete
    52      authorised-keys import
    53      deploy
    54      destroy-environment
    55      ensure-availability
    56      expose
    57      remove-machine
    58      remove-relation
    59      remove-service
    60      remove-unit
    61      resolved
    62      retry-provisioning
    63      run
    64      set
    65      set-constraints
    66      set-env
    67      sync-tools
    68      unexpose
    69      unset
    70      unset-env
    71      upgrade-charm
    72      upgrade-juju
    73      user add
    74      user change-password
    75      user disable
    76      user enable
    77  
    78  Examples:
    79     To allow the environment to be destroyed:
    80     juju unblock destroy-environment
    81  
    82     To allow the machines, services, units and relations to be removed:
    83     juju unblock remove-object
    84  
    85     To allow changes to the environment:
    86     juju unblock all-changes
    87  
    88  See Also:
    89     juju help block
    90  `
    91  
    92  	// blockArgsFmt has formatted representation of block command valid arguments.
    93  	blockArgsFmt = fmt.Sprintf(strings.Join(blockArgs, " | "))
    94  )
    95  
    96  // assignValidOperation verifies that supplied operation is supported.
    97  func (p *UnblockCommand) assignValidOperation(cmd string, args []string) error {
    98  	if len(args) < 1 {
    99  		return errors.Trace(errors.Errorf("must specify one of [%v] to %v", blockArgsFmt, cmd))
   100  	}
   101  	var err error
   102  	p.operation, err = p.obtainValidArgument(args[0])
   103  	return err
   104  }
   105  
   106  // obtainValidArgument returns polished argument:
   107  // it checks that the argument is a supported operation and
   108  // forces it into lower case for consistency.
   109  func (p *UnblockCommand) obtainValidArgument(arg string) (string, error) {
   110  	for _, valid := range blockArgs {
   111  		if strings.EqualFold(valid, arg) {
   112  			return strings.ToLower(arg), nil
   113  		}
   114  	}
   115  	return "", errors.Trace(errors.Errorf("%q is not a valid argument: use one of [%v]", arg, blockArgsFmt))
   116  }
   117  
   118  // Info provides information about command.
   119  // Satisfying Command interface.
   120  func (c *UnblockCommand) Info() *cmd.Info {
   121  	return &cmd.Info{
   122  		Name:    "unblock",
   123  		Args:    blockArgsFmt,
   124  		Purpose: "unblock an operation that would alter a running environment",
   125  		Doc:     unblockDoc,
   126  	}
   127  }
   128  
   129  // Init initializes the command.
   130  // Satisfying Command interface.
   131  func (c *UnblockCommand) Init(args []string) error {
   132  	if len(args) > 1 {
   133  		return errors.Trace(errors.New("can only specify block type"))
   134  	}
   135  
   136  	return c.assignValidOperation("unblock", args)
   137  }
   138  
   139  // SetFlags implements Command.SetFlags.
   140  func (c *UnblockCommand) SetFlags(f *gnuflag.FlagSet) {
   141  	c.EnvCommandBase.SetFlags(f)
   142  }
   143  
   144  // Run unblocks previously blocked commands.
   145  // Satisfying Command interface.
   146  func (c *UnblockCommand) Run(_ *cmd.Context) error {
   147  	client, err := getUnblockClientAPI(c)
   148  	if err != nil {
   149  		return errors.Trace(err)
   150  	}
   151  	defer client.Close()
   152  
   153  	return client.SwitchBlockOff(TypeFromOperation(c.operation))
   154  }
   155  
   156  // UnblockClientAPI defines the client API methods that unblock command uses.
   157  type UnblockClientAPI interface {
   158  	Close() error
   159  	SwitchBlockOff(blockType string) error
   160  }
   161  
   162  var getUnblockClientAPI = func(p *UnblockCommand) (UnblockClientAPI, error) {
   163  	return getBlockAPI(&p.EnvCommandBase)
   164  }