From 98cc0e0bd94a65f99b8e5541f7bc8aa24a41dde4 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Mon, 26 Jan 2026 12:16:59 +0100 Subject: [PATCH 1/7] feat: add UI for disk IOPS and throughput configuration on AWS nodepools Add user interface for configuring IOPS and throughput on AWS EBS gp3 volumes for cluster nodepools. Changes: - Add disk_iops and disk_throughput to ClusterResourcesData and KarpenterData interfaces - Add IOPS/throughput input fields in cluster resources settings (non-Karpenter, Karpenter stable, Karpenter GPU) - Update cluster creation flow to include IOPS/throughput in API requests - Update cluster edit flow to handle IOPS/throughput updates - Add default values in cluster factory mocks for testing - Fields are optional and only displayed for AWS clusters The UI provides hints for valid value ranges: - IOPS: 3000-16000 for EBS gp3 - Throughput: 125-1000 MB/s for EBS gp3 --- .../page-settings-resources-feature.tsx | 10 ++ .../step-summary-feature.tsx | 4 + .../cluster-resources-settings.tsx | 154 +++++++++++++++--- .../factories/src/lib/cluster-factory.mock.ts | 2 + .../domain/cluster-creation-flow.interface.ts | 4 + 5 files changed, 151 insertions(+), 23 deletions(-) diff --git a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx index 29fc2c84711..f595acb5063 100644 --- a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx +++ b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx @@ -27,6 +27,8 @@ export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { max_running_nodes: data['nodes'][1], min_running_nodes: data['nodes'][0], disk_size: data['disk_size'], + disk_iops: cluster.cloud_provider === 'AWS' ? data['disk_iops'] : undefined, + disk_throughput: cluster.cloud_provider === 'AWS' ? data['disk_throughput'] : undefined, instance_type: data['instance_type'], } @@ -40,6 +42,8 @@ export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { value: { spot_enabled: data['karpenter'].spot_enabled ?? false, disk_size_in_gib: data['karpenter'].disk_size_in_gib, + disk_iops: data['karpenter'].disk_iops, + disk_throughput: data['karpenter'].disk_throughput, default_service_architecture: data['karpenter'].default_service_architecture, qovery_node_pools: data['karpenter'].qovery_node_pools, }, @@ -53,6 +57,8 @@ export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { value: { spot_enabled: data['karpenter'].spot_enabled ?? false, disk_size_in_gib: data['karpenter'].disk_size_in_gib, + disk_iops: data['karpenter'].disk_iops, + disk_throughput: data['karpenter'].disk_throughput, default_service_architecture: data['karpenter'].default_service_architecture, qovery_node_pools: data['karpenter'].qovery_node_pools, }, @@ -100,11 +106,15 @@ function SettingsResourcesFeature({ cluster }: SettingsResourcesFeatureProps) { instance_type: cluster.instance_type, nodes: [cluster.min_running_nodes || 1, cluster.max_running_nodes || 1], disk_size: cluster.disk_size || 0, + disk_iops: cluster.disk_iops, + disk_throughput: cluster.disk_throughput, karpenter: karpenterFeature ? { enabled: true, spot_enabled: karpenterFeature.value.spot_enabled, disk_size_in_gib: karpenterFeature.value.disk_size_in_gib, + disk_iops: karpenterFeature.value.disk_iops, + disk_throughput: karpenterFeature.value.disk_throughput, default_service_architecture: karpenterFeature.value.default_service_architecture, qovery_node_pools: karpenterFeature.value.qovery_node_pools, } diff --git a/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx b/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx index f0ef031c32a..fcee25a3c26 100644 --- a/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx +++ b/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx @@ -251,6 +251,8 @@ export function StepSummaryFeature() { value: { spot_enabled: resourcesData.karpenter.spot_enabled, disk_size_in_gib: resourcesData.karpenter.disk_size_in_gib, + disk_iops: resourcesData.karpenter.disk_iops, + disk_throughput: resourcesData.karpenter.disk_throughput, default_service_architecture: resourcesData.karpenter.default_service_architecture, qovery_node_pools: resourcesData.karpenter.qovery_node_pools, }, @@ -341,6 +343,8 @@ export function StepSummaryFeature() { min_running_nodes: resourcesData.nodes[0], max_running_nodes: resourcesData.nodes[1], disk_size: resourcesData.disk_size, + disk_iops: generalData.cloud_provider === 'AWS' ? resourcesData.disk_iops : undefined, + disk_throughput: generalData.cloud_provider === 'AWS' ? resourcesData.disk_throughput : undefined, instance_type: resourcesData.instance_type, kubernetes: resourcesData.cluster_type as KubernetesEnum, features: formatFeatures as ClusterRequestFeaturesInner[], diff --git a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx index 704298ad637..6bf0967cacd 100644 --- a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx +++ b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx @@ -386,7 +386,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { )} {props.fromDetail && ( -
+
)} /> +
+ ( + + )} + /> + ( + + )} + /> +
)}
@@ -481,7 +513,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { /> {props.fromDetail && ( -
+
)} /> +
+ ( + + )} + /> + ( + + )} + /> +
)} {watchKarpenterEnabled && props.cluster && ( @@ -556,28 +620,72 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { )} /> {props.fromDetail && ( - ( - { - field.onChange(event) - if (props.fromDetail) { - setWarningClusterNodes(true) - } - }} - value={field.value} - label="Disk size (GB)" - hint="Storage allocated to your Kubernetes nodes to store files, application images etc.." - /> + <> + ( + { + field.onChange(event) + if (props.fromDetail) { + setWarningClusterNodes(true) + } + }} + value={field.value} + label="Disk size (GB)" + hint="Storage allocated to your Kubernetes nodes to store files, application images etc.." + /> + )} + /> + {props.cloudProvider === 'AWS' && ( +
+ ( + { + field.onChange(event) + if (props.fromDetail) { + setWarningClusterNodes(true) + } + }} + value={field.value} + label="Disk IOPS (optional)" + hint="I/O operations per second for EBS gp3 volumes (3000-16000)" + /> + )} + /> + ( + { + field.onChange(event) + if (props.fromDetail) { + setWarningClusterNodes(true) + } + }} + value={field.value} + label="Disk throughput (optional)" + hint="Throughput in MB/s for EBS gp3 volumes (125-1000)" + /> + )} + /> +
)} - /> + )} {warningClusterNodes && ( diff --git a/libs/shared/factories/src/lib/cluster-factory.mock.ts b/libs/shared/factories/src/lib/cluster-factory.mock.ts index e50d993993f..4cfd338aa25 100644 --- a/libs/shared/factories/src/lib/cluster-factory.mock.ts +++ b/libs/shared/factories/src/lib/cluster-factory.mock.ts @@ -18,6 +18,8 @@ export const clusterFactoryMock = (howMany: number, customCloudProvider?: CloudP min_running_nodes: 1, max_running_nodes: 5, disk_size: 20, + disk_iops: customCloudProvider === CloudProviderEnum.AWS ? 3000 : undefined, + disk_throughput: customCloudProvider === CloudProviderEnum.AWS ? 125 : undefined, status: chance.pickone(Object.values(ClusterStateEnum)), is_default: false, version: '1.22', diff --git a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts index 48e64b1fc4a..a3a95892603 100644 --- a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts +++ b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts @@ -37,6 +37,8 @@ export interface ClusterKubeconfigData { export interface KarpenterData extends ClusterFeatureKarpenterParameters { enabled: boolean + disk_iops?: number + disk_throughput?: number } export interface ClusterResourcesData { @@ -44,6 +46,8 @@ export interface ClusterResourcesData { instance_type: string nodes: [number, number] disk_size: number + disk_iops?: number + disk_throughput?: number karpenter?: KarpenterData scw_control_plane?: SCWControlPlaneFeatureType infrastructure_charts_parameters?: { From 0f5eb8eec1fb1220c591c358d2a2d3e4affc1afc Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Mon, 26 Jan 2026 14:04:55 +0100 Subject: [PATCH 2/7] feat: clarify disk IOPS/throughput requires gp3 storage class Update hints for disk IOPS and throughput fields to indicate they are only available with AWS EBS gp3 storage class. This provides better user guidance and prevents configuration errors. --- .../cluster-resources-settings.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx index 6bf0967cacd..d16d8b6901d 100644 --- a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx +++ b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx @@ -418,7 +418,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="I/O operations per second for EBS gp3 volumes (3000-16000)" + hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." /> )} /> @@ -433,7 +433,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000)" + hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." /> )} /> @@ -545,7 +545,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="I/O operations per second for EBS gp3 volumes (3000-16000)" + hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." /> )} /> @@ -560,7 +560,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000)" + hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." /> )} /> @@ -660,7 +660,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { }} value={field.value} label="Disk IOPS (optional)" - hint="I/O operations per second for EBS gp3 volumes (3000-16000)" + hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." /> )} /> @@ -679,7 +679,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { }} value={field.value} label="Disk throughput (optional)" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000)" + hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." /> )} /> From bd90fe0bc0b16b76f8b71c8cd83a8547c83683e0 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Mon, 26 Jan 2026 14:15:18 +0100 Subject: [PATCH 3/7] feat: add TypeScript types for disk IOPS/throughput fields Add extended interfaces to support disk_iops and disk_throughput fields for cluster nodepools and Karpenter GPU nodes until the API client is regenerated with the latest backend schema. - ClusterExtended: extends Cluster with disk_iops and disk_throughput - ClusterFeatureKarpenterParametersExtended: extends Karpenter params - KarpenterGpuNodePoolOverrideExtended: extends GPU override with IOPS/throughput --- .../page-settings-resources-feature.tsx | 13 ++++--- .../step-summary-feature.tsx | 2 +- libs/shared/interfaces/src/index.ts | 1 + .../domain/cluster-creation-flow.interface.ts | 16 +++++---- .../lib/domain/cluster-extended.interface.ts | 35 +++++++++++++++++++ 5 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts diff --git a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx index f595acb5063..0ec8d3e77ef 100644 --- a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx +++ b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx @@ -13,7 +13,12 @@ import { useEditCluster, useUpdateKarpenterPrivateFargate, } from '@qovery/domains/clusters/feature' -import { type ClusterResourcesEdit, type SCWControlPlaneFeatureType } from '@qovery/shared/interfaces' +import { + type ClusterExtended, + type ClusterFeatureKarpenterParametersResponseExtended, + type ClusterResourcesEdit, + type SCWControlPlaneFeatureType, +} from '@qovery/shared/interfaces' import { useModal } from '@qovery/shared/ui' import { PageSettingsResources } from '../../ui/page-settings-resources/page-settings-resources' @@ -21,7 +26,7 @@ function getValueByKey(key: string, data: { [key: string]: string }[] = []): str return data.filter((obj) => key in obj).map((obj) => obj[key]) } -export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { +export const handleSubmit = (data: FieldValues, cluster: ClusterExtended): ClusterExtended => { const payload = { ...cluster, max_running_nodes: data['nodes'][1], @@ -86,13 +91,13 @@ export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { } export interface SettingsResourcesFeatureProps { - cluster: Cluster + cluster: ClusterExtended } function SettingsResourcesFeature({ cluster }: SettingsResourcesFeatureProps) { const karpenterFeature = cluster.features?.find( (feature) => feature.id === 'KARPENTER' - ) as ClusterFeatureKarpenterParametersResponse + ) as ClusterFeatureKarpenterParametersResponseExtended const scwFeature = cluster.features?.find( (feature) => feature.id === SCW_CONTROL_PLANE_FEATURE_ID ) as ClusterFeatureStringResponse diff --git a/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx b/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx index fcee25a3c26..4e30c75c51c 100644 --- a/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx +++ b/libs/pages/clusters/src/lib/feature/page-clusters-create-feature/step-summary-feature/step-summary-feature.tsx @@ -255,7 +255,7 @@ export function StepSummaryFeature() { disk_throughput: resourcesData.karpenter.disk_throughput, default_service_architecture: resourcesData.karpenter.default_service_architecture, qovery_node_pools: resourcesData.karpenter.qovery_node_pools, - }, + } as any, }) } diff --git a/libs/shared/interfaces/src/index.ts b/libs/shared/interfaces/src/index.ts index 2ba191677a2..aa48d5d274f 100644 --- a/libs/shared/interfaces/src/index.ts +++ b/libs/shared/interfaces/src/index.ts @@ -7,6 +7,7 @@ export * from './lib/domain/service-running-status.interface' export * from './lib/domain/application-creation-flow.interface' export * from './lib/domain/job-creation-flow.interface' export * from './lib/domain/cluster-creation-flow.interface' +export * from './lib/domain/cluster-extended.interface' export * from './lib/types/loading-status.type' export * from './lib/types/deployment-service.type' diff --git a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts index a3a95892603..e23d62f1754 100644 --- a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts +++ b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts @@ -1,8 +1,4 @@ -import { - type CloudProviderEnum, - type ClusterFeatureKarpenterParameters, - type ClusterKeda, -} from 'qovery-typescript-axios' +import { type CloudProviderEnum, type ClusterFeatureKarpenterParameters } from 'qovery-typescript-axios' export interface ClusterGeneralData { name: string @@ -24,7 +20,7 @@ export interface ClusterGeneralData { } } } - keda?: ClusterKeda + keda?: unknown } export type SCWControlPlaneFeatureType = 'KAPSULE' | 'KAPSULE_DEDICATED4' | 'KAPSULE_DEDICATED8' | 'KAPSULE_DEDICATED16' @@ -35,10 +31,16 @@ export interface ClusterKubeconfigData { file_size: number } -export interface KarpenterData extends ClusterFeatureKarpenterParameters { +export interface KarpenterData extends Omit { enabled: boolean disk_iops?: number disk_throughput?: number + qovery_node_pools: ClusterFeatureKarpenterParameters['qovery_node_pools'] & { + gpu_override?: ClusterFeatureKarpenterParameters['qovery_node_pools']['gpu_override'] & { + disk_iops?: number + disk_throughput?: number + } + } } export interface ClusterResourcesData { diff --git a/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts new file mode 100644 index 00000000000..541a183c512 --- /dev/null +++ b/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts @@ -0,0 +1,35 @@ +import { + type Cluster, + type ClusterFeatureKarpenterParameters, + type ClusterFeatureKarpenterParametersResponse, + type KarpenterGpuNodePoolOverride, +} from 'qovery-typescript-axios' + +// Extended GPU override with disk_iops and disk_throughput +export interface KarpenterGpuNodePoolOverrideExtended extends KarpenterGpuNodePoolOverride { + disk_iops?: number + disk_throughput?: number +} + +// Extended Karpenter parameters with disk_iops and disk_throughput +export interface ClusterFeatureKarpenterParametersExtended + extends Omit { + disk_iops?: number + disk_throughput?: number + qovery_node_pools: Omit & { + gpu_override?: KarpenterGpuNodePoolOverrideExtended + } +} + +// Extended Karpenter feature response with extended parameters +export interface ClusterFeatureKarpenterParametersResponseExtended + extends Omit { + value: ClusterFeatureKarpenterParametersExtended +} + +// Extended Cluster type with disk_iops and disk_throughput fields +// These will be available once the API client is regenerated +export interface ClusterExtended extends Cluster { + disk_iops?: number + disk_throughput?: number +} From 13f66a2c2bbcf5a602b509f55ce9fbed4f57fcda Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Mon, 26 Jan 2026 14:39:37 +0100 Subject: [PATCH 4/7] revert: restore original ClusterKeda type import Use ClusterKeda type from qovery-typescript-axios instead of custom interface to maintain consistency with generated API types. --- .../src/lib/domain/cluster-creation-flow.interface.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts index e23d62f1754..7002c75053c 100644 --- a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts +++ b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts @@ -1,4 +1,8 @@ -import { type CloudProviderEnum, type ClusterFeatureKarpenterParameters } from 'qovery-typescript-axios' +import { + type CloudProviderEnum, + type ClusterFeatureKarpenterParameters, + type ClusterKeda, +} from 'qovery-typescript-axios' export interface ClusterGeneralData { name: string @@ -20,7 +24,7 @@ export interface ClusterGeneralData { } } } - keda?: unknown + keda?: ClusterKeda } export type SCWControlPlaneFeatureType = 'KAPSULE' | 'KAPSULE_DEDICATED4' | 'KAPSULE_DEDICATED8' | 'KAPSULE_DEDICATED16' From a08671fb7000dc438e9b00084537157c7a8d9287 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Tue, 27 Jan 2026 09:45:45 +0100 Subject: [PATCH 5/7] refactor: simplify disk IOPS/throughput hints by removing storage class mention Remove 'Only available with gp3 storage class' from form hints as gp3 is the default storage class, making the UI lighter and cleaner. --- .../cluster-resources-settings.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx index d16d8b6901d..21139df7a5c 100644 --- a/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx +++ b/libs/shared/console-shared/src/lib/cluster-settings/ui/cluster-resources-settings/cluster-resources-settings.tsx @@ -418,7 +418,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." + hint="I/O operations per second for EBS gp3 volumes (3000-16000)." /> )} /> @@ -433,7 +433,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." + hint="Throughput in MB/s for EBS gp3 volumes (125-1000)." /> )} /> @@ -545,7 +545,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." + hint="I/O operations per second for EBS gp3 volumes (3000-16000)." /> )} /> @@ -560,7 +560,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { onChange={field.onChange} value={field.value} className="w-full" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." + hint="Throughput in MB/s for EBS gp3 volumes (125-1000)." /> )} /> @@ -660,7 +660,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { }} value={field.value} label="Disk IOPS (optional)" - hint="I/O operations per second for EBS gp3 volumes (3000-16000). Only available with gp3 storage class." + hint="I/O operations per second for EBS gp3 volumes (3000-16000)." /> )} /> @@ -679,7 +679,7 @@ export function ClusterResourcesSettings(props: ClusterResourcesSettingsProps) { }} value={field.value} label="Disk throughput (optional)" - hint="Throughput in MB/s for EBS gp3 volumes (125-1000). Only available with gp3 storage class." + hint="Throughput in MB/s for EBS gp3 volumes (125-1000)." /> )} /> From 1a9ccd30ff2c1ef36449866cb1d44cf5a3761f4d Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Wed, 28 Jan 2026 10:43:50 +0100 Subject: [PATCH 6/7] chore(console): upgrade qovery-typescript-axios and remove redundant extensions - Upgrade qovery-typescript-axios from 1.1.812 to 1.1.816 - Remove ClusterExtended interface as Cluster now includes disk_iops and disk_throughput - Simplify ClusterFeatureKarpenterParametersExtended by removing redundant disk_iops/disk_throughput - Keep KarpenterGpuNodePoolOverrideExtended as gpu_override doesn't have these fields yet in generated client - Update page-settings-resources-feature to use Cluster instead of ClusterExtended --- .../page-settings-resources-feature.tsx | 3 +-- .../lib/domain/cluster-creation-flow.interface.ts | 4 +--- .../src/lib/domain/cluster-extended.interface.ts | 14 +++----------- package.json | 2 +- yarn.lock | 10 +++++----- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx index 0ec8d3e77ef..5c43f30d3d3 100644 --- a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx +++ b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx @@ -14,7 +14,6 @@ import { useUpdateKarpenterPrivateFargate, } from '@qovery/domains/clusters/feature' import { - type ClusterExtended, type ClusterFeatureKarpenterParametersResponseExtended, type ClusterResourcesEdit, type SCWControlPlaneFeatureType, @@ -26,7 +25,7 @@ function getValueByKey(key: string, data: { [key: string]: string }[] = []): str return data.filter((obj) => key in obj).map((obj) => obj[key]) } -export const handleSubmit = (data: FieldValues, cluster: ClusterExtended): ClusterExtended => { +export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { const payload = { ...cluster, max_running_nodes: data['nodes'][1], diff --git a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts index 7002c75053c..350a6a25c3e 100644 --- a/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts +++ b/libs/shared/interfaces/src/lib/domain/cluster-creation-flow.interface.ts @@ -35,10 +35,8 @@ export interface ClusterKubeconfigData { file_size: number } -export interface KarpenterData extends Omit { +export interface KarpenterData extends ClusterFeatureKarpenterParameters { enabled: boolean - disk_iops?: number - disk_throughput?: number qovery_node_pools: ClusterFeatureKarpenterParameters['qovery_node_pools'] & { gpu_override?: ClusterFeatureKarpenterParameters['qovery_node_pools']['gpu_override'] & { disk_iops?: number diff --git a/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts index 541a183c512..fa46d213943 100644 --- a/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts +++ b/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts @@ -1,21 +1,20 @@ import { - type Cluster, type ClusterFeatureKarpenterParameters, type ClusterFeatureKarpenterParametersResponse, type KarpenterGpuNodePoolOverride, } from 'qovery-typescript-axios' // Extended GPU override with disk_iops and disk_throughput +// TODO: Remove this extension once KarpenterGpuNodePoolOverride includes disk_iops and disk_throughput in the generated client export interface KarpenterGpuNodePoolOverrideExtended extends KarpenterGpuNodePoolOverride { disk_iops?: number disk_throughput?: number } -// Extended Karpenter parameters with disk_iops and disk_throughput +// Extended Karpenter parameters with gpu_override extension +// Only needed to extend gpu_override with disk_iops/disk_throughput fields export interface ClusterFeatureKarpenterParametersExtended extends Omit { - disk_iops?: number - disk_throughput?: number qovery_node_pools: Omit & { gpu_override?: KarpenterGpuNodePoolOverrideExtended } @@ -26,10 +25,3 @@ export interface ClusterFeatureKarpenterParametersResponseExtended extends Omit { value: ClusterFeatureKarpenterParametersExtended } - -// Extended Cluster type with disk_iops and disk_throughput fields -// These will be available once the API client is regenerated -export interface ClusterExtended extends Cluster { - disk_iops?: number - disk_throughput?: number -} diff --git a/package.json b/package.json index 817090a25dd..09c410cf3f1 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "mermaid": "^11.6.0", "monaco-editor": "0.53.0", "posthog-js": "^1.260.1", - "qovery-typescript-axios": "^1.1.812", + "qovery-typescript-axios": "^1.1.816", "react": "18.3.1", "react-country-flag": "^3.0.2", "react-datepicker": "^4.12.0", diff --git a/yarn.lock b/yarn.lock index b078280b2b1..ff9450a7c64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5679,7 +5679,7 @@ __metadata: prettier: ^3.2.5 prettier-plugin-tailwindcss: ^0.5.14 pretty-quick: ^4.0.0 - qovery-typescript-axios: ^1.1.812 + qovery-typescript-axios: ^1.1.816 qovery-ws-typescript-axios: ^0.1.420 react: 18.3.1 react-country-flag: ^3.0.2 @@ -24520,12 +24520,12 @@ __metadata: languageName: node linkType: hard -"qovery-typescript-axios@npm:^1.1.812": - version: 1.1.812 - resolution: "qovery-typescript-axios@npm:1.1.812" +"qovery-typescript-axios@npm:^1.1.816": + version: 1.1.816 + resolution: "qovery-typescript-axios@npm:1.1.816" dependencies: axios: 1.12.2 - checksum: f682cdeb07aa02164c9ee75a1ef8c914a0584e5fc1a3265c65a7583976af7b16d4a13e485e1e29f946ed1e9033aa378f152636a21793326773503bb2eb882714 + checksum: 092da0eceed47a368f26abe069bda9817cd4c943963f276d3744fa9407bb4d2d4ba095ecf4c041be4ca2d412473711f03e20432985552490f1af3de4f9e7fe39 languageName: node linkType: hard From 75e13f189d179c17d31423a4de350461574eec71 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Wed, 28 Jan 2026 10:50:40 +0100 Subject: [PATCH 7/7] chore(console): remove all remaining Extended interfaces - Remove cluster-extended.interface.ts file entirely - Replace ClusterExtended with Cluster in page-settings-resources-feature - Replace ClusterFeatureKarpenterParametersResponseExtended with ClusterFeatureKarpenterParametersResponse - All disk_iops and disk_throughput fields now come directly from qovery-typescript-axios client --- .../page-settings-resources-feature.tsx | 5 ++-- libs/shared/interfaces/src/index.ts | 1 - .../lib/domain/cluster-extended.interface.ts | 27 ------------------- 3 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts diff --git a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx index 5c43f30d3d3..58a2e865dde 100644 --- a/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx +++ b/libs/pages/cluster/src/lib/feature/page-settings-resources-feature/page-settings-resources-feature.tsx @@ -14,7 +14,6 @@ import { useUpdateKarpenterPrivateFargate, } from '@qovery/domains/clusters/feature' import { - type ClusterFeatureKarpenterParametersResponseExtended, type ClusterResourcesEdit, type SCWControlPlaneFeatureType, } from '@qovery/shared/interfaces' @@ -90,13 +89,13 @@ export const handleSubmit = (data: FieldValues, cluster: Cluster): Cluster => { } export interface SettingsResourcesFeatureProps { - cluster: ClusterExtended + cluster: Cluster } function SettingsResourcesFeature({ cluster }: SettingsResourcesFeatureProps) { const karpenterFeature = cluster.features?.find( (feature) => feature.id === 'KARPENTER' - ) as ClusterFeatureKarpenterParametersResponseExtended + ) as ClusterFeatureKarpenterParametersResponse const scwFeature = cluster.features?.find( (feature) => feature.id === SCW_CONTROL_PLANE_FEATURE_ID ) as ClusterFeatureStringResponse diff --git a/libs/shared/interfaces/src/index.ts b/libs/shared/interfaces/src/index.ts index aa48d5d274f..2ba191677a2 100644 --- a/libs/shared/interfaces/src/index.ts +++ b/libs/shared/interfaces/src/index.ts @@ -7,7 +7,6 @@ export * from './lib/domain/service-running-status.interface' export * from './lib/domain/application-creation-flow.interface' export * from './lib/domain/job-creation-flow.interface' export * from './lib/domain/cluster-creation-flow.interface' -export * from './lib/domain/cluster-extended.interface' export * from './lib/types/loading-status.type' export * from './lib/types/deployment-service.type' diff --git a/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts b/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts deleted file mode 100644 index fa46d213943..00000000000 --- a/libs/shared/interfaces/src/lib/domain/cluster-extended.interface.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - type ClusterFeatureKarpenterParameters, - type ClusterFeatureKarpenterParametersResponse, - type KarpenterGpuNodePoolOverride, -} from 'qovery-typescript-axios' - -// Extended GPU override with disk_iops and disk_throughput -// TODO: Remove this extension once KarpenterGpuNodePoolOverride includes disk_iops and disk_throughput in the generated client -export interface KarpenterGpuNodePoolOverrideExtended extends KarpenterGpuNodePoolOverride { - disk_iops?: number - disk_throughput?: number -} - -// Extended Karpenter parameters with gpu_override extension -// Only needed to extend gpu_override with disk_iops/disk_throughput fields -export interface ClusterFeatureKarpenterParametersExtended - extends Omit { - qovery_node_pools: Omit & { - gpu_override?: KarpenterGpuNodePoolOverrideExtended - } -} - -// Extended Karpenter feature response with extended parameters -export interface ClusterFeatureKarpenterParametersResponseExtended - extends Omit { - value: ClusterFeatureKarpenterParametersExtended -}