github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/annotations/client.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package annotations
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  
    10  	"github.com/juju/juju/apiserver/common"
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/state"
    13  )
    14  
    15  func init() {
    16  	common.RegisterStandardFacade("Annotations", 2, NewAPI)
    17  }
    18  
    19  var getState = func(st *state.State) annotationAccess {
    20  	return stateShim{st}
    21  }
    22  
    23  // Annotations defines the methods on the service API end point.
    24  type Annotations interface {
    25  	Get(args params.Entities) params.AnnotationsGetResults
    26  	Set(args params.AnnotationsSet) params.ErrorResults
    27  }
    28  
    29  // API implements the service interface and is the concrete
    30  // implementation of the api end point.
    31  type API struct {
    32  	access     annotationAccess
    33  	authorizer common.Authorizer
    34  }
    35  
    36  // NewAPI returns a new charm annotator API facade.
    37  func NewAPI(
    38  	st *state.State,
    39  	resources *common.Resources,
    40  	authorizer common.Authorizer,
    41  ) (*API, error) {
    42  	if !authorizer.AuthClient() {
    43  		return nil, common.ErrPerm
    44  	}
    45  
    46  	return &API{
    47  		access:     getState(st),
    48  		authorizer: authorizer,
    49  	}, nil
    50  }
    51  
    52  // Get returns annotations for given entities.
    53  // If annotations cannot be retrieved for a given entity, an error is returned.
    54  // Each entity is treated independently and, hence, will fail or succeed independently.
    55  func (api *API) Get(args params.Entities) params.AnnotationsGetResults {
    56  	entityResults := []params.AnnotationsGetResult{}
    57  	for _, entity := range args.Entities {
    58  		anEntityResult := params.AnnotationsGetResult{EntityTag: entity.Tag}
    59  		if annts, err := api.getEntityAnnotations(entity.Tag); err != nil {
    60  			anEntityResult.Error = params.ErrorResult{annotateError(err, entity.Tag, "getting")}
    61  		} else {
    62  			anEntityResult.Annotations = annts
    63  		}
    64  		entityResults = append(entityResults, anEntityResult)
    65  	}
    66  	return params.AnnotationsGetResults{Results: entityResults}
    67  }
    68  
    69  // Set stores annotations for given entities
    70  func (api *API) Set(args params.AnnotationsSet) params.ErrorResults {
    71  	setErrors := []params.ErrorResult{}
    72  	for _, entityAnnotation := range args.Annotations {
    73  		err := api.setEntityAnnotations(entityAnnotation.EntityTag, entityAnnotation.Annotations)
    74  		if err != nil {
    75  			setErrors = append(setErrors,
    76  				params.ErrorResult{Error: annotateError(err, entityAnnotation.EntityTag, "setting")})
    77  		}
    78  	}
    79  	return params.ErrorResults{Results: setErrors}
    80  }
    81  
    82  func annotateError(err error, tag, op string) *params.Error {
    83  	return common.ServerError(
    84  		errors.Trace(
    85  			errors.Annotatef(
    86  				err, "while %v annotations to %q", op, tag)))
    87  }
    88  
    89  func (api *API) getEntityAnnotations(entityTag string) (map[string]string, error) {
    90  	tag, err := names.ParseTag(entityTag)
    91  	if err != nil {
    92  		return nil, errors.Trace(err)
    93  	}
    94  	entity, err := api.findEntity(tag)
    95  	if err != nil {
    96  		return nil, errors.Trace(err)
    97  	}
    98  	annotations, err := api.access.GetAnnotations(entity)
    99  	if err != nil {
   100  		return nil, errors.Trace(err)
   101  	}
   102  	return annotations, nil
   103  }
   104  
   105  func (api *API) findEntity(tag names.Tag) (state.GlobalEntity, error) {
   106  	entity0, err := api.access.FindEntity(tag)
   107  	if err != nil {
   108  		if errors.IsNotFound(err) {
   109  			return nil, common.ErrPerm
   110  		}
   111  		return nil, err
   112  	}
   113  	entity, ok := entity0.(state.GlobalEntity)
   114  	if !ok {
   115  		return nil, common.NotSupportedError(tag, "annotations")
   116  	}
   117  	return entity, nil
   118  }
   119  
   120  func (api *API) setEntityAnnotations(entityTag string, annotations map[string]string) error {
   121  	tag, err := names.ParseTag(entityTag)
   122  	if err != nil {
   123  		return errors.Trace(err)
   124  	}
   125  	entity, err := api.findEntity(tag)
   126  	if err != nil {
   127  		return errors.Trace(err)
   128  	}
   129  	return api.access.SetAnnotations(entity, annotations)
   130  }