From d1cb6cfea8d3f477fbab2d0578992f4ad306cd1c Mon Sep 17 00:00:00 2001 From: Vincent Germain Date: Thu, 12 Jan 2023 11:12:36 +0100 Subject: [PATCH 1/3] feat: temporary function to updateImage --- .../clients/src/api/instance/v1/api.utils.ts | 48 ++++++++++++++++++- .../src/api/instance/v1/types.utils.ts | 14 ++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/packages/clients/src/api/instance/v1/api.utils.ts b/packages/clients/src/api/instance/v1/api.utils.ts index 5f96f543d..94aa8d775 100644 --- a/packages/clients/src/api/instance/v1/api.utils.ts +++ b/packages/clients/src/api/instance/v1/api.utils.ts @@ -1,3 +1,4 @@ +import { validatePathParam } from '../../../bridge' import { createExponentialBackoffStrategy, tryAtIntervals, @@ -11,6 +12,10 @@ import { SNAPSHOT_TRANSIENT_STATUSES, VOLUME_TRANSIENT_STATUSES, } from './content.gen' +import { + marshalSetImageRequest, + unmarshalSetImageResponse, +} from './marshalling.gen' import type { GetImageRequest, GetPrivateNICRequest, @@ -26,13 +31,18 @@ import type { Volume, VolumeServerTemplate, } from './types.gen' -import type { SetSecurityGroupRuleRequest } from './types.private.gen' +import type { + SetImageResponse, + SetSecurityGroupRuleRequest, +} from './types.private.gen' import type { AttachVolumeRequest, AttachVolumeResponse, CreateServerRequest, DetachVolumeRequest, DetachVolumeResponse, + UpdateImageRequest, + UpdateImageResponse, UpdateSecurityGroupRequest, UpdateSecurityGroupResponse, UpdateSecurityGroupRuleRequest, @@ -467,4 +477,40 @@ export class InstanceV1UtilsAPI extends API { zone: request.zone, } as UpdateServerRequest).then(obj => obj as DetachVolumeResponse) } + + /** + * Updates an image. + * + * @param request - The request {@link UpdateImageRequest} + * @returns A Promise of UpdateImageResponse + */ + updateImage = ( + request: Readonly, + ): Promise => + this.getImage(request) + .then(res => validateNotUndefined(res.image)) + .then(image => ({ + ...image, + name: request.name ?? image.name, + public: request.public ?? image.public, + tags: request.tags ?? image.tags, + id: image.id, + })) + .then(imageReq => + this.client.fetch( + { + body: JSON.stringify( + marshalSetImageRequest(imageReq, this.client.settings), + ), + headers: { 'Content-Type': 'application/json; charset=utf-8' }, + method: 'PUT', + path: `/instance/v1/zones/${validatePathParam( + 'zone', + imageReq.zone ?? this.client.settings.defaultZone, + )}/images/${validatePathParam('id', imageReq.id)}`, + }, + unmarshalSetImageResponse, + ), + ) + .then(res => ({ image: res.image })) } diff --git a/packages/clients/src/api/instance/v1/types.utils.ts b/packages/clients/src/api/instance/v1/types.utils.ts index 1e2c79709..0e51875ff 100644 --- a/packages/clients/src/api/instance/v1/types.utils.ts +++ b/packages/clients/src/api/instance/v1/types.utils.ts @@ -1,5 +1,6 @@ import type { Zone } from '../../../scw/locality' import type { + Image, SecurityGroup, SecurityGroupPolicy, SecurityGroupRule, @@ -93,6 +94,19 @@ export interface DetachVolumeResponse { server?: Server } +export type UpdateImageRequest = { + /** Zone to target. If none is passed will use default zone from the config */ + zone?: Zone + imageId: string + name?: string + public?: boolean + tags?: string[] +} + +export interface UpdateImageResponse { + image?: Image +} + export type { CreateServerRequest, UpdateServerRequest, From ee9d0bd2032566b98462ab5fd07527d6d8accbd5 Mon Sep 17 00:00:00 2001 From: Vincent Germain Date: Thu, 12 Jan 2023 11:26:10 +0100 Subject: [PATCH 2/3] fix: adjust a few things --- packages/clients/src/api/instance/v1/api.utils.ts | 3 +-- packages/clients/src/api/instance/v1/types.utils.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/clients/src/api/instance/v1/api.utils.ts b/packages/clients/src/api/instance/v1/api.utils.ts index 94aa8d775..142a83540 100644 --- a/packages/clients/src/api/instance/v1/api.utils.ts +++ b/packages/clients/src/api/instance/v1/api.utils.ts @@ -487,12 +487,11 @@ export class InstanceV1UtilsAPI extends API { updateImage = ( request: Readonly, ): Promise => - this.getImage(request) + this.getImage({ zone: request.zone, imageId: request.imageId }) .then(res => validateNotUndefined(res.image)) .then(image => ({ ...image, name: request.name ?? image.name, - public: request.public ?? image.public, tags: request.tags ?? image.tags, id: image.id, })) diff --git a/packages/clients/src/api/instance/v1/types.utils.ts b/packages/clients/src/api/instance/v1/types.utils.ts index 0e51875ff..4a2ab0268 100644 --- a/packages/clients/src/api/instance/v1/types.utils.ts +++ b/packages/clients/src/api/instance/v1/types.utils.ts @@ -99,7 +99,6 @@ export type UpdateImageRequest = { zone?: Zone imageId: string name?: string - public?: boolean tags?: string[] } From 578a18aab3c35eb6ba1018e62cf3456b57edd372 Mon Sep 17 00:00:00 2001 From: Vincent Germain Date: Thu, 12 Jan 2023 13:41:27 +0100 Subject: [PATCH 3/3] fix: use custom marshalling to send id as body parameter --- .../clients/src/api/instance/v1/api.utils.ts | 8 +- .../src/api/instance/v1/marshalling.utils.ts | 97 +++++++++++++++++++ 2 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 packages/clients/src/api/instance/v1/marshalling.utils.ts diff --git a/packages/clients/src/api/instance/v1/api.utils.ts b/packages/clients/src/api/instance/v1/api.utils.ts index 142a83540..51b053e80 100644 --- a/packages/clients/src/api/instance/v1/api.utils.ts +++ b/packages/clients/src/api/instance/v1/api.utils.ts @@ -12,10 +12,8 @@ import { SNAPSHOT_TRANSIENT_STATUSES, VOLUME_TRANSIENT_STATUSES, } from './content.gen' -import { - marshalSetImageRequest, - unmarshalSetImageResponse, -} from './marshalling.gen' +import { unmarshalSetImageResponse } from './marshalling.gen' +import { marshalSetImageRequestWithID } from './marshalling.utils' import type { GetImageRequest, GetPrivateNICRequest, @@ -499,7 +497,7 @@ export class InstanceV1UtilsAPI extends API { this.client.fetch( { body: JSON.stringify( - marshalSetImageRequest(imageReq, this.client.settings), + marshalSetImageRequestWithID(imageReq, this.client.settings), ), headers: { 'Content-Type': 'application/json; charset=utf-8' }, method: 'PUT', diff --git a/packages/clients/src/api/instance/v1/marshalling.utils.ts b/packages/clients/src/api/instance/v1/marshalling.utils.ts new file mode 100644 index 000000000..9d7f7cc8d --- /dev/null +++ b/packages/clients/src/api/instance/v1/marshalling.utils.ts @@ -0,0 +1,97 @@ +import { type DefaultValues } from '../../../bridge' +import type { + Bootscript, + ServerSummary, + Volume, + VolumeSummary, +} from './types.gen' +import type { SetImageRequest } from './types.private.gen' + +const marshalVolumeSummary = ( + request: VolumeSummary, + defaults: DefaultValues, +): Record => ({ + id: request.id, + name: request.name, + size: request.size, + volume_type: request.volumeType, +}) + +const marshalServerSummary = ( + request: ServerSummary, + defaults: DefaultValues, +): Record => ({ + id: request.id, + name: request.name, +}) + +const marshalBootscript = ( + request: Bootscript, + defaults: DefaultValues, +): Record => ({ + arch: request.arch, + bootcmdargs: request.bootcmdargs, + default: request.default, + dtb: request.dtb, + id: request.id, + initrd: request.initrd, + kernel: request.kernel, + organization: request.organization, + project: request.project, + public: request.public, + title: request.title, + zone: request.zone, +}) + +const marshalVolume = ( + request: Volume, + defaults: DefaultValues, +): Record => ({ + creation_date: request.creationDate, + export_uri: request.exportUri, + id: request.id, + modification_date: request.modificationDate, + name: request.name, + organization: request.organization, + project: request.project, + server: request.server + ? marshalServerSummary(request.server, defaults) + : undefined, + size: request.size, + state: request.state, + tags: request.tags, + volume_type: request.volumeType, + zone: request.zone, +}) + +export const marshalSetImageRequestWithID = ( + request: SetImageRequest, + defaults: DefaultValues, +): Record => ({ + arch: request.arch, + creation_date: request.creationDate, + default_bootscript: request.defaultBootscript + ? marshalBootscript(request.defaultBootscript, defaults) + : undefined, + extra_volumes: request.extraVolumes + ? Object.entries(request.extraVolumes).reduce( + (acc, [key, value]) => ({ + ...acc, + [key]: marshalVolume(value, defaults), + }), + {}, + ) + : undefined, + from_server: request.fromServer, + modification_date: request.modificationDate, + id: request.id, + name: request.name, + organization: request.organization, + project: request.project, + public: request.public, + root_volume: request.rootVolume + ? marshalVolumeSummary(request.rootVolume, defaults) + : undefined, + state: request.state, + tags: request.tags, +})