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