Skip to content

Commit

Permalink
feat(pci-block-storage): add exten beta (#13489)
Browse files Browse the repository at this point in the history
Extend volume capacity to 12To
Add banner for beta extension
Implement dependent regions on block tiles
ref: TAPC-1609, TAPC-2071, TAPC-2072, TAPC-1139, 
TAPC-1505, TAPC-2063, TAPC-1711, TAPC-1716, TAPC-1728,
TAPC-1938

Signed-off-by: Simon Chaumet <[email protected]>
Co-authored-by: Yann Lojewski <[email protected]>
Co-authored-by: CDS Translator Agent <[email protected]>
  • Loading branch information
3 people authored Oct 31, 2024
1 parent 8b1cbf8 commit d217168
Show file tree
Hide file tree
Showing 29 changed files with 232 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Mit Instanz verbinden",
"pci_projects_project_storages_blocks_create_backup_label": "Backup erstellen",
"pci_projects_project_storages_blocks_delete_label": "Löschen",
"pci_projects_project_storages_blocks_add_label": "Volume erstellen"
"pci_projects_project_storages_blocks_add_label": "Volume erstellen",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Attach to instance",
"pci_projects_project_storages_blocks_create_backup_label": "Create a backup ",
"pci_projects_project_storages_blocks_delete_label": "Delete",
"pci_projects_project_storages_blocks_add_label": "Create a volume "
"pci_projects_project_storages_blocks_add_label": "Create a volume ",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Asociar a la instancia",
"pci_projects_project_storages_blocks_create_backup_label": "Crear una copia de seguridad",
"pci_projects_project_storages_blocks_delete_label": "Eliminar",
"pci_projects_project_storages_blocks_add_label": "Crear un volumen"
"pci_projects_project_storages_blocks_add_label": "Crear un volumen",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Attacher à l'instance",
"pci_projects_project_storages_blocks_create_backup_label": "Créer une sauvegarde",
"pci_projects_project_storages_blocks_delete_label": "Supprimer",
"pci_projects_project_storages_blocks_add_label": "Créer un volume"
"pci_projects_project_storages_blocks_add_label": "Créer un volume",

"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Attacher à l'instance",
"pci_projects_project_storages_blocks_create_backup_label": "Créer une sauvegarde",
"pci_projects_project_storages_blocks_delete_label": "Supprimer",
"pci_projects_project_storages_blocks_add_label": "Créer un volume"
"pci_projects_project_storages_blocks_add_label": "Créer un volume",

"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Associa all’istanza",
"pci_projects_project_storages_blocks_create_backup_label": "Crea un backup",
"pci_projects_project_storages_blocks_delete_label": "Eliminare",
"pci_projects_project_storages_blocks_add_label": "Crea un volume"
"pci_projects_project_storages_blocks_add_label": "Crea un volume",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Podłącz do instancji",
"pci_projects_project_storages_blocks_create_backup_label": "Utwórz kopię zapasową",
"pci_projects_project_storages_blocks_delete_label": "Usuń",
"pci_projects_project_storages_blocks_add_label": "Utwórz wolumen"
"pci_projects_project_storages_blocks_add_label": "Utwórz wolumen",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"pci_projects_project_storages_blocks_instance_attach_label": "Associar a instância",
"pci_projects_project_storages_blocks_create_backup_label": "Criar uma cópia de segurança",
"pci_projects_project_storages_blocks_delete_label": "Eliminar",
"pci_projects_project_storages_blocks_add_label": "Criar um volume"
"pci_projects_project_storages_blocks_add_label": "Criar um volume",
"pci_projects_project_storages_blocks_new": "Beta"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Optimieren Sie Ihre Performance mit Block Storage NVMe over Fabric!\nErhältlich in der Betaphase in den Regionen {{regions}}, verdoppeln Sie die Performance Ihrer Classic Volumes und steigern Sie die Effizienz Ihrer rechenintensiven Aufgaben."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Optimize your performance with Block Storage NVMe over Fabric!\nAvailable in the beta phase in the {{regions}} regions, double the performance of your Classic volumes and improve the efficiency of your intensive workloads."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "¡Optimice su rendimiento con Block Storage NVMe over Fabric!\nDisponible en fase beta en las regiones {{regions}}, duplique el rendimiento de sus volúmenes Classic y mejore la eficiencia de sus cargas de trabajo intensivas."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Optimisez vos performances avec Block Storage NVMe over Fabric !\nDisponible en phase bêta dans les régions {{regions}}, doublez les performances de vos volumes Classic et améliorez l'efficacité de vos charges de travail intensives."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Optimisez vos performances avec Block Storage NVMe over Fabric !\nDisponible en phase bêta dans les régions {{regions}}, doublez les performances de vos volumes Classic et améliorez l'efficacité de vos charges de travail intensives."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Ottimizza le performance con Block Storage NVMe over Fabric!\nDisponibile in fase beta nelle Region {{regions}}, raddoppia le performance dei volumi Classic e migliora l'efficacia dei carichi di lavoro intensivi."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Zoptymalizuj swoją wydajność korzystając z Block Storage NVMe over Fabric!\nZwiększ wydajność wolumenów Classic i zwiększ wydajność w przypadku intensywnych obciążeń, dzięki czemu Twoje rozwiązania będą dostępne w fazie beta w regionach {{regions}}."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exten_banner_description": "Otimize as suas performances com o Block Storage NVMe over Fabric!\nDisponível na fase beta nas regiões {{regions}}, duplique os desempenhos dos seus volumes Classic e melhore a eficácia das suas cargas de trabalho intensivas."
}
39 changes: 36 additions & 3 deletions packages/manager/apps/pci-block-storage/src/api/data/quota.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { v6 } from '@ovh-ux/manager-core-api';
import { useFeatureAvailability } from '@ovh-ux/manager-react-components';
import { useMemo } from 'react';

export interface RegionQuota {
region: string;
Expand All @@ -12,9 +14,40 @@ export interface RegionQuota {

export const getRegionsQuota = async (
projectId: string,
): Promise<RegionQuota[]> => {
const { data } = await v6.get<RegionQuota[]>(
`/cloud/project/${projectId}/quota`,
region?: string,
): Promise<RegionQuota> => {
const { data } = await v6.get<RegionQuota>(
`/cloud/project/${projectId}/region/${region}/quota`,
);
return data;
};

function isLocalZone(region: string) {
return region.split('-')[2] === 'LZ';
}

function getVolumeMaxSize(region: string) {
return isLocalZone(region) ? 4 * 1000 : 12 * 1000;
}

export const FA_VOLUME_EXTEND_12TO = 'pci-block-storage:volume-extend-12To';
export const FA_EXTEN_BANNER = 'pci-block-storage:exten-banner';

export function useVolumeMaxSize(region: string | undefined) {
const { data, ...restApi } = useFeatureAvailability([
FA_VOLUME_EXTEND_12TO,
FA_EXTEN_BANNER,
]);

const volumeMaxSize = useMemo(() => {
if (region && data?.[FA_VOLUME_EXTEND_12TO]) {
return getVolumeMaxSize(region);
}
return 4 * 1000;
}, [data, region]);

return {
...restApi,
volumeMaxSize,
};
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useQuery } from '@tanstack/react-query';
import { getRegionsQuota } from '@/api/data/quota';

export const useRegionsQuota = (projectId: string) =>
export const useRegionsQuota = (projectId: string, region: string) =>
useQuery({
queryKey: ['project', projectId, 'quota'],
queryFn: () => getRegionsQuota(projectId),
queryKey: ['project', projectId, 'region', region, 'quota'],
queryFn: () => getRegionsQuota(projectId, region),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useFeatureAvailability } from '@ovh-ux/manager-react-components';
import { OsdsMessage, OsdsText } from '@ovhcloud/ods-components/react';
import {
ODS_MESSAGE_TYPE,
ODS_TEXT_COLOR_HUE,
ODS_TEXT_COLOR_INTENT,
} from '@ovhcloud/ods-components';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { useMemo } from 'react';
import { FA_EXTEN_BANNER } from '@/api/data/quota';
import { useProjectsAvailableVolumes } from '@/api/hooks/useProjectsAvailableVolumes';

const extenProducts = [
'volume.high-speed-BETA.consumption',
'volume.classic-BETA.consumption',
];

function Banner() {
const { t } = useTranslation('exten-banner-beta');
const { projectId } = useParams();
const { data: availableVolumes } = useProjectsAvailableVolumes(projectId);

const regionsString = useMemo(
() =>
availableVolumes
? [
...new Set(
availableVolumes.plans
.filter((p) => extenProducts.includes(p.code))
.flatMap((p) => p.regions)
.map((r) => r.name),
),
].join(', ')
: '',
[availableVolumes],
);

if (!availableVolumes) return null;

return (
<OsdsMessage type={ODS_MESSAGE_TYPE.info}>
<OsdsText
color={ODS_TEXT_COLOR_INTENT.info}
style={{ whiteSpace: 'pre-wrap' }}
hue={ODS_TEXT_COLOR_HUE._700}
>
{t('exten_banner_description', {
regions: regionsString,
})}
</OsdsText>
</OsdsMessage>
);
}

export function ExtenBannerBeta() {
const { data } = useFeatureAvailability([FA_EXTEN_BANNER]);

if (!data?.[FA_EXTEN_BANNER]) return null;

return <Banner />;
}
1 change: 0 additions & 1 deletion packages/manager/apps/pci-block-storage/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const URL_INFO = {
LOCAL_ZONE: LOCAL_ZONE_INFO_URL,
};

export const VOLUME_MAX_SIZE = 4 * 1000; // Should be 10 * 1024 (but API is wrong;
export const VOLUME_MIN_SIZE = 10; // 10 Gio
export const VOLUME_UNLIMITED_QUOTA = -1; // Should be 10 * 1024 (but API is wrong)
export const ALPHA_CHARACTERS_REGEX = /^[a-zA-Z-]+$/;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ vi.mock('@/core/HidePreloader', () => ({
default: () => <div>HidePeloader</div>,
}));

vi.mock('@/api/hooks/useQuota', () => ({
useRegionsQuota: vi.fn().mockReturnValue({ data: [] }),
}));

vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => {
const mod = await importOriginal<
typeof import('@ovh-ux/manager-react-components')
Expand All @@ -38,7 +42,6 @@ vi.mock('@ovh-ux/manager-react-components', async (importOriginal) => {
addSuccess: vi.fn(),
}),
useProjectLocalRegions: vi.fn().mockReturnValue({ data: [] }),
useProjectQuota: vi.fn().mockReturnValue({ data: [] }),
useProjectUrl: vi.fn().mockReturnValue('/project-url'),
useTranslatedMicroRegions: vi
.fn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
useCatalogPrice,
useNotifications,
useProjectLocalRegions,
useProjectQuota,
useProjectUrl,
useTranslatedMicroRegions,
} from '@ovh-ux/manager-react-components';
Expand Down Expand Up @@ -38,11 +37,7 @@ import {
OsdsText,
} from '@ovhcloud/ods-components/react';
import { useProject } from '@ovh-ux/manager-pci-common';
import {
VOLUME_MAX_SIZE,
VOLUME_MIN_SIZE,
VOLUME_UNLIMITED_QUOTA,
} from '@/constants';
import { VOLUME_MIN_SIZE, VOLUME_UNLIMITED_QUOTA } from '@/constants';
import ChipRegion from '@/components/edit/ChipRegion.component';
import { TVolume } from '@/api/data/volume';
import {
Expand All @@ -51,6 +46,8 @@ import {
useVolume,
} from '@/api/hooks/useVolume';
import HidePreloader from '@/core/HidePreloader';
import { useVolumeMaxSize } from '@/api/data/quota';
import { useRegionsQuota } from '@/api/hooks/useQuota';

type TFormState = {
name: string;
Expand Down Expand Up @@ -95,6 +92,8 @@ export default function EditPage() {
isPending: isPendingVolume,
} = useVolume(projectId, volumeId);

const { volumeMaxSize } = useVolumeMaxSize(volume?.region);

const {
data: localRegions,
isPending: isPendingLocal,
Expand All @@ -106,7 +105,7 @@ export default function EditPage() {
size: {
value: volume?.size || VOLUME_MIN_SIZE,
min: VOLUME_MIN_SIZE,
max: VOLUME_MAX_SIZE,
max: volumeMaxSize,
},
bootable: volume?.bootable || false,
isInitialized: false,
Expand Down Expand Up @@ -152,25 +151,23 @@ export default function EditPage() {
},
});

const { data: projectQuota, isPending: isPendingQuota } = useProjectQuota(
const { data: regionQuota, isPending: isPendingQuota } = useRegionsQuota(
projectId,
volume?.region,
);

const getMaxSize = (_volume: TVolume) => {
if (projectQuota?.length > 0) {
const regionQuota = projectQuota.find(
({ region }) => region === _volume.region,
);
if (regionQuota) {
if (
regionQuota.volume &&
regionQuota.volume.maxGigabytes !== VOLUME_UNLIMITED_QUOTA
) {
const availableGigabytes =
regionQuota.volume.maxGigabytes - regionQuota.volume.usedGigabytes;
return Math.min(_volume.size + availableGigabytes, VOLUME_MAX_SIZE);
return Math.min(_volume.size + availableGigabytes, volumeMaxSize);
}
}
return VOLUME_MAX_SIZE;
return volumeMaxSize;
};

const getVolumePriceEstimationFromCatalog = (
Expand All @@ -194,7 +191,7 @@ export default function EditPage() {
isPendingQuota;

useEffect(() => {
if (volume && projectQuota) {
if (volume && regionQuota) {
setFormState({
name: volume.name,
size: {
Expand All @@ -206,7 +203,7 @@ export default function EditPage() {
isInitialized: true,
});
}
}, [volume, projectQuota]);
}, [volume, regionQuota]);

useEffect(() => {
const { min, max, value } = formState.size;
Expand Down Expand Up @@ -443,7 +440,7 @@ export default function EditPage() {
</div>

{!hasError &&
(estimatedPrice?.monthly ? (
(estimatedPrice?.monthly !== undefined ? (
<OsdsText
level={ODS_THEME_TYPOGRAPHY_LEVEL.body}
size={ODS_THEME_TYPOGRAPHY_SIZE._400}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ValidationStep } from './components/ValidationStep.component';
import { LocationStep } from './components/LocationStep.component';
import { useVolumeStepper } from './hooks/useVolumeStepper';
import { useAddVolume } from '@/api/hooks/useVolume';
import { ExtenBannerBeta } from '@/components/exten-banner-beta/ExtenBannerBeta';

export default function NewPage(): JSX.Element {
const { t } = useTranslation('common');
Expand Down Expand Up @@ -102,6 +103,10 @@ export default function NewPage(): JSX.Element {
<PciDiscoveryBanner project={project} />
</div>

<div className="mb-5">
<ExtenBannerBeta />
</div>

<div className="mt-8">
<StepComponent
order={1}
Expand Down
Loading

0 comments on commit d217168

Please sign in to comment.