github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/apiserver/imagemetadata/metadata.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package imagemetadata
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/juju/apiserver/common"
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/state/cloudimagemetadata"
    14  )
    15  
    16  func init() {
    17  	common.RegisterStandardFacade("ImageMetadata", 1, NewAPI)
    18  }
    19  
    20  // API is the concrete implementation of the api end point
    21  // for loud image metadata manipulations.
    22  type API struct {
    23  	metadata   metadataAcess
    24  	authorizer common.Authorizer
    25  }
    26  
    27  // createAPI returns a new image metadata API facade.
    28  func createAPI(
    29  	st metadataAcess,
    30  	resources *common.Resources,
    31  	authorizer common.Authorizer,
    32  ) (*API, error) {
    33  	if !authorizer.AuthClient() && !authorizer.AuthEnvironManager() {
    34  		return nil, common.ErrPerm
    35  	}
    36  
    37  	return &API{
    38  		metadata:   st,
    39  		authorizer: authorizer,
    40  	}, nil
    41  }
    42  
    43  // NewAPI returns a new cloud image metadata API facade.
    44  func NewAPI(
    45  	st *state.State,
    46  	resources *common.Resources,
    47  	authorizer common.Authorizer,
    48  ) (*API, error) {
    49  	return createAPI(getState(st), resources, authorizer)
    50  }
    51  
    52  // List returns all found cloud image metadata that satisfy
    53  // given filter.
    54  // Returned list contains metadata for custom images first, then public.
    55  func (api *API) List(filter params.ImageMetadataFilter) (params.ListCloudImageMetadataResult, error) {
    56  	found, err := api.metadata.FindMetadata(cloudimagemetadata.MetadataFilter{
    57  		Region:          filter.Region,
    58  		Series:          filter.Series,
    59  		Arches:          filter.Arches,
    60  		Stream:          filter.Stream,
    61  		VirtualType:     filter.VirtualType,
    62  		RootStorageType: filter.RootStorageType,
    63  	})
    64  	if err != nil {
    65  		return params.ListCloudImageMetadataResult{}, common.ServerError(err)
    66  	}
    67  
    68  	var all []params.CloudImageMetadata
    69  	addAll := func(ms []cloudimagemetadata.Metadata) {
    70  		for _, m := range ms {
    71  			all = append(all, parseMetadataToParams(m))
    72  		}
    73  	}
    74  
    75  	// First return metadata for custom images, then public.
    76  	// No other source for cloud images should exist at the moment.
    77  	// Once new source is identified, the order of returned metadata
    78  	// may need to be changed.
    79  	addAll(found[cloudimagemetadata.Custom])
    80  	addAll(found[cloudimagemetadata.Public])
    81  
    82  	return params.ListCloudImageMetadataResult{Result: all}, nil
    83  }
    84  
    85  // Save stores given cloud image metadata.
    86  // It supports bulk calls.
    87  func (api *API) Save(metadata params.MetadataSaveParams) (params.ErrorResults, error) {
    88  	all := make([]params.ErrorResult, len(metadata.Metadata))
    89  	for i, one := range metadata.Metadata {
    90  		err := api.metadata.SaveMetadata(parseMetadataFromParams(one))
    91  		all[i] = params.ErrorResult{Error: common.ServerError(err)}
    92  	}
    93  	return params.ErrorResults{Results: all}, nil
    94  }
    95  
    96  func parseMetadataToParams(p cloudimagemetadata.Metadata) params.CloudImageMetadata {
    97  	result := params.CloudImageMetadata{
    98  		ImageId:         p.ImageId,
    99  		Stream:          p.Stream,
   100  		Region:          p.Region,
   101  		Series:          p.Series,
   102  		Arch:            p.Arch,
   103  		VirtualType:     p.VirtualType,
   104  		RootStorageType: p.RootStorageType,
   105  		RootStorageSize: p.RootStorageSize,
   106  		Source:          string(p.Source),
   107  	}
   108  	return result
   109  }
   110  
   111  func parseMetadataFromParams(p params.CloudImageMetadata) cloudimagemetadata.Metadata {
   112  
   113  	parseSource := func(s string) cloudimagemetadata.SourceType {
   114  		switch cloudimagemetadata.SourceType(strings.ToLower(s)) {
   115  		case cloudimagemetadata.Public:
   116  			return cloudimagemetadata.Public
   117  		case cloudimagemetadata.Custom:
   118  			return cloudimagemetadata.Custom
   119  		default:
   120  			panic(fmt.Sprintf("unknown cloud image metadata source %q", s))
   121  		}
   122  	}
   123  
   124  	result := cloudimagemetadata.Metadata{
   125  		cloudimagemetadata.MetadataAttributes{
   126  			Stream:          p.Stream,
   127  			Region:          p.Region,
   128  			Series:          p.Series,
   129  			Arch:            p.Arch,
   130  			VirtualType:     p.VirtualType,
   131  			RootStorageType: p.RootStorageType,
   132  			RootStorageSize: p.RootStorageSize,
   133  			Source:          parseSource(p.Source),
   134  		},
   135  		p.ImageId,
   136  	}
   137  	if p.Stream == "" {
   138  		result.Stream = "released"
   139  	}
   140  	return result
   141  }