Skip to content

Commit 861663d

Browse files
Added integration tests for Private Image Sharing (#831)
* Fixes and added integration tests * Separate ImageShareEntry struct and address PR comments * Fix lint * Addressed PR comments * Reran GetMonthlyTransfer fixture
1 parent 77cd445 commit 861663d

12 files changed

+2689
-361
lines changed

image_sharegroups_consumer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,10 @@ func (c *Client) ImageShareGroupGetByToken(ctx context.Context, tokenUUID string
196196
)
197197
}
198198

199-
// ImageShareGroupGetImagesByToken lists the images in the ImageShareGroup that the
199+
// ImageShareGroupGetImageShareEntriesByToken lists the im_ImageShare entriess in the ImageShareGroup that the
200200
// consumer's specified token has been accepted into.
201-
func (c *Client) ImageShareGroupGetImagesByToken(ctx context.Context, tokenUUID string, opts *ListOptions) ([]Image, error) {
202-
return getPaginatedResults[Image](
201+
func (c *Client) ImageShareGroupGetImageShareEntriesByToken(ctx context.Context, tokenUUID string, opts *ListOptions) ([]ImageShareEntry, error) {
202+
return getPaginatedResults[ImageShareEntry](
203203
ctx,
204204
c,
205205
formatAPIPath("images/sharegroups/tokens/%s/sharegroup/images", tokenUUID),

image_sharegroups_producer.go

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ type ImageShareGroupUpdateImageOptions struct {
7373

7474
// ImageShareGroupImage represents an Image to be included in a ProducerImageShareGroup.
7575
type ImageShareGroupImage struct {
76-
ImageID string `json:"image_id"`
76+
ID string `json:"id"`
7777
Label *string `json:"label,omitempty"`
7878
Description *string `json:"description,omitempty"`
7979
}
@@ -142,13 +142,13 @@ func (c *Client) ListImageShareGroups(
142142
// the given private image is present.
143143
func (c *Client) ListImageShareGroupsContainingPrivateImage(
144144
ctx context.Context,
145-
privateImageID int,
145+
privateImageID string,
146146
opts *ListOptions,
147147
) ([]ProducerImageShareGroup, error) {
148148
return getPaginatedResults[ProducerImageShareGroup](
149149
ctx,
150150
c,
151-
formatAPIPath("images/%d/sharegroups", privateImageID),
151+
formatAPIPath("images/%s/sharegroups", privateImageID),
152152
opts,
153153
)
154154
}
@@ -201,13 +201,13 @@ func (c *Client) DeleteImageShareGroup(ctx context.Context, imageShareGroupID in
201201
)
202202
}
203203

204-
// ImageShareGroupListImages lists the Images in a specified ImageShareGroup owned by the producer.
205-
func (c *Client) ImageShareGroupListImages(
204+
// ImageShareGroupListImageShareEntries lists the im_ImageShare entries of a specified ImageShareGroup owned by the producer.
205+
func (c *Client) ImageShareGroupListImageShareEntries(
206206
ctx context.Context,
207207
imageShareGroupID int,
208208
opts *ListOptions,
209-
) ([]Image, error) {
210-
return getPaginatedResults[Image](
209+
) ([]ImageShareEntry, error) {
210+
return getPaginatedResults[ImageShareEntry](
211211
ctx,
212212
c,
213213
formatAPIPath("images/sharegroups/%d/images", imageShareGroupID),
@@ -220,28 +220,24 @@ func (c *Client) ImageShareGroupAddImages(
220220
ctx context.Context,
221221
imageShareGroupID int,
222222
opts ImageShareGroupAddImagesOptions,
223-
) ([]Image, error) {
224-
response, err := doPOSTRequest[[]Image](
223+
) ([]ImageShareEntry, error) {
224+
return postPaginatedResults[ImageShareEntry, ImageShareGroupAddImagesOptions](
225225
ctx,
226226
c,
227227
formatAPIPath("images/sharegroups/%d/images", imageShareGroupID),
228+
nil,
228229
opts,
229230
)
230-
if err != nil {
231-
return nil, err
232-
}
233-
234-
return *response, nil
235231
}
236232

237-
// ImageShareGroupUpdateImage allows the producer to update the specified Image's description and label within an ImageShareGroup.
238-
func (c *Client) ImageShareGroupUpdateImage(
233+
// ImageShareGroupUpdateImageShareEntry allows the producer to update the description and label of a specified ImageShareEntry within the specified ImageShareGroup.
234+
func (c *Client) ImageShareGroupUpdateImageShareEntry(
239235
ctx context.Context,
240236
imageShareGroupID int,
241237
imageID string,
242238
opts ImageShareGroupUpdateImageOptions,
243-
) (*Image, error) {
244-
return doPUTRequest[Image](
239+
) (*ImageShareEntry, error) {
240+
return doPUTRequest[ImageShareEntry](
245241
ctx,
246242
c,
247243
formatAPIPath("images/sharegroups/%d/images/%s", imageShareGroupID, imageID),

images.go

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ type ImageRegion struct {
4343
// Image represents a deployable Image object for use with Linode Instances
4444
type Image struct {
4545
ID string `json:"id"`
46-
CreatedBy *string `json:"created_by"`
46+
CreatedBy string `json:"created_by"`
4747
Capabilities []string `json:"capabilities"`
4848
Label string `json:"label"`
4949
Description string `json:"description"`
5050
Type string `json:"type"`
51-
Vendor *string `json:"vendor"`
51+
Vendor string `json:"vendor"`
5252
Status ImageStatus `json:"status"`
5353
Size int `json:"size"`
5454
TotalSize int `json:"total_size"`
5555
IsPublic bool `json:"is_public"`
56-
IsShared *bool `json:"is_shared"`
56+
IsShared bool `json:"is_shared"`
5757
Deprecated bool `json:"deprecated"`
5858
Regions []ImageRegion `json:"regions"`
5959
Tags []string `json:"tags"`
@@ -72,8 +72,8 @@ type ImageSharing struct {
7272
}
7373

7474
type ImageSharingSharedWith struct {
75-
ShareGroupCount int `json:"sharegroup_count"`
76-
ImageShareGroupListURL string `json:"image_sharegroup_list_url"`
75+
ShareGroupCount int `json:"sharegroup_count"`
76+
ShareGroupListURL string `json:"sharegroup_list_url"`
7777
}
7878

7979
type ImageSharingSharedBy struct {
@@ -83,6 +83,32 @@ type ImageSharingSharedBy struct {
8383
SourceImageID *string `json:"source_image_id"`
8484
}
8585

86+
// ImageShareEntry represents a row in the im_ImageShare entries for an ImageShareGroup
87+
type ImageShareEntry struct {
88+
ID string `json:"id"`
89+
CreatedBy *string `json:"created_by"`
90+
Capabilities []string `json:"capabilities"`
91+
Label string `json:"label"`
92+
Description string `json:"description"`
93+
Type string `json:"type"`
94+
Vendor *string `json:"vendor"`
95+
Status ImageStatus `json:"status"`
96+
Size int `json:"size"`
97+
TotalSize int `json:"total_size"`
98+
IsPublic bool `json:"is_public"`
99+
IsShared *bool `json:"is_shared"`
100+
Deprecated bool `json:"deprecated"`
101+
Regions []ImageRegion `json:"regions"`
102+
Tags []string `json:"tags"`
103+
104+
Updated *time.Time `json:"-"`
105+
Created *time.Time `json:"-"`
106+
Expiry *time.Time `json:"-"`
107+
EOL *time.Time `json:"-"`
108+
109+
ImageSharing ImageSharing `json:"image_sharing"`
110+
}
111+
86112
// ImageCreateOptions fields are those accepted by CreateImage
87113
type ImageCreateOptions struct {
88114
DiskID int `json:"disk_id"`
@@ -157,6 +183,33 @@ func (i *Image) UnmarshalJSON(b []byte) error {
157183
return nil
158184
}
159185

186+
// UnmarshalJSON implements the json.Unmarshaler interface
187+
func (ise *ImageShareEntry) UnmarshalJSON(b []byte) error {
188+
type Mask ImageShareEntry
189+
190+
p := struct {
191+
*Mask
192+
193+
Updated *parseabletime.ParseableTime `json:"updated"`
194+
Created *parseabletime.ParseableTime `json:"created"`
195+
Expiry *parseabletime.ParseableTime `json:"expiry"`
196+
EOL *parseabletime.ParseableTime `json:"eol"`
197+
}{
198+
Mask: (*Mask)(ise),
199+
}
200+
201+
if err := json.Unmarshal(b, &p); err != nil {
202+
return err
203+
}
204+
205+
ise.Updated = (*time.Time)(p.Updated)
206+
ise.Created = (*time.Time)(p.Created)
207+
ise.Expiry = (*time.Time)(p.Expiry)
208+
ise.EOL = (*time.Time)(p.EOL)
209+
210+
return nil
211+
}
212+
160213
// GetUpdateOptions converts an Image to ImageUpdateOptions for use in UpdateImage
161214
func (i Image) GetUpdateOptions() (iu ImageUpdateOptions) {
162215
iu.Label = i.Label

request_helpers.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ func handlePaginatedResults[T any, O any](
9393
return err
9494
}
9595

96+
response = res.Result().(*paginatedResponse[T])
97+
case "POST":
98+
res, err := coupleAPIErrors(req.Post(endpoint))
99+
if err != nil {
100+
return err
101+
}
102+
96103
response = res.Result().(*paginatedResponse[T])
97104
default:
98105
return fmt.Errorf("unsupported HTTP method: %s", method)
@@ -159,6 +166,18 @@ func putPaginatedResults[T, O any](
159166
return handlePaginatedResults[T, O](ctx, client, endpoint, opts, "PUT", options...)
160167
}
161168

169+
// postPaginatedResults sends a POST request and aggregates the results from the given
170+
// paginated endpoint using the provided ListOptions.
171+
func postPaginatedResults[T, O any](
172+
ctx context.Context,
173+
client *Client,
174+
endpoint string,
175+
opts *ListOptions,
176+
options ...O,
177+
) ([]T, error) {
178+
return handlePaginatedResults[T, O](ctx, client, endpoint, opts, "POST", options...)
179+
}
180+
162181
// doGETRequest runs a GET request using the given client and API endpoint,
163182
// and returns the result
164183
func doGETRequest[T any](

0 commit comments

Comments
 (0)