github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/remove.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/names.v2" 11 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/state" 14 ) 15 16 // Remover implements a common Remove method for use by various facades. 17 type Remover struct { 18 st state.EntityFinder 19 callEnsureDead bool 20 getCanModify GetAuthFunc 21 } 22 23 // NewRemover returns a new Remover. The callEnsureDead flag specifies 24 // whether EnsureDead should be called on an entity before 25 // removing. The GetAuthFunc will be used on each invocation of Remove 26 // to determine current permissions. 27 func NewRemover(st state.EntityFinder, callEnsureDead bool, getCanModify GetAuthFunc) *Remover { 28 return &Remover{ 29 st: st, 30 callEnsureDead: callEnsureDead, 31 getCanModify: getCanModify, 32 } 33 } 34 35 func (r *Remover) removeEntity(tag names.Tag) error { 36 entity, err := r.st.FindEntity(tag) 37 if err != nil { 38 return err 39 } 40 remover, ok := entity.(interface { 41 state.Lifer 42 state.Remover 43 state.EnsureDeader 44 }) 45 if !ok { 46 return NotSupportedError(tag, "removal") 47 } 48 // Only remove entites that are not Alive. 49 if life := remover.Life(); life == state.Alive { 50 return fmt.Errorf("cannot remove entity %q: still alive", tag.String()) 51 } 52 if r.callEnsureDead { 53 if err := remover.EnsureDead(); err != nil { 54 return err 55 } 56 } 57 return remover.Remove() 58 } 59 60 // Remove removes every given entity from state, calling EnsureDead 61 // first, then Remove. It will fail if the entity is not present. 62 func (r *Remover) Remove(args params.Entities) (params.ErrorResults, error) { 63 result := params.ErrorResults{ 64 Results: make([]params.ErrorResult, len(args.Entities)), 65 } 66 if len(args.Entities) == 0 { 67 return result, nil 68 } 69 canModify, err := r.getCanModify() 70 if err != nil { 71 return params.ErrorResults{}, errors.Trace(err) 72 } 73 for i, entity := range args.Entities { 74 tag, err := names.ParseTag(entity.Tag) 75 if err != nil { 76 result.Results[i].Error = ServerError(ErrPerm) 77 continue 78 } 79 err = ErrPerm 80 if canModify(tag) { 81 err = r.removeEntity(tag) 82 } 83 result.Results[i].Error = ServerError(err) 84 } 85 return result, nil 86 }