1import * as _ from 'lodash-es' 7import { StorageV1Api } from '@kubernetes/client-node' 11type PvcSizeValidator = (sizeGb: number) => void 12const sizeValidatorH: Record<string, PvcSizeValidator> = {} 13export const registerPvcSizeValidator = (cloudName: string, validator: PvcSizeValidator) => { 14 sizeValidatorH[cloudName] = validator 16export const validatePvcSizeForCloud = (k8sCloudName: string | undefined, sizeGb: number) => { 17 if (!k8sCloudName) return 18 const validator = sizeValidatorH[k8sCloudName] 19 if (validator) validator(sizeGb) 22const listStorageClassNames = async ({cluster_name}: {cluster_name: string}) => { 24 const storageV1Api = kubeConfig.makeApiClient(StorageV1Api) 25 const {items} = await storageV1Api.listStorageClass() 26 return _.map(items, 'metadata.name') 29export const getOptStorClassName = async ({cluster_name, name}: {cluster_name: string, name?: string}): Promise<string | undefined> => { 30 if (!name) return undefined 31 const storageClassNames = await listStorageClassNames({cluster_name}) 32 return storageClassNames.includes(name) ? name : undefined 35export const pvcTypeCtx = genContext<{ pvcReplicaCnt?: number, pvcEncName?: string }>() 37type GenericPvcTmplAProps = { 39 storageClassName?: string 40 pvcStorClassName?: string 44 pvcReplicaCnt?: number 48export const genericPvcTmplA = async ({ 49 useM2, storageClassName: deprecStorageClassName, 52}: GenericPvcTmplAProps): Promise<KubeResource[]> => { 53 // prefer kubeActionPvc since it sets softdeleted 55 const pvcTypeStore = pvcTypeCtx.getStore() 56 let {pvcReplicaCnt} = _.merge({}, pvcTypeStore, props) as { pvcReplicaCnt?: number } 58 const {cluster_name, pvcStorClassName: _pvcStorClassName} = getKlusterCtx(props) 59 pvcStorClassName ||= _pvcStorClassName 63 const {k8sCloudName, pvcReplicaCnt: _pvcReplicaCnt=1, storClassGenFn} = getCurKlusterCfg(cluster_name) 64 pvcReplicaCnt ||= _pvcReplicaCnt 66 if (action == 'apply') validatePvcSizeForCloud(k8sCloudName, props.sizeGb) 68 const resources: KubeResource[] = [] 70 if (!pvcStorClassName && storClassGenFn) { 71 ;({pvcStorClassName} = storClassGenFn({useM2, pvcReplicaCnt, ...pvcTypeStore})) 74 if (action == 'apply' && pvcStorClassName) { 75 const storageClassNames = await listStorageClassNames({cluster_name}) 77 pvcStorClassName, storageClassNames, cluster_name, 78 msg: 'required storageclass does not exist on cluster' 84 deprecGenericPvc({storageClassName: pvcStorClassName, ...props}) as KubeResource, 88type DeprecGenericPvcProps = { 92 storageClassName?: string 93 accessModes?: string[] 96export const deprecGenericPvc = ({ 97 name, sizeGb, softdeleted, storageClassName, accessModes = ['ReadWriteOnce'], 98}: DeprecGenericPvcProps) => { // prefer genericPvcTmplA 102 kind: 'PersistentVolumeClaim', 106 softdeleted_since: softdeleted ? _.round(luxNow().toSeconds()).toString() : 'false' 114 storage: `${sizeGb}Gi`