github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/block/client.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package block
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/apiserver/common"
    10  	"github.com/juju/juju/apiserver/facade"
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/permission"
    13  	"github.com/juju/juju/state"
    14  )
    15  
    16  // Block defines the methods on the block API end point.
    17  type Block interface {
    18  	// List returns all current blocks for this model.
    19  	List() (params.BlockResults, error)
    20  
    21  	// SwitchBlockOn switches desired block type on for this
    22  	// model.
    23  	SwitchBlockOn(params.BlockSwitchParams) params.ErrorResult
    24  
    25  	// SwitchBlockOff switches desired block type off for this
    26  	// model.
    27  	SwitchBlockOff(params.BlockSwitchParams) params.ErrorResult
    28  }
    29  
    30  // API implements Block interface and is the concrete
    31  // implementation of the api end point.
    32  type API struct {
    33  	access     blockAccess
    34  	authorizer facade.Authorizer
    35  }
    36  
    37  // NewAPI returns a new block API facade.
    38  func NewAPI(
    39  	st *state.State,
    40  	resources facade.Resources,
    41  	authorizer facade.Authorizer,
    42  ) (*API, error) {
    43  
    44  	if !authorizer.AuthClient() {
    45  		return nil, common.ErrPerm
    46  	}
    47  
    48  	m, err := st.Model()
    49  	if err != nil {
    50  		return nil, errors.Trace(err)
    51  	}
    52  
    53  	return &API{
    54  		access:     getState(st, m),
    55  		authorizer: authorizer,
    56  	}, nil
    57  }
    58  
    59  var getState = func(st *state.State, m *state.Model) blockAccess {
    60  	return stateShim{st, m}
    61  }
    62  
    63  func (a *API) checkCanRead() error {
    64  	canRead, err := a.authorizer.HasPermission(permission.ReadAccess, a.access.ModelTag())
    65  	if err != nil && !errors.IsNotFound(err) {
    66  		return errors.Trace(err)
    67  	}
    68  	if !canRead {
    69  		return common.ErrPerm
    70  	}
    71  	return nil
    72  }
    73  
    74  func (a *API) checkCanWrite() error {
    75  	canWrite, err := a.authorizer.HasPermission(permission.WriteAccess, a.access.ModelTag())
    76  	if err != nil && !errors.IsNotFound(err) {
    77  		return errors.Trace(err)
    78  	}
    79  	if !canWrite {
    80  		return common.ErrPerm
    81  	}
    82  	return nil
    83  }
    84  
    85  // List implements Block.List().
    86  func (a *API) List() (params.BlockResults, error) {
    87  	if err := a.checkCanRead(); err != nil {
    88  		return params.BlockResults{}, err
    89  	}
    90  
    91  	all, err := a.access.AllBlocks()
    92  	if err != nil {
    93  		return params.BlockResults{}, common.ServerError(err)
    94  	}
    95  	found := make([]params.BlockResult, len(all))
    96  	for i, one := range all {
    97  		found[i] = convertBlock(one)
    98  	}
    99  	return params.BlockResults{Results: found}, nil
   100  }
   101  
   102  func convertBlock(b state.Block) params.BlockResult {
   103  	result := params.BlockResult{}
   104  	tag, err := b.Tag()
   105  	if err != nil {
   106  		err := errors.Annotatef(err, "getting block %v", b.Type().String())
   107  		result.Error = common.ServerError(err)
   108  	}
   109  	result.Result = params.Block{
   110  		Id:      b.Id(),
   111  		Tag:     tag.String(),
   112  		Type:    b.Type().String(),
   113  		Message: b.Message(),
   114  	}
   115  	return result
   116  }
   117  
   118  // SwitchBlockOn implements Block.SwitchBlockOn().
   119  func (a *API) SwitchBlockOn(args params.BlockSwitchParams) params.ErrorResult {
   120  	if err := a.checkCanWrite(); err != nil {
   121  		return params.ErrorResult{Error: common.ServerError(err)}
   122  	}
   123  
   124  	err := a.access.SwitchBlockOn(state.ParseBlockType(args.Type), args.Message)
   125  	return params.ErrorResult{Error: common.ServerError(err)}
   126  }
   127  
   128  // SwitchBlockOff implements Block.SwitchBlockOff().
   129  func (a *API) SwitchBlockOff(args params.BlockSwitchParams) params.ErrorResult {
   130  	if err := a.checkCanWrite(); err != nil {
   131  		return params.ErrorResult{Error: common.ServerError(err)}
   132  	}
   133  
   134  	err := a.access.SwitchBlockOff(state.ParseBlockType(args.Type))
   135  	return params.ErrorResult{Error: common.ServerError(err)}
   136  }