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