import { K8S } from "@k8ts/sample-interfaces" import { ResourceEntity, ResourcePart, toCdkQuantity, Units, type Resource_Props, type ResourceRef, type ResourceRef_HasKeys } from "@k8ts/instruments" import { merge } from "lodash" import { v1 } from "../../../../gvks/default" import type { HostPath_Type } from "../../../hostpath" import { type ContainerVolumeMount_Input, type ContainerVolumeMount_Unbound } from "../container/mounts/volume" export interface PodVolume_Backend_Pvc< A extends ResourceRef = ResourceRef > extends Resource_Props { $backend: A readOnly?: boolean } export interface PodVolume_Backend_HostPath extends Resource_Props { $backend: { kind: "HostPath" $noEmit?: boolean type?: HostPath_Type path: string } } export interface PodVolume_Backend_EmptyDir extends Resource_Props { $backend: { kind: "EmptyDir" medium?: "" | "Memory" sizeLimit?: Units.Data } } export interface PodVolume_Backend_ConfigMap< A extends ResourceRef = ResourceRef > extends Resource_Props { $backend: A optional?: boolean mappings?: { [K in ResourceRef_HasKeys]?: string } } export interface PodVolume_Backend_Secret< A extends ResourceRef = ResourceRef > extends Resource_Props { $backend: A optional?: boolean mappings?: { [K in ResourceRef_HasKeys]?: string } } export type PodVolume_Backend = ( | PodVolume_Backend_Pvc | PodVolume_Backend_ConfigMap | PodVolume_Backend_Secret | PodVolume_Backend_HostPath | PodVolume_Backend_EmptyDir ) & Resource_Props type _KeysOf = T extends { $backend: { keys: infer Ks extends string[] } } ? Ks[number] : string type _Mapped = T extends { mappings: infer M } ? { [K in _KeysOf]: K extends keyof M ? M[K] : K }[_KeysOf] : _KeysOf export type PodVolumeBackendKnownPaths = string & _Mapped export abstract class PodVolume< P extends PodVolume_Backend = PodVolume_Backend > extends ResourcePart

{ get kind() { return v1.Pod.Volume._ } get namespace() { const backend = this.props.$backend if (backend instanceof ResourceEntity) { const x = backend.ident.namespace return x } return this.__parent__.ident.namespace } protected __needs__(): Record { return { backend: this.props.$backend instanceof ResourceEntity ? this.props.$backend : undefined } } mount( options?: ContainerVolumeMount_Input> ): ContainerVolumeMount_Unbound { return { ...options, $backend: this } } protected abstract __submanifest__(): K8S.Volume } export class PodVolume_Pvc extends PodVolume { protected __submanifest__(): K8S.Volume { const body = { name: this.ident.name, persistentVolumeClaim: { claimName: this.props.$backend.ident.name, readOnly: this.props.readOnly } } return merge(body, this.props.$$manifest) } } function mappingsToKeyPaths(input: Record) { const mappings = input const arr = Object.entries(mappings).map(([key, value]) => { return { key: key, path: value } satisfies K8S.KeyToPath }) if (arr.length === 0) { return undefined } return arr } export class PodVolume_ConfigMap extends PodVolume { protected __submanifest__(): K8S.Volume { const mappings = mappingsToKeyPaths(this.props.mappings ?? {}) const body = { name: this.ident.name, configMap: { name: this.props.$backend.ident.name, optional: this.props.optional, items: mappings } } return merge(body, this.props.$$manifest) } } export class PodVolume_Secret< Source extends ResourceRef > extends PodVolume { protected __submanifest__(): K8S.Volume { const mappings = mappingsToKeyPaths(this.props.mappings ?? {}) const body = { name: this.ident.name, secret: { secretName: this.props.$backend.ident.name, optional: this.props.optional, items: mappings } } return merge(body, this.props.$$manifest) } } export class PodVolume_HostPath extends PodVolume { protected __submanifest__(): K8S.Volume { const body = { name: this.ident.name, hostPath: { path: this.props.$backend.path, type: this.props.$backend.kind } } return merge(body, this.props.$$manifest) } } export class PodVolume_EmptyDir extends PodVolume { protected __submanifest__(): K8S.Volume { const body = { medium: this.props.$backend.medium, sizeLimit: toCdkQuantity(this.props.$backend.sizeLimit) } satisfies K8S.EmptyDirVolumeSource return merge(body, this.props.$$manifest) } }