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 }