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..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 @@ -13,7 +13,10 @@ import { useEditCluster, useUpdateKarpenterPrivateFargate, } from '@qovery/domains/clusters/feature' -import { type ClusterResourcesEdit, type SCWControlPlaneFeatureType } from '@qovery/shared/interfaces' +import { + type ClusterResourcesEdit, + type SCWControlPlaneFeatureType, +} from '@qovery/shared/interfaces' import { useModal } from '@qovery/shared/ui' import { PageSettingsResources } from '../../ui/page-settings-resources/page-settings-resources' @@ -27,6 +30,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 +45,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 +60,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 +109,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..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 @@ -251,9 +251,11 @@ 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, - }, + } as any, }) } @@ -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..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 @@ -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..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 @@ -37,6 +37,12 @@ export interface ClusterKubeconfigData { export interface KarpenterData extends ClusterFeatureKarpenterParameters { enabled: boolean + qovery_node_pools: ClusterFeatureKarpenterParameters['qovery_node_pools'] & { + gpu_override?: ClusterFeatureKarpenterParameters['qovery_node_pools']['gpu_override'] & { + disk_iops?: number + disk_throughput?: number + } + } } export interface ClusterResourcesData { @@ -44,6 +50,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?: { diff --git a/package.json b/package.json index f6ed56b2c06..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.814", + "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 2e8ec7c927e..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.814 + 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.814": - version: 1.1.814 - resolution: "qovery-typescript-axios@npm:1.1.814" +"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: f7ad5bb89dab893a06efaafa9b8570ff6f5a1589e4e774d2ddb2e5fced09ad6b3aa3fac24b1ae117ec8db2efd5875efc431a65683bc54f4d5dc054dfc61376c2 + checksum: 092da0eceed47a368f26abe069bda9817cd4c943963f276d3744fa9407bb4d2d4ba095ecf4c041be4ca2d412473711f03e20432985552490f1af3de4f9e7fe39 languageName: node linkType: hard