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