github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/client/controller/destroy.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package controller
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/apiserver/common"
    10  	apiservererrors "github.com/juju/juju/apiserver/errors"
    11  	"github.com/juju/juju/apiserver/facade"
    12  	"github.com/juju/juju/core/permission"
    13  	"github.com/juju/juju/rpc/params"
    14  	"github.com/juju/juju/state"
    15  )
    16  
    17  // DestroyController destroys the controller.
    18  //
    19  // If the args specify the destruction of the models, this method will
    20  // attempt to do so. Otherwise, if the controller has any non-empty,
    21  // non-Dead hosted models, then an error with the code
    22  // params.CodeHasHostedModels will be transmitted.
    23  func (c *ControllerAPI) DestroyController(args params.DestroyControllerArgs) error {
    24  	return destroyController(c.state, c.statePool, c.authorizer, args)
    25  }
    26  
    27  func destroyController(
    28  	st Backend,
    29  	pool *state.StatePool,
    30  	authorizer facade.Authorizer,
    31  	args params.DestroyControllerArgs,
    32  ) error {
    33  	err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag())
    34  	if err != nil {
    35  		return errors.Trace(err)
    36  	}
    37  
    38  	if err := ensureNotBlocked(st); err != nil {
    39  		return errors.Trace(err)
    40  	}
    41  
    42  	model, err := st.Model()
    43  	if err != nil {
    44  		return errors.Trace(err)
    45  	}
    46  
    47  	// If we are destroying models, we need to tolerate living
    48  	// models but set the controller to dying to prevent new
    49  	// models sneaking in. If we are not destroying hosted models,
    50  	// this will fail if any hosted models are found.
    51  	backend := common.NewModelManagerBackend(model, pool)
    52  	return errors.Trace(common.DestroyController(
    53  		backend, args.DestroyModels, args.DestroyStorage,
    54  		args.Force, args.MaxWait, args.ModelTimeout,
    55  	))
    56  }
    57  
    58  func ensureNotBlocked(st Backend) error {
    59  	// If there are blocks let the user know.
    60  	blocks, err := st.AllBlocksForController()
    61  	if err != nil {
    62  		logger.Debugf("Unable to get blocks for controller: %s", err)
    63  		return errors.Trace(err)
    64  	}
    65  	if len(blocks) > 0 {
    66  		return apiservererrors.OperationBlockedError("found blocks in controller models")
    67  	}
    68  	return nil
    69  }