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  }