github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/resource/api/helpers.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package api
     5  
     6  // TODO(ericsnow) Eliminate the dependence on apiserver if possible.
     7  
     8  import (
     9  	"github.com/juju/errors"
    10  	charmresource "gopkg.in/juju/charm.v6-unstable/resource"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/resource"
    16  )
    17  
    18  // Resource2API converts a resource.Resource into
    19  // a Resource struct.
    20  func Resource2API(res resource.Resource) Resource {
    21  	return Resource{
    22  		CharmResource: CharmResource2API(res.Resource),
    23  		ID:            res.ID,
    24  		PendingID:     res.PendingID,
    25  		ApplicationID: res.ApplicationID,
    26  		Username:      res.Username,
    27  		Timestamp:     res.Timestamp,
    28  	}
    29  }
    30  
    31  // APIResult2ServiceResources converts a ResourcesResult into a resource.ServiceResources.
    32  func APIResult2ServiceResources(apiResult ResourcesResult) (resource.ServiceResources, error) {
    33  	var result resource.ServiceResources
    34  
    35  	if apiResult.Error != nil {
    36  		// TODO(ericsnow) Return the resources too?
    37  		err := common.RestoreError(apiResult.Error)
    38  		return resource.ServiceResources{}, errors.Trace(err)
    39  	}
    40  
    41  	for _, apiRes := range apiResult.Resources {
    42  		res, err := API2Resource(apiRes)
    43  		if err != nil {
    44  			// This could happen if the server is misbehaving
    45  			// or non-conforming.
    46  			// TODO(ericsnow) Aggregate errors?
    47  			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
    48  		}
    49  		result.Resources = append(result.Resources, res)
    50  	}
    51  
    52  	for _, unitRes := range apiResult.UnitResources {
    53  		tag, err := names.ParseUnitTag(unitRes.Tag)
    54  		if err != nil {
    55  			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
    56  		}
    57  		resNames := map[string]bool{}
    58  		unitResources := resource.UnitResources{Tag: tag}
    59  		for _, apiRes := range unitRes.Resources {
    60  			res, err := API2Resource(apiRes)
    61  			if err != nil {
    62  				return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
    63  			}
    64  			resNames[res.Name] = true
    65  			unitResources.Resources = append(unitResources.Resources, res)
    66  		}
    67  		if len(unitRes.DownloadProgress) > 0 {
    68  			unitResources.DownloadProgress = make(map[string]int64)
    69  			for resName, progress := range unitRes.DownloadProgress {
    70  				if _, ok := resNames[resName]; !ok {
    71  					err := errors.Errorf("got progress from unrecognized resource %q", resName)
    72  					return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
    73  				}
    74  				unitResources.DownloadProgress[resName] = progress
    75  			}
    76  		}
    77  		result.UnitResources = append(result.UnitResources, unitResources)
    78  	}
    79  
    80  	for _, chRes := range apiResult.CharmStoreResources {
    81  		res, err := API2CharmResource(chRes)
    82  		if err != nil {
    83  			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
    84  		}
    85  		result.CharmStoreResources = append(result.CharmStoreResources, res)
    86  	}
    87  
    88  	return result, nil
    89  }
    90  
    91  func ServiceResources2APIResult(svcRes resource.ServiceResources) ResourcesResult {
    92  	var result ResourcesResult
    93  	for _, res := range svcRes.Resources {
    94  		result.Resources = append(result.Resources, Resource2API(res))
    95  	}
    96  
    97  	for _, unitResources := range svcRes.UnitResources {
    98  		tag := unitResources.Tag
    99  		apiRes := UnitResources{
   100  			Entity: params.Entity{Tag: tag.String()},
   101  		}
   102  		for _, unitRes := range unitResources.Resources {
   103  			apiRes.Resources = append(apiRes.Resources, Resource2API(unitRes))
   104  		}
   105  		if len(unitResources.DownloadProgress) > 0 {
   106  			apiRes.DownloadProgress = make(map[string]int64)
   107  			for resName, progress := range unitResources.DownloadProgress {
   108  				apiRes.DownloadProgress[resName] = progress
   109  			}
   110  		}
   111  		result.UnitResources = append(result.UnitResources, apiRes)
   112  	}
   113  
   114  	result.CharmStoreResources = make([]CharmResource, len(svcRes.CharmStoreResources))
   115  	for i, chRes := range svcRes.CharmStoreResources {
   116  		result.CharmStoreResources[i] = CharmResource2API(chRes)
   117  	}
   118  	return result
   119  }
   120  
   121  // API2Resource converts an API Resource struct into
   122  // a resource.Resource.
   123  func API2Resource(apiRes Resource) (resource.Resource, error) {
   124  	var res resource.Resource
   125  
   126  	charmRes, err := API2CharmResource(apiRes.CharmResource)
   127  	if err != nil {
   128  		return res, errors.Trace(err)
   129  	}
   130  
   131  	res = resource.Resource{
   132  		Resource:      charmRes,
   133  		ID:            apiRes.ID,
   134  		PendingID:     apiRes.PendingID,
   135  		ApplicationID: apiRes.ApplicationID,
   136  		Username:      apiRes.Username,
   137  		Timestamp:     apiRes.Timestamp,
   138  	}
   139  
   140  	if err := res.Validate(); err != nil {
   141  		return res, errors.Trace(err)
   142  	}
   143  
   144  	return res, nil
   145  }
   146  
   147  // CharmResource2API converts a charm resource into
   148  // a CharmResource struct.
   149  func CharmResource2API(res charmresource.Resource) CharmResource {
   150  	return CharmResource{
   151  		Name:        res.Name,
   152  		Type:        res.Type.String(),
   153  		Path:        res.Path,
   154  		Description: res.Description,
   155  		Origin:      res.Origin.String(),
   156  		Revision:    res.Revision,
   157  		Fingerprint: res.Fingerprint.Bytes(),
   158  		Size:        res.Size,
   159  	}
   160  }
   161  
   162  // API2CharmResource converts an API CharmResource struct into
   163  // a charm resource.
   164  func API2CharmResource(apiInfo CharmResource) (charmresource.Resource, error) {
   165  	var res charmresource.Resource
   166  
   167  	rtype, err := charmresource.ParseType(apiInfo.Type)
   168  	if err != nil {
   169  		return res, errors.Trace(err)
   170  	}
   171  
   172  	origin, err := charmresource.ParseOrigin(apiInfo.Origin)
   173  	if err != nil {
   174  		return res, errors.Trace(err)
   175  	}
   176  
   177  	fp, err := resource.DeserializeFingerprint(apiInfo.Fingerprint)
   178  	if err != nil {
   179  		return res, errors.Trace(err)
   180  	}
   181  
   182  	res = charmresource.Resource{
   183  		Meta: charmresource.Meta{
   184  			Name:        apiInfo.Name,
   185  			Type:        rtype,
   186  			Path:        apiInfo.Path,
   187  			Description: apiInfo.Description,
   188  		},
   189  		Origin:      origin,
   190  		Revision:    apiInfo.Revision,
   191  		Fingerprint: fp,
   192  		Size:        apiInfo.Size,
   193  	}
   194  
   195  	if err := res.Validate(); err != nil {
   196  		return res, errors.Trace(err)
   197  	}
   198  	return res, nil
   199  }