<div dir="ltr">This sounds great, thanks!<div><br></div><div>Can you also block specific services from being removed?</div><div>That would fit in well with my own usage, where there's a</div><div>central database which would be a Bad Thing to remove,</div><div>but the other services are much more ephemeral.</div><div><br></div><div>  cheers,</div><div>    rog.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 9 January 2015 at 06:52, Anastasia Macmood <span dir="ltr"><<a href="mailto:anastasia.macmood@canonical.com" target="_blank">anastasia.macmood@canonical.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
I have recently worked on blocking juju commands. If you are creating<br>
new commands, you may find this helpful :-)<br>
<br>
PROBLEM<br>
Customers and stakeholders want to be able to prevent accidental damage<br>
to their Juju deployments.<br>
<br>
SOLUTION<br>
To prevent running some commands, we have introduced a concept of<br>
command block. Once the block is switched on, it has to be manually<br>
switched off to run commands successfully.<br>
<br>
There are currently three types of blocks developed.<br>
DESTROY_BLOCK blocks destroy-environment command.<br>
REMOVE_BLOCK blocks destroy-environment as well as all object removal -<br>
machines, services, units, relations.<br>
CHANGE_BLOCK blocks all commands from DESTROY and REMOVE blocks as well<br>
as all environment modifications.<br>
For more information and the list of all commands that are blocked, run<br>
`juju help block` or `juju help unblock`.<br>
<br>
IMPLEMENTATION<br>
These are the steps that I followed when blocking a command.<br>
<br>
A. Command (package cmd/juju)<br>
    1. Help for block/unblock command is updated to contain your command.<br>
    2. Delegate error processing of the client from apiserver error.<br>
Most commonly, it would be done in the implementation of the Run from<br>
Command interface.<br>
       E.g.<br>
<br>
      func (c *SetFluffCommand) Run(_ *cmd.Context) (err error) {<br>
        ....<br>
        err := apiclient.SetFluff(args)<br>
        //there are corresponding block.BlockDestroy and block.BlockRemove<br>
        return block.ProcessBlockedError(err, block.BlockChange)<br>
      }<br>
<br>
  3. Add tests switching the block on before running the command.<br>
     Eg.<br>
<br>
      // Block operation<br>
      s.AssertConfigParameterUpdated(c, "block-all-changes", true)<br>
<br>
B. Client (package apiserver)<br>
  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.<br>
     E.g.<br>
<br>
        func (c *Client) SetFluff(args params.SetFluff) error {<br>
            if err := c.check.ChangeAllowed(); err != nil {<br>
               return errors.Trace(err)<br>
            }<br>
            ......<br>
        }<br>
<br>
     or<br>
<br>
        func (c *Client) SetFluff(args params.SetFluff) error {<br>
            blockChecker := common.NewBlockChecker(st)<br>
            //there are corresponding blockChecker.DestroyAllowed() and block.RemoveAllowed()<br>
            if err := blockChecker.ChangeAllowed(); err != nil {<br>
                return errors.Trace(err)<br>
            }<br>
            ......<br>
        }<br>
<br>
  2. Add tests switching the block on.<br>
<br>
C. Notify Interested Parties<br>
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 :)<br>
<br>
Let me know if this information is helpful.<br>
<br>
Sincerely Yours,<br>
<br>
Anastasia<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
<br>
--<br>
Juju-dev mailing list<br>
<a href="mailto:Juju-dev@lists.ubuntu.com">Juju-dev@lists.ubuntu.com</a><br>
Modify settings or unsubscribe at: <a href="https://lists.ubuntu.com/mailman/listinfo/juju-dev" target="_blank">https://lists.ubuntu.com/mailman/listinfo/juju-dev</a><br>
</font></span></blockquote></div><br></div>