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 }