From 19c7aba74eb81d665a879b110fa537a4a2d57405 Mon Sep 17 00:00:00 2001 From: Nkeiruka Date: Wed, 8 Jan 2025 13:48:57 +0000 Subject: [PATCH] feat: [WD-17984] Add Pure Storage Signed-off-by: Nkeiruka --- src/pages/storage/forms/StoragePoolForm.tsx | 14 ++++ .../storage/forms/StoragePoolFormMain.tsx | 68 ++++++++++++++++++- .../storage/forms/StoragePoolFormMenu.tsx | 1 + src/pages/storage/forms/StorageVolumeForm.tsx | 22 +++--- src/types/config.d.ts | 1 + src/util/permissions.spec.ts | 1 + src/util/storageOptions.tsx | 9 ++- src/util/storagePool.tsx | 5 ++ src/util/storagePoolForm.tsx | 4 ++ 9 files changed, 113 insertions(+), 12 deletions(-) diff --git a/src/pages/storage/forms/StoragePoolForm.tsx b/src/pages/storage/forms/StoragePoolForm.tsx index 3b5a5e338a..e357a4c256 100644 --- a/src/pages/storage/forms/StoragePoolForm.tsx +++ b/src/pages/storage/forms/StoragePoolForm.tsx @@ -26,6 +26,7 @@ import { cephFSDriver, getSupportedStorageDrivers, powerFlex, + pureStorage, zfsDriver, } from "util/storageOptions"; import { getPoolKey } from "util/storagePool"; @@ -70,6 +71,10 @@ export interface StoragePoolFormValues { powerflex_sdt?: string; powerflex_user_name?: string; powerflex_user_password?: string; + pure_api_token?: string; + pure_gateway?: string; + pure_gateway_verify?: string; + pure_mode?: string; zfs_clone_copy?: string; zfs_export?: string; zfs_pool_name?: string; @@ -90,6 +95,7 @@ export const toStoragePool = ( const isCephDriver = values.driver === cephDriver; const isCephFSDriver = values.driver === cephFSDriver; const isPowerFlexDriver = values.driver === powerFlex; + const isPureDriver = values.driver === pureStorage; const isZFSDriver = values.driver === zfsDriver; const hasValidSize = values.size?.match(/^\d/); @@ -129,6 +135,14 @@ export const toStoragePool = ( [getPoolKey("powerflex_user_password")]: values.powerflex_user_password, }; } + if (isPureDriver) { + return { + [getPoolKey("pure_api_token")]: values.pure_api_token, + [getPoolKey("pure_gateway")]: values.pure_gateway, + [getPoolKey("pure_gateway_verify")]: values.pure_gateway_verify, + [getPoolKey("pure_mode")]: values.pure_mode, + }; + } if (isZFSDriver) { return { [getPoolKey("zfs_clone_copy")]: values.zfs_clone_copy ?? "", diff --git a/src/pages/storage/forms/StoragePoolFormMain.tsx b/src/pages/storage/forms/StoragePoolFormMain.tsx index 698f2971f9..1c26cc8950 100644 --- a/src/pages/storage/forms/StoragePoolFormMain.tsx +++ b/src/pages/storage/forms/StoragePoolFormMain.tsx @@ -9,6 +9,7 @@ import { cephDriver, getStorageDriverOptions, powerFlex, + pureStorage, cephFSDriver, } from "util/storageOptions"; import { StoragePoolFormValues } from "./StoragePoolForm"; @@ -18,6 +19,7 @@ import { getCephPoolFormFields } from "util/storagePool"; import { useSettings } from "context/useSettings"; import ScrollableForm from "components/ScrollableForm"; import { ensureEditMode } from "util/instanceEdit"; +import { optionTrueFalse } from "util/instanceOptions"; interface Props { formik: FormikProps; @@ -42,6 +44,7 @@ const StoragePoolFormMain: FC = ({ formik }) => { const isCephFSDriver = formik.values.driver === cephFSDriver; const isDirDriver = formik.values.driver === dirDriver; const isPowerFlexDriver = formik.values.driver === powerFlex; + const isPureDriver = formik.values.driver === pureStorage; const storageDriverOptions = getStorageDriverOptions(settings); return ( @@ -104,6 +107,7 @@ const StoragePoolFormMain: FC = ({ formik }) => { {!isCephDriver && !isCephFSDriver && !isDirDriver && + !isPureDriver && !isPowerFlexDriver && ( = ({ formik }) => { disabled={formik.values.driver === dirDriver} /> )} - {!isPowerFlexDriver && ( + {!isPureDriver && !isPowerFlexDriver && ( = ({ formik }) => { /> )} + {isPureDriver && ( + <> + { + ensureEditMode(formik); + formik.handleChange(e); + }} + required + /> + { + ensureEditMode(formik); + formik.handleChange(e); + }} + required + /> + { + ensureEditMode(formik); + formik.handleChange(e); + }} + /> + + )} diff --git a/src/pages/storage/forms/StoragePoolFormMenu.tsx b/src/pages/storage/forms/StoragePoolFormMenu.tsx index 674e913017..89c8c97061 100644 --- a/src/pages/storage/forms/StoragePoolFormMenu.tsx +++ b/src/pages/storage/forms/StoragePoolFormMenu.tsx @@ -19,6 +19,7 @@ export const CEPHFS_CONFIGURATION = "CephFS"; export const POWERFLEX = "Powerflex"; export const ZFS_CONFIGURATION = "ZFS"; export const YAML_CONFIGURATION = "YAML configuration"; +export const PURE_STORAGE = "Pure Storage"; interface Props { active: string; diff --git a/src/pages/storage/forms/StorageVolumeForm.tsx b/src/pages/storage/forms/StorageVolumeForm.tsx index 956084e75b..7b961ab23c 100644 --- a/src/pages/storage/forms/StorageVolumeForm.tsx +++ b/src/pages/storage/forms/StorageVolumeForm.tsx @@ -156,16 +156,18 @@ const StorageVolumeForm: FC = ({ formik, section, setSection }) => { const poolDriver = pools.find((item) => item.name === formik.values.pool)?.driver ?? ""; - const invalidFields: (keyof StorageVolumeFormValues)[] = []; - if (!driversWithFilesystemSupport.includes(poolDriver)) { - invalidFields.push(...getFilesystemVolumeFormFields()); - } - if (poolDriver !== "zfs") { - invalidFields.push(...getZfsVolumeFormFields()); - } - for (const field of invalidFields) { - if (formik.values[field] !== undefined) { - void formik.setFieldValue(field, undefined); + if (pools.length > 0) { + const invalidFields: (keyof StorageVolumeFormValues)[] = []; + if (!driversWithFilesystemSupport.includes(poolDriver)) { + invalidFields.push(...getFilesystemVolumeFormFields()); + } + if (poolDriver !== "zfs") { + invalidFields.push(...getZfsVolumeFormFields()); + } + for (const field of invalidFields) { + if (formik.values[field] !== undefined) { + void formik.setFieldValue(field, undefined); + } } } diff --git a/src/types/config.d.ts b/src/types/config.d.ts index 555f903c9f..3ecfb51d20 100644 --- a/src/types/config.d.ts +++ b/src/types/config.d.ts @@ -53,6 +53,7 @@ export interface LxdMetadata { "storage-dir": LxcConfigOptionCategories; "storage-lvm": LxcConfigOptionCategories; "storage-powerflex": LxcConfigOptionCategories; + "storage-pure": LxcConfigOptionCategories; "storage-zfs": LxcConfigOptionCategories; }; entities: LxdEntityEntitlements; diff --git a/src/util/permissions.spec.ts b/src/util/permissions.spec.ts index 2f81cf16fd..0d89d3c22a 100644 --- a/src/util/permissions.spec.ts +++ b/src/util/permissions.spec.ts @@ -133,6 +133,7 @@ describe("General util functions for permissions feature", () => { "storage-dir": {}, "storage-lvm": {}, "storage-powerflex": {}, + "storage-pure": {}, "storage-zfs": {}, }, entities: { diff --git a/src/util/storageOptions.tsx b/src/util/storageOptions.tsx index c2ea644b23..a1331299ac 100644 --- a/src/util/storageOptions.tsx +++ b/src/util/storageOptions.tsx @@ -8,6 +8,7 @@ export const zfsDriver = "zfs"; export const cephDriver = "ceph"; export const cephFSDriver = "cephfs"; export const powerFlex = "powerflex"; +export const pureStorage = "pure"; const storageDriverLabels: { [key: string]: string } = { [dirDriver]: "Directory", @@ -17,6 +18,7 @@ const storageDriverLabels: { [key: string]: string } = { [cephDriver]: "Ceph", [cephFSDriver]: "CephFS", [powerFlex]: "Dell PowerFlex", + [pureStorage]: "Pure Storage", }; export const getStorageDriverOptions = ( @@ -60,4 +62,9 @@ export const getSourceHelpForDriver = (driver: string) => { return "Not available"; }; -export const driversWithFilesystemSupport = [zfsDriver, lvmDriver, cephDriver]; +export const driversWithFilesystemSupport = [ + zfsDriver, + lvmDriver, + cephDriver, + pureStorage, +]; diff --git a/src/util/storagePool.tsx b/src/util/storagePool.tsx index 3f406b14a1..ae86f3507a 100644 --- a/src/util/storagePool.tsx +++ b/src/util/storagePool.tsx @@ -26,6 +26,10 @@ export const storagePoolFormFieldToPayloadName: Record = { powerflex_sdt: "powerflex.sdt", powerflex_user_name: "powerflex.user.name", powerflex_user_password: "powerflex.user.password", + pure_api_token: "pure.api.token", + pure_gateway: "pure.gateway", + pure_gateway_verify: "pure.gateway.verify", + pure_mode: "pure.mode", zfs_clone_copy: "zfs.clone_copy", zfs_export: "zfs.export", zfs_pool_name: "zfs.pool_name", @@ -54,6 +58,7 @@ const storagePoolDriverToOptionKey: Record = { ceph: "storage-ceph", cephfs: "storage-cephfs", powerflex: "storage-powerflex", + pure: "storage-pure", }; export const storagePoolFormDriverToOptionKey = ( diff --git a/src/util/storagePoolForm.tsx b/src/util/storagePoolForm.tsx index 8bbebe4163..156f339030 100644 --- a/src/util/storagePoolForm.tsx +++ b/src/util/storagePoolForm.tsx @@ -33,6 +33,10 @@ export const toStoragePoolFormValues = ( powerflex_sdt: pool.config?.["powerflex.sdt"], powerflex_user_name: pool.config?.["powerflex.user.name"], powerflex_user_password: pool.config?.["powerflex.user.password"], + pure_api_token: pool.config?.["pure.api.token"], + pure_gateway: pool.config?.["pure.gateway"], + pure_gateway_verify: pool.config?.["pure.gateway.verify"], + pure_mode: pool.config?.["pure.mode"], zfs_clone_copy: pool.config?.["zfs.clone_copy"], zfs_export: pool.config?.["zfs.export"], zfs_pool_name: pool.config?.["zfs.pool_name"],