<commit_before>=========================
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
=========================

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. 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<commit_msg>Compliant with Markdown. Changed Client to Server.<commit_after>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.

    1. DESTROY_BLOCK blocks destroy-environment command.
    2. REMOVE_BLOCK blocks destroy-environment as well as all object removal - machines, services, units, relations.
    3. 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
=========================
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)

Server: client instance in apiserver package)
---------------------------------------------
  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.

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
{'fraction_non_alphanumeric': 0.12328278322925959, 'fraction_numerical': 0.0023193577163247102, 'mean_word_length': 2.5103318722604886, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6592156', 'n_tokens_mistral': 1371, 'n_tokens_neox': 1335, 'n_words': 591}