From 0068c6d220919f95a5360c04a8dccb6c86a75bc9 Mon Sep 17 00:00:00 2001 From: Hussain Khalil Date: Mon, 3 Jun 2024 16:09:57 -0400 Subject: [PATCH 1/5] Update APIv4 and validation based on Image Service API spec --- packages/api-v4/src/images/images.ts | 19 +++++++++++++++++++ packages/api-v4/src/images/types.ts | 18 +++++++++++++++++- packages/manager/src/factories/images.ts | 2 ++ packages/validation/src/images.schema.ts | 8 +++++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/api-v4/src/images/images.ts b/packages/api-v4/src/images/images.ts index 53b3d3d63e0..c625a158a85 100644 --- a/packages/api-v4/src/images/images.ts +++ b/packages/api-v4/src/images/images.ts @@ -1,5 +1,6 @@ import { createImageSchema, + updateImageRegionsSchema, updateImageSchema, uploadImageSchema, } from '@linode/validation/lib/images.schema'; @@ -107,3 +108,21 @@ export const uploadImage = (data: ImageUploadPayload) => { setData(data, uploadImageSchema) ); }; + +/** + * Selects the regions to which this image will be replicated. + * + * @param imageId { string } ID of the Image to look up. + * @param regions { string[] } ID of regions to replicate to. Must contain at least one valid region. + */ +export const updateImageRegions = (imageId: string, regions: string[]) => { + const data = { + regions, + }; + + return Request( + setURL(`${API_ROOT}/images/${encodeURIComponent(imageId)}/regions`), + setMethod('POST'), + setData(data, updateImageRegionsSchema) + ); +}; diff --git a/packages/api-v4/src/images/types.ts b/packages/api-v4/src/images/types.ts index eabad2806a4..6ab56b1b23b 100644 --- a/packages/api-v4/src/images/types.ts +++ b/packages/api-v4/src/images/types.ts @@ -4,7 +4,21 @@ export type ImageStatus = | 'deleted' | 'pending_upload'; -type ImageCapabilities = 'cloud-init'; +type ImageCapabilities = 'cloud-init' | 'distributed-images'; + +type ImageRegionStatus = + | 'creating' + | 'pending' + | 'available' + | 'pending deletion' + | 'pending replication' + | 'replicating' + | 'timedout'; + +export interface ImageRegion { + region: string; + status: ImageRegionStatus; +} export interface Image { eol: string | null; @@ -16,12 +30,14 @@ export interface Image { type: string; is_public: boolean; size: number; + total_size: number; created_by: null | string; vendor: string | null; deprecated: boolean; expiry: null | string; status: ImageStatus; capabilities: ImageCapabilities[]; + regions: ImageRegion[]; tags: string[]; } diff --git a/packages/manager/src/factories/images.ts b/packages/manager/src/factories/images.ts index ec80a043440..18a6246e599 100644 --- a/packages/manager/src/factories/images.ts +++ b/packages/manager/src/factories/images.ts @@ -12,9 +12,11 @@ export const imageFactory = Factory.Sync.makeFactory({ id: Factory.each((id) => `private/${id}`), is_public: false, label: Factory.each((i) => `image-${i}`), + regions: [], size: 1500, status: 'available', tags: [], + total_size: 1500, type: 'manual', updated: new Date().toISOString(), vendor: null, diff --git a/packages/validation/src/images.schema.ts b/packages/validation/src/images.schema.ts index 4ff45ebef4c..c8b3b6f9a45 100644 --- a/packages/validation/src/images.schema.ts +++ b/packages/validation/src/images.schema.ts @@ -12,7 +12,7 @@ export const baseImageSchema = object({ label: labelSchema.notRequired(), description: string().notRequired().min(1).max(65000), cloud_init: boolean().notRequired(), - tags: array(string()).notRequired(), + tags: array(string().min(3).max(50)).max(500).notRequired(), }); export const createImageSchema = baseImageSchema.shape({ @@ -33,3 +33,9 @@ export const updateImageSchema = object({ .max(65000, 'Length must be 65000 characters or less.'), tags: array(string()).notRequired(), }); + +export const updateImageRegionsSchema = object({ + regions: array(string()) + .required('Regions are required.') + .min(1, 'Must specify at least one region.'), +}); From 4c6313616f3e7da073baa7497b14fa64881602b9 Mon Sep 17 00:00:00 2001 From: Hussain Khalil Date: Mon, 3 Jun 2024 16:26:13 -0400 Subject: [PATCH 2/5] Added changeset: Add `regions` and `total_size` fields to `imageFactory` --- .../manager/.changeset/pr-10541-changed-1717446372854.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-10541-changed-1717446372854.md diff --git a/packages/manager/.changeset/pr-10541-changed-1717446372854.md b/packages/manager/.changeset/pr-10541-changed-1717446372854.md new file mode 100644 index 00000000000..2403d5c6323 --- /dev/null +++ b/packages/manager/.changeset/pr-10541-changed-1717446372854.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Add `regions` and `total_size` fields to `imageFactory` ([#10541](https://github.com/linode/manager/pull/10541)) From 4cbd78aaa57ad2c436570678e254cd90766f3835 Mon Sep 17 00:00:00 2001 From: Hussain Khalil Date: Mon, 3 Jun 2024 16:27:39 -0400 Subject: [PATCH 3/5] Added changeset: Update images endpoints to reflect the image service API spec --- .../.changeset/pr-10541-upcoming-features-1717446459710.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/api-v4/.changeset/pr-10541-upcoming-features-1717446459710.md diff --git a/packages/api-v4/.changeset/pr-10541-upcoming-features-1717446459710.md b/packages/api-v4/.changeset/pr-10541-upcoming-features-1717446459710.md new file mode 100644 index 00000000000..b5e7a41a687 --- /dev/null +++ b/packages/api-v4/.changeset/pr-10541-upcoming-features-1717446459710.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Upcoming Features +--- + +Update images endpoints to reflect the image service API spec ([#10541](https://github.com/linode/manager/pull/10541)) From 04aecb17e2a46dd79832c05599f3902f1d534949 Mon Sep 17 00:00:00 2001 From: Hussain Khalil Date: Mon, 3 Jun 2024 16:28:17 -0400 Subject: [PATCH 4/5] Added changeset: `updateImageRegionsSchema` --- .../validation/.changeset/pr-10541-added-1717446497849.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/validation/.changeset/pr-10541-added-1717446497849.md diff --git a/packages/validation/.changeset/pr-10541-added-1717446497849.md b/packages/validation/.changeset/pr-10541-added-1717446497849.md new file mode 100644 index 00000000000..74db8363504 --- /dev/null +++ b/packages/validation/.changeset/pr-10541-added-1717446497849.md @@ -0,0 +1,5 @@ +--- +"@linode/validation": Added +--- + +`updateImageRegionsSchema` ([#10541](https://github.com/linode/manager/pull/10541)) From ee9d6934f27c7178576fbc30d1168fface940747 Mon Sep 17 00:00:00 2001 From: Hussain Khalil Date: Tue, 4 Jun 2024 12:51:11 -0400 Subject: [PATCH 5/5] Add JSDoc comments for Image fields --- packages/api-v4/src/images/types.ts | 75 ++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/api-v4/src/images/types.ts b/packages/api-v4/src/images/types.ts index 6ab56b1b23b..dd034eda126 100644 --- a/packages/api-v4/src/images/types.ts +++ b/packages/api-v4/src/images/types.ts @@ -6,6 +6,8 @@ export type ImageStatus = type ImageCapabilities = 'cloud-init' | 'distributed-images'; +type ImageType = 'manual' | 'automatic'; + type ImageRegionStatus = | 'creating' | 'pending' @@ -21,23 +23,94 @@ export interface ImageRegion { } export interface Image { + /** + * An optional timestamp of this image's planned end-of-life. + */ eol: string | null; + + /** + * The unique ID of the this image. + */ id: string; + + /** + * A short description of this image. + */ label: string; + + /** + * A detailed description of this image. + */ description: string | null; + + /** + * The timestamp of when this image was created. + */ created: string; + + /** + * The timestamp of when this image was last updated. + */ updated: string; - type: string; + + /** + * Indicates the method of this image's creation. + */ + type: ImageType; + + /** + * Whether this image is marked for public distribution. + */ is_public: boolean; + + /** + * The minimum size in MB needed to deploy this image. + */ size: number; + + /** + * The total storage consumed by this image across its regions. + */ total_size: number; + + /** + * The name of the user who created this image or 'linode' for public images. + */ created_by: null | string; + + /** + * The distribution author. + */ vendor: string | null; + + /** + * Whether this is a public image that is deprecated. + */ deprecated: boolean; + + /** + * A timestamp of when this image will expire if it was automatically captured. + */ expiry: null | string; + + /** + * The current status of this image. + */ status: ImageStatus; + + /** + * A list of the capabilities of this image. + */ capabilities: ImageCapabilities[]; + + /** + * A list of the regions in which this image is available. + */ regions: ImageRegion[]; + + /** + * A list of tags added to this image. + */ tags: string[]; }