Skip to content

Commit e8cd264

Browse files
Added support for Private Image Sharing (#800)
* Added support for Private Image Sharing * Add missing endpoint * Fix lint * Addressed copilot suggestions * Reran monthly transfer fixture * Addressed PR comments * More PR comments
1 parent bcb371a commit e8cd264

27 files changed

+2003
-302
lines changed

image_sharegroups_consumer.go

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package linodego
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"time"
7+
8+
"github.com/linode/linodego/internal/parseabletime"
9+
)
10+
11+
// ConsumerImageShareGroup represents an ImageShareGroup that the consumer is a member of.
12+
type ConsumerImageShareGroup struct {
13+
ID int `json:"id"`
14+
UUID string `json:"uuid"`
15+
Label string `json:"label"`
16+
Description string `json:"description"`
17+
IsSuspended bool `json:"is_suspended"`
18+
Created *time.Time `json:"-"`
19+
Updated *time.Time `json:"-"`
20+
}
21+
22+
// UnmarshalJSON implements the json.Unmarshaler interface
23+
func (isg *ConsumerImageShareGroup) UnmarshalJSON(b []byte) error {
24+
type Mask ConsumerImageShareGroup
25+
26+
p := struct {
27+
*Mask
28+
29+
Created *parseabletime.ParseableTime `json:"created"`
30+
Updated *parseabletime.ParseableTime `json:"updated"`
31+
}{
32+
Mask: (*Mask)(isg),
33+
}
34+
35+
if err := json.Unmarshal(b, &p); err != nil {
36+
return err
37+
}
38+
39+
isg.Created = (*time.Time)(p.Created)
40+
isg.Updated = (*time.Time)(p.Updated)
41+
42+
return nil
43+
}
44+
45+
// ImageShareGroupToken contains information about a token created by a consumer.
46+
// The token itself is only visible once upon creation.
47+
type ImageShareGroupToken struct {
48+
TokenUUID string `json:"token_uuid"`
49+
Status string `json:"status"`
50+
Label string `json:"label"`
51+
ValidForShareGroupUUID string `json:"valid_for_sharegroup_uuid"`
52+
Created *time.Time `json:"-"`
53+
Updated *time.Time `json:"-"`
54+
Expiry *time.Time `json:"-"`
55+
ShareGroupUUID *string `json:"sharegroup_uuid"`
56+
ShareGroupLabel *string `json:"sharegroup_label"`
57+
}
58+
59+
// UnmarshalJSON implements the json.Unmarshaler interface
60+
func (t *ImageShareGroupToken) UnmarshalJSON(b []byte) error {
61+
type Mask ImageShareGroupToken
62+
63+
p := struct {
64+
*Mask
65+
66+
Created *parseabletime.ParseableTime `json:"created"`
67+
Updated *parseabletime.ParseableTime `json:"updated"`
68+
Expiry *parseabletime.ParseableTime `json:"expiry"`
69+
}{
70+
Mask: (*Mask)(t),
71+
}
72+
73+
if err := json.Unmarshal(b, &p); err != nil {
74+
return err
75+
}
76+
77+
t.Created = (*time.Time)(p.Created)
78+
t.Updated = (*time.Time)(p.Updated)
79+
t.Expiry = (*time.Time)(p.Expiry)
80+
81+
return nil
82+
}
83+
84+
// ImageShareGroupCreateTokenResponse represents the response when the consumer
85+
// creates a single-use ImageShareGroup membership token.
86+
// The token itself is only provided upon creation, and must be given to the producer
87+
// via an outside medium for the consumer to be added as a member of the producer's ImageShareGroup.
88+
type ImageShareGroupCreateTokenResponse struct {
89+
Token string `json:"token"`
90+
TokenUUID string `json:"token_uuid"`
91+
Status string `json:"status"`
92+
Label string `json:"label"`
93+
ValidForShareGroupUUID string `json:"valid_for_sharegroup_uuid"`
94+
Created *time.Time `json:"-"`
95+
Updated *time.Time `json:"-"`
96+
Expiry *time.Time `json:"-"`
97+
ShareGroupUUID *string `json:"sharegroup_uuid"`
98+
ShareGroupLabel *string `json:"sharegroup_label"`
99+
}
100+
101+
// UnmarshalJSON implements the json.Unmarshaler interface
102+
func (t *ImageShareGroupCreateTokenResponse) UnmarshalJSON(b []byte) error {
103+
type Mask ImageShareGroupCreateTokenResponse
104+
105+
p := struct {
106+
*Mask
107+
108+
Created *parseabletime.ParseableTime `json:"created"`
109+
Updated *parseabletime.ParseableTime `json:"updated"`
110+
Expiry *parseabletime.ParseableTime `json:"expiry"`
111+
}{
112+
Mask: (*Mask)(t),
113+
}
114+
115+
if err := json.Unmarshal(b, &p); err != nil {
116+
return err
117+
}
118+
119+
t.Created = (*time.Time)(p.Created)
120+
t.Updated = (*time.Time)(p.Updated)
121+
t.Expiry = (*time.Time)(p.Expiry)
122+
123+
return nil
124+
}
125+
126+
// ImageShareGroupCreateTokenOptions fields are those accepted by ImageShareGroupCreateToken
127+
type ImageShareGroupCreateTokenOptions struct {
128+
Label *string `json:"label,omitempty"`
129+
ValidForShareGroupUUID string `json:"valid_for_sharegroup_uuid"`
130+
}
131+
132+
// ImageShareGroupUpdateTokenOptions fields are those accepted by ImageShareGroupUpdateToken
133+
type ImageShareGroupUpdateTokenOptions struct {
134+
Label string `json:"label"`
135+
}
136+
137+
// ImageShareGroupListTokens lists information about all the ImageShareGroupTokens created by the user.
138+
// The tokens themselves are only visible once upon creation.
139+
func (c *Client) ImageShareGroupListTokens(ctx context.Context, opts *ListOptions) ([]ImageShareGroupToken, error) {
140+
return getPaginatedResults[ImageShareGroupToken](
141+
ctx,
142+
c,
143+
"/images/sharegroups/tokens",
144+
opts,
145+
)
146+
}
147+
148+
// ImageShareGroupGetToken gets information about the specified ImageShareGroupToken created by the user.
149+
// the tokens themselves are only visible once upon creation.
150+
func (c *Client) ImageShareGroupGetToken(ctx context.Context, tokenUUID string) (*ImageShareGroupToken, error) {
151+
return doGETRequest[ImageShareGroupToken](
152+
ctx,
153+
c,
154+
formatAPIPath("images/sharegroups/tokens/%s", tokenUUID),
155+
)
156+
}
157+
158+
// ImageShareGroupCreateToken allows the consumer to create a single-use ImageShareGroup membership
159+
// token for a specific ImageShareGroup owned by the producer.
160+
func (c *Client) ImageShareGroupCreateToken(ctx context.Context, opts ImageShareGroupCreateTokenOptions) (*ImageShareGroupCreateTokenResponse, error) {
161+
return doPOSTRequest[ImageShareGroupCreateTokenResponse](
162+
ctx,
163+
c,
164+
formatAPIPath("images/sharegroups/tokens"),
165+
opts,
166+
)
167+
}
168+
169+
// ImageShareGroupUpdateToken allows the consumer to update an ImageShareGroupToken's label.
170+
func (c *Client) ImageShareGroupUpdateToken(ctx context.Context, tokenUUID string, opts ImageShareGroupUpdateTokenOptions) (*ImageShareGroupToken, error) {
171+
return doPUTRequest[ImageShareGroupToken](
172+
ctx,
173+
c,
174+
formatAPIPath("images/sharegroups/tokens/%s", tokenUUID),
175+
opts,
176+
)
177+
}
178+
179+
// ImageShareGroupRemoveToken allows the consumer to remove an individual ImageShareGroupToken from an ImageShareGroup
180+
// this token has been accepted into.
181+
func (c *Client) ImageShareGroupRemoveToken(ctx context.Context, tokenUUID string) error {
182+
return doDELETERequest(
183+
ctx,
184+
c,
185+
formatAPIPath("images/sharegroups/tokens/%s", tokenUUID),
186+
)
187+
}
188+
189+
// ImageShareGroupGetByToken gets information about the ImageShareGroup that the
190+
// consumer's specified token has been accepted into.
191+
func (c *Client) ImageShareGroupGetByToken(ctx context.Context, tokenUUID string) (*ConsumerImageShareGroup, error) {
192+
return doGETRequest[ConsumerImageShareGroup](
193+
ctx,
194+
c,
195+
formatAPIPath("images/sharegroups/tokens/%s/sharegroup", tokenUUID),
196+
)
197+
}
198+
199+
// ImageShareGroupGetImagesByToken lists the images in the ImageShareGroup that the
200+
// 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](
203+
ctx,
204+
c,
205+
formatAPIPath("images/sharegroups/tokens/%s/sharegroup/images", tokenUUID),
206+
opts,
207+
)
208+
}

0 commit comments

Comments
 (0)