container_registry.go raw
1 package govultr
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7
8 "github.com/google/go-querystring/query"
9 )
10
11 const vcrPath = "/v2/registry"
12 const vcrListPath = "/v2/registries"
13
14 // ContainerRegistryService is the interface to interact with the container
15 // registry endpoints on the Vultr API. Link :
16 // https://www.vultr.com/api/#tag/Container-Registry
17 type ContainerRegistryService interface {
18 Create(ctx context.Context, createReq *ContainerRegistryReq) (*ContainerRegistry, *http.Response, error)
19 Get(ctx context.Context, vcrID string) (*ContainerRegistry, *http.Response, error)
20 Update(ctx context.Context, vcrID string, updateReq *ContainerRegistryUpdateReq) (*ContainerRegistry, *http.Response, error)
21 Delete(ctx context.Context, vcrID string) error
22 List(ctx context.Context, options *ListOptions) ([]ContainerRegistry, *Meta, *http.Response, error)
23
24 ListRepositories(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRepo, *Meta, *http.Response, error)
25 GetRepository(ctx context.Context, vcrID, imageName string) (*ContainerRegistryRepo, *http.Response, error)
26 UpdateRepository(ctx context.Context, vcrID, imageName string, updateReq *ContainerRegistryRepoUpdateReq) (*ContainerRegistryRepo, *http.Response, error) //nolint:lll
27 DeleteRepository(ctx context.Context, vcrID, imageName string) error
28
29 ListReplications(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryReplication, *Meta, *http.Response, error)
30 CreateReplication(ctx context.Context, vcrID, regionID string) (*ContainerRegistryReplication, *http.Response, error)
31 GetReplication(ctx context.Context, vcrID, regionID string) (*ContainerRegistryReplication, *http.Response, error)
32 DeleteReplication(ctx context.Context, vcrID, regionID string) error
33
34 UpdateRetentionSchedule(ctx context.Context, vcrID, schedule string) (*ContainerRegistryRetentionSchedule, *http.Response, error)
35 ExecuteRetention(ctx context.Context, vcrID string, dryRun bool) (*ContainerRegistryRetentionExecution, *http.Response, error)
36
37 ListRetentionRules(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRetentionRule, *Meta, *http.Response, error) //nolint:lll
38 GetRetentionRule(ctx context.Context, vcrID string, ruleID int) (*ContainerRegistryRetentionRule, *http.Response, error)
39 CreateRetentionRule(ctx context.Context, vcrID string, ruleReq *ContainerRegistryRetentionRuleReq) (*ContainerRegistryRetentionRule, *http.Response, error) //nolint:lll
40 UpdateRetentionRule(ctx context.Context, vcrID string, ruleID int, disabled bool) (*ContainerRegistryRetentionRule, *http.Response, error)
41 DeleteRetentionRule(ctx context.Context, vcrID string, ruleID int) error
42
43 ListRobots(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRobot, *Meta, *http.Response, error)
44 GetRobot(ctx context.Context, vcrID, robotName string) (*ContainerRegistryRobot, *http.Response, error)
45 UpdateRobot(ctx context.Context, vcrID, robotName string, updateReq *ContainerRegistryRobotReq) (*ContainerRegistryRobot, *http.Response, error) //nolint:lll
46 DeleteRobot(ctx context.Context, vcrID, robotName string) error
47
48 ListArtifacts(ctx context.Context, vcrID, imageName string, options *ListOptions) ([]ContainerRegistryArtifact, *Meta, *http.Response, error) //nolint:lll
49 GetArtifact(ctx context.Context, vcrID, imageName, artifactDigest string) (*ContainerRegistryArtifact, *http.Response, error)
50 DeleteArtifact(ctx context.Context, vcrID, imageName, artifactDigest string) error
51
52 CreateDockerCredentials(ctx context.Context, vcrID string, createOptions *DockerCredentialsOpt) (*ContainerRegistryDockerCredentials, *http.Response, error) //nolint:lll
53
54 ListRegions(ctx context.Context) ([]ContainerRegistryRegion, *Meta, *http.Response, error)
55 ListPlans(ctx context.Context) (*ContainerRegistryPlans, *http.Response, error)
56 }
57
58 // ContainerRegistryServiceHandler handles interaction between the container
59 // registry service and the Vultr API.
60 type ContainerRegistryServiceHandler struct {
61 client *Client
62 }
63
64 // ContainerRegistry represents a Vultr container registry subscription.
65 type ContainerRegistry struct {
66 ID string `json:"id"`
67 Name string `json:"name"`
68 URN string `json:"urn"`
69 Storage ContainerRegistryStorage `json:"storage"`
70 DateCreated string `json:"date_created"`
71 Public bool `json:"public"`
72 RootUser ContainerRegistryUser `json:"root_user"`
73 Metadata ContainerRegistryMetadata `json:"metadata"`
74 }
75
76 type containerRegistries struct {
77 ContainerRegistries []ContainerRegistry `json:"registries"`
78 Meta *Meta `json:"meta"`
79 }
80
81 // ContainerRegistryStorage represents the storage usage and limit.
82 type ContainerRegistryStorage struct {
83 Used ContainerRegistryStorageCount `json:"used"`
84 Allowed ContainerRegistryStorageCount `json:"allowed"`
85 }
86
87 // ContainerRegistryStorageCount represents the different storage usage counts.
88 type ContainerRegistryStorageCount struct {
89 Bytes float32 `json:"bytes"`
90 MegaBytes float32 `json:"mb"`
91 GigaBytes float32 `json:"gb"`
92 TeraBytes float32 `json:"tb"`
93 DateModified string `json:"updated_at"`
94 }
95
96 // ContainerRegistryUser contains the user data.
97 type ContainerRegistryUser struct {
98 ID int `json:"id"`
99 UserName string `json:"username"`
100 Password string `json:"password"`
101 Root bool `json:"root"`
102 DateCreated string `json:"added_at"`
103 DateModified string `json:"updated_at"`
104 }
105
106 // ContainerRegistryMetadata contains the meta data for the registry.
107 type ContainerRegistryMetadata struct {
108 Region ContainerRegistryRegion `json:"region"`
109 Subscription ContainerRegistrySubscription `json:"subscription"`
110 }
111
112 // ContainerRegistrySubscription contains the subscription information for the
113 // registry.
114 type ContainerRegistrySubscription struct {
115 Billing ContainerRegistrySubscriptionBilling `json:"billing"`
116 }
117
118 // ContainerRegistrySubscriptionBilling represents the subscription billing
119 // data on the registry.
120 type ContainerRegistrySubscriptionBilling struct {
121 MonthlyPrice float32 `json:"monthly_price"`
122 PendingCharges float32 `json:"pending_charges"`
123 }
124
125 // ContainerRegistryReq represents the data used to create a registry.
126 type ContainerRegistryReq struct {
127 Name string `json:"name"`
128 Public bool `json:"public"`
129 Region string `json:"region"`
130 Plan string `json:"plan"`
131 }
132
133 // ContainerRegistryUpdateReq represents the data used to update a registry.
134 type ContainerRegistryUpdateReq struct {
135 Public *bool `json:"public,omitempty"`
136 Plan *string `json:"plan,omitempty"`
137 }
138
139 // ContainerRegistryRepo represents the data of a registry repository.
140 type ContainerRegistryRepo struct {
141 Name string `json:"name"`
142 Image string `json:"image"`
143 Description string `json:"description"`
144 DateCreated string `json:"added_at"`
145 DateModified string `json:"updated_at"`
146 PullCount int `json:"pull_count"`
147 ArtifactCount int `json:"artifact_count"`
148 }
149
150 type containerRegistryRepos struct {
151 Repositories []ContainerRegistryRepo `json:"repositories"`
152 Meta *Meta `json:"meta"`
153 }
154
155 // ContainerRegistryRepoUpdateReq is the data to update a registry repository.
156 type ContainerRegistryRepoUpdateReq struct {
157 Description string `json:"description"`
158 }
159
160 // ContainerRegistryReplication represents a container registry replication.
161 type ContainerRegistryReplication struct {
162 Region string `json:"region"`
163 Namespace string `json:"namespace"`
164 URN string `json:"urn"`
165 }
166
167 // ContainerRegistryReplicationReq represents a container registry replication.
168 // request
169 type ContainerRegistryReplicationReq struct {
170 Region string `json:"region"`
171 }
172
173 type containerRegistryReplicationsBase struct {
174 Replications []ContainerRegistryReplication `json:"replications"`
175 Meta *Meta `json:"meta"`
176 }
177
178 // ContainerRegistryRetentionSchedule represents a container registry retention
179 // schedule.
180 type ContainerRegistryRetentionSchedule struct {
181 Schedule string `json:"schedule"`
182 NextScheduledTime string `json:"next_scheduled_time"`
183 }
184
185 // ContainerRegistryRetentionScheduleReq represents a container registry
186 // schedule request.
187 type ContainerRegistryRetentionScheduleReq struct {
188 Cron string `json:"cron"`
189 }
190
191 // ContainerRegistryRetentionExecution represents a container registry
192 // execution.
193 type ContainerRegistryRetentionExecution struct {
194 Start string `json:"start_time"`
195 End string `json:"end_time"`
196 Trigger string `json:"trigger"`
197 DryRun bool `json:"dry_run"`
198 }
199
200 // ContainerRegistryRetentionExecutionReq represents a container registry
201 // execution request.
202 type ContainerRegistryRetentionExecutionReq struct {
203 DryRun bool `json:"dry_run"`
204 }
205
206 // ContainerRegistryRetentionRule represents a container registry retention
207 // rule.
208 type ContainerRegistryRetentionRule struct {
209 ID int `json:"id"`
210 Disabled bool `json:"disabled"`
211 Action string `json:"action"`
212 Parameters ContainerRegistryRetentionRuleParameter `json:"params"`
213 ScopeSelector ContainerRegistryScopeSelector `json:"scope_selector"`
214 TagSelectors []ContainerRegistryRetentionRuleSelector `json:"tag_selectors"`
215 Template string `json:"template"`
216 }
217
218 // ContainerRegistryRetentionRuleParameter represents a container registry rule
219 // parameter.
220 type ContainerRegistryRetentionRuleParameter struct {
221 AdditionalProperty int `json:"additional_prop"`
222 }
223
224 // ContainerRegistryScopeSelector represents a container registry retention
225 // rule scope selector.
226 type ContainerRegistryScopeSelector struct {
227 Repository []ContainerRegistryRetentionRuleSelector `json:"repository"`
228 }
229
230 // ContainerRegistryRetentionRuleSelector represents a container registry
231 // retention rule selector.
232 type ContainerRegistryRetentionRuleSelector struct {
233 Decoration string `json:"decoration"`
234 Kind string `json:"kind"`
235 Pattern string `json:"pattern"`
236 }
237
238 type containerRegistryRetentionRulesBase struct {
239 Rules []ContainerRegistryRetentionRule `json:"retention_rules"`
240 Meta *Meta `json:"meta"`
241 }
242
243 // ContainerRegistryRetentionRuleReq represents the options for creating a
244 // container registry retention rule.
245 type ContainerRegistryRetentionRuleReq struct {
246 Type string `json:"rule_type"`
247 Count int `json:"count,omitempty"`
248 RepositoryAction string `json:"repository_action"`
249 RepositoryMatch string `json:"repository_match"`
250 TagAction string `json:"tag_action"`
251 TagMatch string `json:"tag_match"`
252 Untagged bool `json:"untagged"`
253 }
254
255 // ContainerRegistryRetentionRuleUpdateReq represents the options for updating
256 // a container registry retention rule.
257 type ContainerRegistryRetentionRuleUpdateReq struct {
258 Disabled bool `json:"disabled"`
259 }
260
261 // ContainerRegistryRobot represents the details of a container registry robot.
262 type ContainerRegistryRobot struct {
263 Name string `json:"name"`
264 Description string `json:"description"`
265 Secret string `json:"secret"`
266 Disable bool `json:"disable"`
267 Duration int `json:"duration"`
268 Permissions []ContainerRegistryRobotPermission `json:"permissions"`
269 DateCreated string `json:"creation_time"`
270 }
271
272 // ContainerRegistryRobotPermission represent container registry robot
273 // permission details.
274 type ContainerRegistryRobotPermission struct {
275 Kind string `json:"kind"`
276 Namespace string `json:"namespace"`
277 Access []ContainerRegistryRobotAccess `json:"access"`
278 }
279
280 // ContainerRegistryRobotAccess represents container registry robot access
281 // details.
282 type ContainerRegistryRobotAccess struct {
283 Action string `json:"action"`
284 Resource string `json:"resource"`
285 Effect string `json:"effect"`
286 }
287
288 type containerRegistryRobotsBase struct {
289 Robots []ContainerRegistryRobot `json:"robots"`
290 Meta *Meta `json:"meta"`
291 }
292
293 type ContainerRegistryRobotReq struct {
294 Description string `json:"description,omitempty"`
295 Disable bool `json:"disable,omitempty"`
296 Duration int `json:"duration,omitempty"`
297 Access ContainerRegistryRobotAccess `json:"access,omitempty"`
298 }
299
300 // ContainerRegistryArtifact represents a container registry artifact.
301 type ContainerRegistryArtifact struct {
302 ArtifactType string `json:"artifact_type"`
303 Digest string `json:"digest"`
304 ManifestMediaType string `json:"manifest_media_type"`
305 MediaType string `json:"media_type"`
306 RepositoryName string `json:"repository_name"`
307 Size int `json:"size"`
308 Type string `json:"type"`
309 Tags []ContainerRegistryArtifactTag `json:"tags"`
310 DatePulled string `json:"pull_time"`
311 DatePushed string `json:"push_time"`
312 }
313
314 // ContainerRegistryArtifactTag represents tags on an artifact.
315 type ContainerRegistryArtifactTag struct {
316 Name string `json:"name"`
317 Immutable bool `json:"immutable"`
318 DatePulled string `json:"pull_time"`
319 DatePushed string `json:"push_time"`
320 }
321
322 type containerRegistryArtifactsBase struct {
323 Artifacts []ContainerRegistryArtifact `json:"artifacts"`
324 Meta *Meta `json:"meta"`
325 }
326
327 // DockerCredentialsOpt contains the options used to create Docker credentials.
328 type DockerCredentialsOpt struct {
329 ExpirySeconds *int
330 WriteAccess *bool
331 }
332
333 // ContainerRegistryDockerCredentials represents the byte array of character
334 // data returned after creating a Docker credential.
335 type ContainerRegistryDockerCredentials []byte
336
337 // UnmarshalJSON is a custom unmarshal function for
338 // ContainerRegistryDockerCredentials.
339 func (c *ContainerRegistryDockerCredentials) UnmarshalJSON(b []byte) error {
340 *c = b
341 return nil
342 }
343
344 // String converts the ContainerRegistryDockerCredentials to a string.
345 func (c *ContainerRegistryDockerCredentials) String() string {
346 return string(*c)
347 }
348
349 // ContainerRegistryRegion represents the region data.
350 type ContainerRegistryRegion struct {
351 ID int `json:"id"`
352 Name string `json:"name"`
353 URN string `json:"urn"`
354 BaseURL string `json:"base_url"`
355 Public bool `json:"public"`
356 DateCreated string `json:"added_at"`
357 DateModified string `json:"updated_at"`
358 DataCenter ContainerRegistryRegionDataCenter `json:"data_center"`
359 }
360
361 // ContainerRegistryRegionDataCenter is the datacenter info for a given region.
362 type ContainerRegistryRegionDataCenter struct {
363 ID int `json:"id"`
364 Name string `json:"name"`
365 SiteCode string `json:"site_code"`
366 Region string `json:"region"`
367 Country string `json:"country"`
368 Continent string `json:"continent"`
369 Description string `json:"description"`
370 Airport string `json:"airport"`
371 }
372
373 type containerRegistryRegions struct {
374 Regions []ContainerRegistryRegion `json:"regions"`
375 Meta *Meta `json:"meta"`
376 }
377
378 // ContainerRegistryPlans contains all plan types.
379 type ContainerRegistryPlans struct {
380 Plans ContainerRegistryPlanTypes `json:"plans"`
381 }
382
383 // ContainerRegistryPlanTypes represent the different plan types.
384 type ContainerRegistryPlanTypes struct {
385 StartUp ContainerRegistryPlan `json:"start_up"`
386 Business ContainerRegistryPlan `json:"business"`
387 Premium ContainerRegistryPlan `json:"premium"`
388 Enterprise ContainerRegistryPlan `json:"enterprise"`
389 }
390
391 // ContainerRegistryPlan represent the plan data.
392 type ContainerRegistryPlan struct {
393 VanityName string `json:"vanity_name"`
394 MaxStorageMB int `json:"max_storage_mb"`
395 MonthlyPrice int `json:"monthly_price"`
396 }
397
398 // Get retrieves a contrainer registry by ID
399 func (h *ContainerRegistryServiceHandler) Get(ctx context.Context, id string) (*ContainerRegistry, *http.Response, error) {
400 req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s", vcrPath, id), nil)
401 if errReq != nil {
402 return nil, nil, errReq
403 }
404
405 vcr := new(ContainerRegistry)
406 resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
407 if errResp != nil {
408 return nil, resp, errResp
409 }
410
411 return vcr, resp, nil
412 }
413
414 // List retrieves the list of all container registries
415 func (h *ContainerRegistryServiceHandler) List(ctx context.Context, options *ListOptions) ([]ContainerRegistry, *Meta, *http.Response, error) { //nolint:lll,dupl
416 req, errReq := h.client.NewRequest(ctx, http.MethodGet, vcrListPath, nil)
417 if errReq != nil {
418 return nil, nil, nil, errReq
419 }
420
421 qStrings, errQ := query.Values(options)
422 if errQ != nil {
423 return nil, nil, nil, errQ
424 }
425
426 req.URL.RawQuery = qStrings.Encode()
427
428 vcrs := new(containerRegistries)
429 resp, errResp := h.client.DoWithContext(ctx, req, &vcrs)
430 if errResp != nil {
431 return nil, nil, resp, errResp
432 }
433
434 return vcrs.ContainerRegistries, vcrs.Meta, resp, nil
435 }
436
437 // Create creates a container registry
438 func (h *ContainerRegistryServiceHandler) Create(ctx context.Context, createReq *ContainerRegistryReq) (*ContainerRegistry, *http.Response, error) { //nolint:lll
439 req, errReq := h.client.NewRequest(ctx, http.MethodPost, vcrPath, createReq)
440 if errReq != nil {
441 return nil, nil, errReq
442 }
443
444 vcr := new(ContainerRegistry)
445 resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
446 if errResp != nil {
447 return nil, resp, errResp
448 }
449
450 return vcr, resp, nil
451 }
452
453 // Update will update an existing container registry
454 func (h *ContainerRegistryServiceHandler) Update(ctx context.Context, vcrID string, updateReq *ContainerRegistryUpdateReq) (*ContainerRegistry, *http.Response, error) { //nolint:lll
455 req, errReq := h.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s", vcrPath, vcrID), updateReq)
456 if errReq != nil {
457 return nil, nil, errReq
458 }
459
460 vcr := new(ContainerRegistry)
461 resp, errResp := h.client.DoWithContext(ctx, req, &vcr)
462 if errResp != nil {
463 return nil, resp, errResp
464 }
465
466 return vcr, resp, nil
467 }
468
469 // Delete will delete a container registry
470 func (h *ContainerRegistryServiceHandler) Delete(ctx context.Context, vcrID string) error {
471 req, errReq := h.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", vcrPath, vcrID), nil)
472 if errReq != nil {
473 return errReq
474 }
475
476 _, errResp := h.client.DoWithContext(ctx, req, nil)
477 if errResp != nil {
478 return errResp
479 }
480
481 return nil
482 }
483
484 // ListRepositories will get a list of the repositories for a existing
485 // container registry
486 func (h *ContainerRegistryServiceHandler) ListRepositories(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRepo, *Meta, *http.Response, error) { //nolint:lll,dupl
487 req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/repositories", vcrPath, vcrID), nil)
488 if errReq != nil {
489 return nil, nil, nil, errReq
490 }
491
492 qStrings, errQ := query.Values(options)
493 if errQ != nil {
494 return nil, nil, nil, errQ
495 }
496
497 req.URL.RawQuery = qStrings.Encode()
498
499 vcrRepos := new(containerRegistryRepos)
500 resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepos)
501 if errResp != nil {
502 return nil, nil, resp, errResp
503 }
504
505 return vcrRepos.Repositories, vcrRepos.Meta, resp, nil
506 }
507
508 // GetRepository will return an existing repository of the requested registry
509 // ID and image name
510 func (h *ContainerRegistryServiceHandler) GetRepository(ctx context.Context, vcrID, imageName string) (*ContainerRegistryRepo, *http.Response, error) { //nolint:lll
511 req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), nil)
512 if errReq != nil {
513 return nil, nil, errReq
514 }
515
516 vcrRepo := new(ContainerRegistryRepo)
517 resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepo)
518 if errResp != nil {
519 return nil, resp, errResp
520 }
521
522 return vcrRepo, resp, nil
523 }
524
525 // UpdateRepository allows updating the repository with the specified registry
526 // ID and image name
527 func (h *ContainerRegistryServiceHandler) UpdateRepository(ctx context.Context, vcrID, imageName string, updateReq *ContainerRegistryRepoUpdateReq) (*ContainerRegistryRepo, *http.Response, error) { //nolint: lll
528 req, errReq := h.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), updateReq)
529 if errReq != nil {
530 return nil, nil, errReq
531 }
532
533 vcrRepo := new(ContainerRegistryRepo)
534 resp, errResp := h.client.DoWithContext(ctx, req, &vcrRepo)
535 if errResp != nil {
536 return nil, resp, errResp
537 }
538
539 return vcrRepo, resp, nil
540 }
541
542 // DeleteRepository remove a repository from the container registry
543 func (h *ContainerRegistryServiceHandler) DeleteRepository(ctx context.Context, vcrID, imageName string) error {
544 req, errReq := h.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s/repository/%s", vcrPath, vcrID, imageName), nil)
545 if errReq != nil {
546 return errReq
547 }
548
549 _, errResp := h.client.DoWithContext(ctx, req, nil)
550 if errResp != nil {
551 return errResp
552 }
553
554 return nil
555 }
556
557 // ListReplications retrieves a list of container registry replications
558 func (h *ContainerRegistryServiceHandler) ListReplications(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryReplication, *Meta, *http.Response, error) { //nolint:lll,dupl
559 url := fmt.Sprintf("%s/%s/replications", vcrPath, vcrID)
560
561 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
562 if err != nil {
563 return nil, nil, nil, err
564 }
565
566 qStrings, err := query.Values(options)
567 if err != nil {
568 return nil, nil, nil, err
569 }
570
571 req.URL.RawQuery = qStrings.Encode()
572
573 replications := new(containerRegistryReplicationsBase)
574
575 resp, err := h.client.DoWithContext(ctx, req, &replications)
576 if err != nil {
577 return nil, nil, resp, err
578 }
579
580 return replications.Replications, replications.Meta, resp, nil
581 }
582
583 // CreateReplication creates a container registry replication
584 func (h *ContainerRegistryServiceHandler) CreateReplication(ctx context.Context, vcrID, regionID string) (*ContainerRegistryReplication, *http.Response, error) { //nolint:lll
585 url := fmt.Sprintf("%s/%s/replication", vcrPath, vcrID)
586
587 req, err := h.client.NewRequest(ctx, http.MethodPost, url, &ContainerRegistryReplicationReq{Region: regionID})
588 if err != nil {
589 return nil, nil, err
590 }
591
592 replication := new(ContainerRegistryReplication)
593
594 resp, err := h.client.DoWithContext(ctx, req, &replication)
595 if err != nil {
596 return nil, resp, err
597 }
598
599 return replication, resp, nil
600 }
601
602 // GetReplication retrieves a container registry replication
603 func (h *ContainerRegistryServiceHandler) GetReplication(ctx context.Context, vcrID, regionID string) (*ContainerRegistryReplication, *http.Response, error) { //nolint:lll
604 url := fmt.Sprintf("%s/%s/replication/%s", vcrPath, vcrID, regionID)
605
606 req, errReq := h.client.NewRequest(ctx, http.MethodGet, url, nil)
607 if errReq != nil {
608 return nil, nil, errReq
609 }
610
611 replication := new(ContainerRegistryReplication)
612
613 resp, errResp := h.client.DoWithContext(ctx, req, &replication)
614 if errResp != nil {
615 return nil, resp, errResp
616 }
617
618 return replication, resp, nil
619 }
620
621 // DeleteReplication deletes a container registry replication
622 func (h *ContainerRegistryServiceHandler) DeleteReplication(ctx context.Context, vcrID, regionID string) error {
623 url := fmt.Sprintf("%s/%s/replication/%s", vcrPath, vcrID, regionID)
624
625 req, err := h.client.NewRequest(ctx, http.MethodDelete, url, nil)
626 if err != nil {
627 return err
628 }
629
630 if _, err := h.client.DoWithContext(ctx, req, nil); err != nil {
631 return err
632 }
633
634 return nil
635 }
636
637 // UpdateRetentionSchedule updates a container registry retention schedule
638 func (h *ContainerRegistryServiceHandler) UpdateRetentionSchedule(ctx context.Context, vcrID, schedule string) (*ContainerRegistryRetentionSchedule, *http.Response, error) { //nolint:lll
639 url := fmt.Sprintf("%s/%s/retention/schedule", vcrPath, vcrID)
640
641 req, err := h.client.NewRequest(ctx, http.MethodPut, url, &ContainerRegistryRetentionScheduleReq{Cron: schedule})
642 if err != nil {
643 return nil, nil, err
644 }
645
646 sched := new(ContainerRegistryRetentionSchedule)
647
648 resp, errResp := h.client.DoWithContext(ctx, req, &sched)
649 if errResp != nil {
650 return nil, resp, errResp
651 }
652
653 return sched, resp, nil
654 }
655
656 // ExecuteRetention triggers a container registry retention execution
657 func (h *ContainerRegistryServiceHandler) ExecuteRetention(ctx context.Context, vcrID string, dryRun bool) (*ContainerRegistryRetentionExecution, *http.Response, error) { //nolint:lll
658 url := fmt.Sprintf("%s/%s/retention/executions", vcrPath, vcrID)
659
660 req, err := h.client.NewRequest(ctx, http.MethodPost, url, &ContainerRegistryRetentionExecutionReq{DryRun: dryRun})
661 if err != nil {
662 return nil, nil, err
663 }
664
665 execution := new(ContainerRegistryRetentionExecution)
666
667 resp, errResp := h.client.DoWithContext(ctx, req, &execution)
668 if errResp != nil {
669 return nil, resp, errResp
670 }
671
672 return execution, resp, nil
673 }
674
675 // ListRetentionRules retrieves a list of container registry retention rules
676 func (h *ContainerRegistryServiceHandler) ListRetentionRules(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRetentionRule, *Meta, *http.Response, error) { //nolint:lll,dupl
677 url := fmt.Sprintf("%s/%s/retention/rules", vcrPath, vcrID)
678
679 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
680 if err != nil {
681 return nil, nil, nil, err
682 }
683
684 qStrings, err := query.Values(options)
685 if err != nil {
686 return nil, nil, nil, err
687 }
688
689 req.URL.RawQuery = qStrings.Encode()
690
691 rules := new(containerRegistryRetentionRulesBase)
692
693 resp, err := h.client.DoWithContext(ctx, req, &rules)
694 if err != nil {
695 return nil, nil, resp, err
696 }
697
698 return rules.Rules, rules.Meta, resp, nil
699 }
700
701 // CreateRetentionRule creates a new container registry retention rule
702 func (h *ContainerRegistryServiceHandler) CreateRetentionRule(ctx context.Context, vcrID string, ruleReq *ContainerRegistryRetentionRuleReq) (*ContainerRegistryRetentionRule, *http.Response, error) { //nolint:lll
703 url := fmt.Sprintf("%s/%s/retention/rules", vcrPath, vcrID)
704
705 req, err := h.client.NewRequest(ctx, http.MethodPost, url, ruleReq)
706 if err != nil {
707 return nil, nil, err
708 }
709
710 rule := new(ContainerRegistryRetentionRule)
711
712 resp, err := h.client.DoWithContext(ctx, req, &rule)
713 if err != nil {
714 return nil, resp, err
715 }
716
717 return rule, resp, nil
718 }
719
720 // GetRetentionRule retrieves a container registry retention rule
721 func (h *ContainerRegistryServiceHandler) GetRetentionRule(ctx context.Context, vcrID string, ruleID int) (*ContainerRegistryRetentionRule, *http.Response, error) { //nolint:lll
722 url := fmt.Sprintf("%s/%s/retention/rules/%d", vcrPath, vcrID, ruleID)
723
724 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
725 if err != nil {
726 return nil, nil, err
727 }
728
729 rule := new(ContainerRegistryRetentionRule)
730
731 resp, err := h.client.DoWithContext(ctx, req, &rule)
732 if err != nil {
733 return nil, resp, err
734 }
735
736 return rule, resp, nil
737 }
738
739 // UpdateRetentionRule updates a container registry retention rule
740 func (h *ContainerRegistryServiceHandler) UpdateRetentionRule(ctx context.Context, vcrID string, ruleID int, disabled bool) (*ContainerRegistryRetentionRule, *http.Response, error) { //nolint:lll
741 url := fmt.Sprintf("%s/%s/retention/rules/%d", vcrPath, vcrID, ruleID)
742
743 req, err := h.client.NewRequest(ctx, http.MethodPut, url, &ContainerRegistryRetentionRuleUpdateReq{Disabled: disabled})
744 if err != nil {
745 return nil, nil, err
746 }
747
748 rule := new(ContainerRegistryRetentionRule)
749
750 resp, err := h.client.DoWithContext(ctx, req, &rule)
751 if err != nil {
752 return nil, resp, err
753 }
754
755 return rule, resp, nil
756 }
757
758 // DeleteRetentionRule deletes a container registry retention rule
759 func (h *ContainerRegistryServiceHandler) DeleteRetentionRule(ctx context.Context, vcrID string, ruleID int) error {
760 url := fmt.Sprintf("%s/%s/retention/rules/%d", vcrPath, vcrID, ruleID)
761
762 req, err := h.client.NewRequest(ctx, http.MethodDelete, url, nil)
763 if err != nil {
764 return err
765 }
766
767 if _, err := h.client.DoWithContext(ctx, req, nil); err != nil {
768 return err
769 }
770
771 return nil
772 }
773
774 func (h *ContainerRegistryServiceHandler) ListRobots(ctx context.Context, vcrID string, options *ListOptions) ([]ContainerRegistryRobot, *Meta, *http.Response, error) { //nolint:lll,dupl
775 url := fmt.Sprintf("%s/%s/robots", vcrPath, vcrID)
776
777 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
778 if err != nil {
779 return nil, nil, nil, err
780 }
781
782 qStrings, err := query.Values(options)
783 if err != nil {
784 return nil, nil, nil, err
785 }
786
787 req.URL.RawQuery = qStrings.Encode()
788
789 bots := new(containerRegistryRobotsBase)
790
791 resp, err := h.client.DoWithContext(ctx, req, &bots)
792 if err != nil {
793 return nil, nil, resp, err
794 }
795
796 return bots.Robots, bots.Meta, resp, nil
797 }
798
799 func (h *ContainerRegistryServiceHandler) GetRobot(ctx context.Context, vcrID, robotName string) (*ContainerRegistryRobot, *http.Response, error) { //nolint:lll
800 url := fmt.Sprintf("%s/%s/robot/%s", vcrPath, vcrID, robotName)
801
802 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
803 if err != nil {
804 return nil, nil, err
805 }
806
807 bot := new(ContainerRegistryRobot)
808
809 resp, err := h.client.DoWithContext(ctx, req, &bot)
810 if err != nil {
811 return nil, resp, err
812 }
813
814 return bot, resp, nil
815 }
816
817 func (h *ContainerRegistryServiceHandler) UpdateRobot(ctx context.Context, vcrID, robotName string, updateReq *ContainerRegistryRobotReq) (*ContainerRegistryRobot, *http.Response, error) { //nolint:lll
818 url := fmt.Sprintf("%s/%s/robot/%s", vcrPath, vcrID, robotName)
819
820 req, err := h.client.NewRequest(ctx, http.MethodPut, url, updateReq)
821 if err != nil {
822 return nil, nil, err
823 }
824
825 bot := new(ContainerRegistryRobot)
826
827 resp, err := h.client.DoWithContext(ctx, req, &bot)
828 if err != nil {
829 return nil, resp, err
830 }
831
832 return bot, resp, nil
833 }
834
835 func (h *ContainerRegistryServiceHandler) DeleteRobot(ctx context.Context, vcrID, robotName string) error {
836 url := fmt.Sprintf("%s/%s/robot/%s", vcrPath, vcrID, robotName)
837
838 req, err := h.client.NewRequest(ctx, http.MethodDelete, url, nil)
839 if err != nil {
840 return err
841 }
842
843 if _, err := h.client.DoWithContext(ctx, req, nil); err != nil {
844 return err
845 }
846
847 return nil
848 }
849
850 func (h *ContainerRegistryServiceHandler) ListArtifacts(ctx context.Context, vcrID, imageName string, options *ListOptions) ([]ContainerRegistryArtifact, *Meta, *http.Response, error) { //nolint:lll,dupl
851 url := fmt.Sprintf("%s/%s/repository/%s/artifacts", vcrPath, vcrID, imageName)
852
853 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
854 if err != nil {
855 return nil, nil, nil, err
856 }
857
858 qStrings, err := query.Values(options)
859 if err != nil {
860 return nil, nil, nil, err
861 }
862
863 req.URL.RawQuery = qStrings.Encode()
864
865 artifacts := new(containerRegistryArtifactsBase)
866
867 resp, err := h.client.DoWithContext(ctx, req, &artifacts)
868 if err != nil {
869 return nil, nil, resp, err
870 }
871
872 return artifacts.Artifacts, artifacts.Meta, resp, nil
873 }
874
875 func (h *ContainerRegistryServiceHandler) GetArtifact(ctx context.Context, vcrID, imageName, artifactDigest string) (*ContainerRegistryArtifact, *http.Response, error) { //nolint:lll
876 url := fmt.Sprintf("%s/%s/repository/%s/artifact/%s", vcrPath, vcrID, imageName, artifactDigest)
877
878 req, err := h.client.NewRequest(ctx, http.MethodGet, url, nil)
879 if err != nil {
880 return nil, nil, err
881 }
882
883 artifact := new(ContainerRegistryArtifact)
884
885 resp, err := h.client.DoWithContext(ctx, req, &artifact)
886 if err != nil {
887 return nil, resp, err
888 }
889
890 return artifact, resp, nil
891 }
892
893 func (h *ContainerRegistryServiceHandler) DeleteArtifact(ctx context.Context, vcrID, imageName, artifactDigest string) error {
894 url := fmt.Sprintf("%s/%s/repository/%s/artifact/%s", vcrPath, vcrID, imageName, artifactDigest)
895
896 req, err := h.client.NewRequest(ctx, http.MethodDelete, url, nil)
897 if err != nil {
898 return err
899 }
900
901 if _, err := h.client.DoWithContext(ctx, req, nil); err != nil {
902 return err
903 }
904
905 return nil
906 }
907
908 // CreateDockerCredentials will create new Docker credentials used by the
909 // Docker CLI
910 func (h *ContainerRegistryServiceHandler) CreateDockerCredentials(ctx context.Context, vcrID string, createOptions *DockerCredentialsOpt) (*ContainerRegistryDockerCredentials, *http.Response, error) { //nolint:lll
911 url := fmt.Sprintf("%s/%s/docker-credentials", vcrPath, vcrID)
912 req, errReq := h.client.NewRequest(ctx, http.MethodOptions, url, nil)
913 if errReq != nil {
914 return nil, nil, errReq
915 }
916
917 queryParam := req.URL.Query()
918 if createOptions.ExpirySeconds != nil {
919 queryParam.Add("expiry_seconds", fmt.Sprintf("%d", createOptions.ExpirySeconds))
920 }
921
922 if createOptions.WriteAccess != nil {
923 queryParam.Add("read_write", fmt.Sprintf("%t", *createOptions.WriteAccess))
924 }
925
926 req.URL.RawQuery = queryParam.Encode()
927
928 creds := new(ContainerRegistryDockerCredentials)
929 resp, errResp := h.client.DoWithContext(ctx, req, &creds)
930 if errResp != nil {
931 return nil, nil, errResp
932 }
933
934 return creds, resp, nil
935 }
936
937 // ListRegions will return a list of regions relevant to the container registry
938 // API operations
939 func (h *ContainerRegistryServiceHandler) ListRegions(ctx context.Context) ([]ContainerRegistryRegion, *Meta, *http.Response, error) {
940 req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/region/list", vcrPath), nil)
941 if errReq != nil {
942 return nil, nil, nil, errReq
943 }
944
945 vcrRegions := new(containerRegistryRegions)
946 resp, errResp := h.client.DoWithContext(ctx, req, &vcrRegions)
947 if errResp != nil {
948 return nil, nil, resp, errResp
949 }
950
951 return vcrRegions.Regions, vcrRegions.Meta, resp, nil
952 }
953
954 // ListPlans returns a list of plans relevant to the container registry
955 // offerings
956 func (h *ContainerRegistryServiceHandler) ListPlans(ctx context.Context) (*ContainerRegistryPlans, *http.Response, error) {
957 req, errReq := h.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/plan/list", vcrPath), nil)
958 if errReq != nil {
959 return nil, nil, errReq
960 }
961
962 vcrPlans := new(ContainerRegistryPlans)
963 resp, errResp := h.client.DoWithContext(ctx, req, &vcrPlans)
964 if errResp != nil {
965 return nil, resp, errResp
966 }
967
968 return vcrPlans, resp, nil
969 }
970