github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/imagemanager/imagemanager.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package imagemanager 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/loggo" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/facade" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/permission" 14 "github.com/juju/juju/state" 15 "github.com/juju/juju/state/imagestorage" 16 ) 17 18 var logger = loggo.GetLogger("juju.apiserver.imagemanager") 19 20 func init() { 21 common.RegisterStandardFacade("ImageManager", 2, NewImageManagerAPI) 22 } 23 24 // ImageManager defines the methods on the imagemanager API end point. 25 type ImageManager interface { 26 ListImages(arg params.ImageFilterParams) (params.ListImageResult, error) 27 DeleteImages(arg params.ImageFilterParams) (params.ErrorResults, error) 28 } 29 30 // ImageManagerAPI implements the ImageManager interface and is the concrete 31 // implementation of the api end point. 32 type ImageManagerAPI struct { 33 state stateInterface 34 resources facade.Resources 35 authorizer facade.Authorizer 36 check *common.BlockChecker 37 } 38 39 var _ ImageManager = (*ImageManagerAPI)(nil) 40 41 var getState = func(st *state.State) stateInterface { 42 return stateShim{st} 43 } 44 45 // NewImageManagerAPI creates a new server-side imagemanager API end point. 46 func NewImageManagerAPI(st *state.State, resources facade.Resources, authorizer facade.Authorizer) (*ImageManagerAPI, error) { 47 // Only clients can access the image manager service. 48 if !authorizer.AuthClient() { 49 return nil, common.ErrPerm 50 } 51 return &ImageManagerAPI{ 52 state: getState(st), 53 resources: resources, 54 authorizer: authorizer, 55 check: common.NewBlockChecker(st), 56 }, nil 57 } 58 59 // ListImages returns images matching the specified filter. 60 func (api *ImageManagerAPI) ListImages(arg params.ImageFilterParams) (params.ListImageResult, error) { 61 var result params.ListImageResult 62 admin, err := api.authorizer.HasPermission(permission.SuperuserAccess, api.state.ControllerTag()) 63 if err != nil { 64 return result, errors.Trace(err) 65 } 66 if !admin { 67 return result, common.ServerError(common.ErrPerm) 68 } 69 70 if len(arg.Images) > 1 { 71 return result, errors.New("image filter with multiple terms not supported") 72 } 73 filter := imagestorage.ImageFilter{} 74 if len(arg.Images) == 1 { 75 filter = imagestorage.ImageFilter{ 76 Kind: arg.Images[0].Kind, 77 Series: arg.Images[0].Series, 78 Arch: arg.Images[0].Arch, 79 } 80 } 81 stor := api.state.ImageStorage() 82 metadata, err := stor.ListImages(filter) 83 if err != nil { 84 return result, nil 85 } 86 result.Result = make([]params.ImageMetadata, len(metadata)) 87 for i, m := range metadata { 88 result.Result[i] = params.ImageMetadata{ 89 Kind: m.Kind, 90 Series: m.Series, 91 Arch: m.Arch, 92 URL: m.SourceURL, 93 Created: m.Created, 94 } 95 } 96 return result, nil 97 } 98 99 // DeleteImages deletes the images matching the specified filter. 100 func (api *ImageManagerAPI) DeleteImages(arg params.ImageFilterParams) (params.ErrorResults, error) { 101 var result params.ErrorResults 102 admin, err := api.authorizer.HasPermission(permission.SuperuserAccess, api.state.ControllerTag()) 103 if err != nil { 104 return result, errors.Trace(err) 105 } 106 if !admin { 107 return result, common.ServerError(common.ErrPerm) 108 } 109 110 if err := api.check.ChangeAllowed(); err != nil { 111 return params.ErrorResults{}, errors.Trace(err) 112 } 113 114 result.Results = make([]params.ErrorResult, len(arg.Images)) 115 stor := api.state.ImageStorage() 116 for i, imageSpec := range arg.Images { 117 filter := imagestorage.ImageFilter{ 118 Kind: imageSpec.Kind, 119 Series: imageSpec.Series, 120 Arch: imageSpec.Arch, 121 } 122 imageMetadata, err := stor.ListImages(filter) 123 if err != nil { 124 result.Results[i].Error = common.ServerError(err) 125 continue 126 } 127 if len(imageMetadata) != 1 { 128 result.Results[i].Error = common.ServerError( 129 errors.NotFoundf("image %s/%s/%s", filter.Kind, filter.Series, filter.Arch)) 130 continue 131 } 132 logger.Infof("deleting image with metadata %+v", *imageMetadata[0]) 133 err = stor.DeleteImage(imageMetadata[0]) 134 if err != nil { 135 result.Results[i].Error = common.ServerError(err) 136 } 137 } 138 return result, nil 139 }