fix: preserve bound PVC storage classes

This commit is contained in:
2026-09-06 03:04:02 +00:00 Unverified
parent 2f0afaadc7
commit 053f28a367
4 changed files with 172 additions and 9 deletions
+67 -5
View File
@@ -984,20 +984,35 @@ export class KubernetesTrustStore implements TrustStore {
}
async list(project: string): Promise<string[]> {
return (await list(this.objects, "ConfigMap", "trust", project))
.map((item) => parsePayload<{ project: string; fingerprint: string }>(item))
.map((item) =>
parsePayload<{ project: string; fingerprint: string }>(item),
)
.filter((record): record is { project: string; fingerprint: string } =>
Boolean(record && record.project === project && /^[a-f0-9]{64}$/.test(record.fingerprint)),
Boolean(
record &&
record.project === project &&
/^[a-f0-9]{64}$/.test(record.fingerprint),
),
)
.map((record) => record.fingerprint);
}
async has(project: string, fingerprint: string): Promise<boolean> {
const item = await read(this.objects, "ConfigMap", this.name(project, fingerprint));
const record = item && parsePayload<{ project: string; fingerprint: string }>(item);
const item = await read(
this.objects,
"ConfigMap",
this.name(project, fingerprint),
);
const record =
item && parsePayload<{ project: string; fingerprint: string }>(item);
return record?.project === project && record.fingerprint === fingerprint;
}
async revoke(project: string, fingerprint: string): Promise<boolean> {
if (!(await this.has(project, fingerprint))) return false;
return deleteObject(this.objects, "ConfigMap", this.name(project, fingerprint));
return deleteObject(
this.objects,
"ConfigMap",
this.name(project, fingerprint),
);
}
}
@@ -1071,6 +1086,53 @@ export function createKubernetesManagementDependencies(
),
);
const overrides: Partial<ManagementDependencies> = {
applyResource: async (desired) => {
let resource = desired as KubernetesObject & {
spec?: { storageClassName?: string };
};
if (
desired.apiVersion === "v1" &&
desired.kind === "PersistentVolumeClaim" &&
desired.metadata?.name
) {
try {
const existing = (await objects.read({
apiVersion: "v1",
kind: "PersistentVolumeClaim",
metadata: {
name: desired.metadata.name,
namespace: desired.metadata.namespace,
},
})) as KubernetesObject & {
spec?: { storageClassName?: string };
status?: { phase?: string };
};
const spec = resource.spec;
if (
existing.status?.phase === "Bound" &&
existing.spec?.storageClassName !== spec?.storageClassName
) {
resource = {
...desired,
spec: {
...spec,
storageClassName: existing.spec?.storageClassName,
},
};
}
} catch (error) {
if (!isNotFound(error)) throw error;
}
}
return objects.patch(
resource,
undefined,
undefined,
FIELD_MANAGER,
true,
PatchStrategy.ServerSideApply,
);
},
listDeployments: async (project) =>
(
await apps.listNamespacedDeployment({