blocking commands

roger peppe roger.peppe at canonical.com
Fri Jan 9 12:37:19 UTC 2015


This sounds great, thanks!

Can you also block specific services from being removed?
That would fit in well with my own usage, where there's a
central database which would be a Bad Thing to remove,
but the other services are much more ephemeral.

  cheers,
    rog.

On 9 January 2015 at 06:52, Anastasia Macmood <
anastasia.macmood at canonical.com> wrote:

>
> I have recently worked on blocking juju commands. If you are creating
> new commands, you may find this helpful :-)
>
> PROBLEM
> Customers and stakeholders want to be able to prevent accidental damage
> to their Juju deployments.
>
> SOLUTION
> To prevent running some commands, we have introduced a concept of
> command block. Once the block is switched on, it has to be manually
> switched off to run commands successfully.
>
> There are currently three types of blocks developed.
> DESTROY_BLOCK blocks destroy-environment command.
> REMOVE_BLOCK blocks destroy-environment as well as all object removal -
> machines, services, units, relations.
> CHANGE_BLOCK blocks all commands from DESTROY and REMOVE blocks as well
> as all environment modifications.
> For more information and the list of all commands that are blocked, run
> `juju help block` or `juju help unblock`.
>
> IMPLEMENTATION
> These are the steps that I followed when blocking a command.
>
> A. Command (package cmd/juju)
>     1. Help for block/unblock command is updated to contain your command.
>     2. Delegate error processing of the client from apiserver error.
> Most commonly, it would be done in the implementation of the Run from
> Command interface.
>        E.g.
>
>       func (c *SetFluffCommand) Run(_ *cmd.Context) (err error) {
>         ....
>         err := apiclient.SetFluff(args)
>         //there are corresponding block.BlockDestroy and block.BlockRemove
>         return block.ProcessBlockedError(err, block.BlockChange)
>       }
>
>   3. Add tests switching the block on before running the command.
>      Eg.
>
>       // Block operation
>       s.AssertConfigParameterUpdated(c, "block-all-changes", true)
>
> B. Client (package apiserver)
>   1. On desired operation, before any other processing, check if the block
> is enabled using common.BlockChecker. Some client already have this checker
> embedded. To construct new checker, you'll need a state.State.
>      E.g.
>
>         func (c *Client) SetFluff(args params.SetFluff) error {
>             if err := c.check.ChangeAllowed(); err != nil {
>                return errors.Trace(err)
>             }
>             ......
>         }
>
>      or
>
>         func (c *Client) SetFluff(args params.SetFluff) error {
>             blockChecker := common.NewBlockChecker(st)
>             //there are corresponding blockChecker.DestroyAllowed() and
> block.RemoveAllowed()
>             if err := blockChecker.ChangeAllowed(); err != nil {
>                 return errors.Trace(err)
>             }
>             ......
>         }
>
>   2. Add tests switching the block on.
>
> C. Notify Interested Parties
> At the very least, QA team might be interested in knowing that a new
> command became blockable. Juju documentation may need to be updated as well
> :)
>
> Let me know if this information is helpful.
>
> Sincerely Yours,
>
> Anastasia
>
>
>
>
> --
> Juju-dev mailing list
> Juju-dev at lists.ubuntu.com
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/juju-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/juju-dev/attachments/20150109/77b90666/attachment.html>


More information about the Juju-dev mailing list