Beispiel #1
0
// ServerError returns an error suitable for returning to an API
// client, with an error code suitable for various kinds of errors
// generated in packages outside the API.
func ServerError(err error) *params.Error {
	if err == nil {
		return nil
	}
	logger.Tracef("server RPC error %v", errors.Details(err))
	msg := err.Error()
	// Skip past annotations when looking for the code.
	err = errors.Cause(err)
	code, ok := singletonCode(err)
	var info *params.ErrorInfo
	switch {
	case ok:
	case errors.IsUnauthorized(err):
		code = params.CodeUnauthorized
	case errors.IsNotFound(err):
		code = params.CodeNotFound
	case errors.IsUserNotFound(err):
		code = params.CodeUserNotFound
	case errors.IsAlreadyExists(err):
		code = params.CodeAlreadyExists
	case errors.IsNotAssigned(err):
		code = params.CodeNotAssigned
	case state.IsHasAssignedUnitsError(err):
		code = params.CodeHasAssignedUnits
	case state.IsHasHostedModelsError(err):
		code = params.CodeHasHostedModels
	case isNoAddressSetError(err):
		code = params.CodeNoAddressSet
	case errors.IsNotProvisioned(err):
		code = params.CodeNotProvisioned
	case IsUpgradeInProgressError(err):
		code = params.CodeUpgradeInProgress
	case state.IsHasAttachmentsError(err):
		code = params.CodeMachineHasAttachedStorage
	case isUnknownModelError(err):
		code = params.CodeModelNotFound
	case errors.IsNotSupported(err):
		code = params.CodeNotSupported
	case errors.IsBadRequest(err):
		code = params.CodeBadRequest
	case errors.IsMethodNotAllowed(err):
		code = params.CodeMethodNotAllowed
	default:
		if err, ok := err.(*DischargeRequiredError); ok {
			code = params.CodeDischargeRequired
			info = &params.ErrorInfo{
				Macaroon: err.Macaroon,
				// One macaroon fits all.
				MacaroonPath: "/",
			}
			break
		}
		code = params.ErrCode(err)
	}
	return &params.Error{
		Message: msg,
		Code:    code,
		Info:    info,
	}
}
Beispiel #2
0
// DestroyController will attempt to destroy the controller. If the args
// specify the removal of blocks or the destruction of the models, this
// method will attempt to do so.
func (s *ControllerAPI) DestroyController(args params.DestroyControllerArgs) error {
	controllerEnv, err := s.state.ControllerModel()
	if err != nil {
		return errors.Trace(err)
	}
	systemTag := controllerEnv.ModelTag()

	if err = s.ensureNotBlocked(args); err != nil {
		return errors.Trace(err)
	}

	// If we are destroying models, we need to tolerate living
	// models but set the controller to dying to prevent new
	// models sneaking in. If we are not destroying hosted models,
	// this will fail if any hosted models are found.
	if args.DestroyModels {
		return errors.Trace(common.DestroyModelIncludingHosted(s.state, systemTag))
	}
	if err = common.DestroyModel(s.state, systemTag); state.IsHasHostedModelsError(err) {
		err = errors.New("controller model cannot be destroyed before all other models are destroyed")
	}
	return errors.Trace(err)
}