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