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