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 }