fix: 收敛 PostgreSQL 配置规模投影
This commit is contained in:
+112
-47
@@ -12,6 +12,7 @@ import { compactText, fingerprintEnvValues as fingerprintValues, parseEnvFile, p
|
||||
const defaultConfigPath = "config/platform-db/postgres-pk01.yaml";
|
||||
const managedHbaStart = "# BEGIN unidesk managed pk01-platform-postgres";
|
||||
const managedHbaEnd = "# END unidesk managed pk01-platform-postgres";
|
||||
const compactActionablePreviewLimit = 4;
|
||||
|
||||
interface PlatformDbOptions {
|
||||
configPath: string;
|
||||
@@ -1184,6 +1185,16 @@ function compactStatus(
|
||||
: Array.isArray(summary.cutoverBlockers)
|
||||
? summary.cutoverBlockers
|
||||
: [];
|
||||
const roles = pg.objects.roles.map((role) => ({
|
||||
name: role.name,
|
||||
exists: facts?.postgres.roles.find((item) => item.name === role.name)?.exists ?? null,
|
||||
}));
|
||||
const databases = pg.objects.databases.map((database) => ({
|
||||
name: database.name,
|
||||
owner: database.owner,
|
||||
exists: facts?.postgres.databases.find((item) => item.name === database.name)?.exists ?? null,
|
||||
}));
|
||||
const appConnections = facts?.postgres.appConnections ?? [];
|
||||
return {
|
||||
ok,
|
||||
action: "platform-db-postgres-status",
|
||||
@@ -1233,31 +1244,37 @@ function compactStatus(
|
||||
error: controllerConnection.error,
|
||||
},
|
||||
},
|
||||
roles: pg.objects.roles.map((role) => ({
|
||||
name: role.name,
|
||||
exists: facts?.postgres.roles.find((item) => item.name === role.name)?.exists ?? null,
|
||||
})),
|
||||
databases: pg.objects.databases.map((database) => ({
|
||||
name: database.name,
|
||||
owner: database.owner,
|
||||
exists: facts?.postgres.databases.find((item) => item.name === database.name)?.exists ?? null,
|
||||
})),
|
||||
appConnections: {
|
||||
ok: facts?.postgres.appConnections.every((connection) => connection.ok === true && connection.ssl === true) ?? false,
|
||||
passed: facts?.postgres.appConnections.filter((connection) => connection.ok === true && connection.ssl === true).length ?? 0,
|
||||
total: facts?.postgres.appConnections.length ?? 0,
|
||||
failed: facts?.postgres.appConnections
|
||||
.filter((connection) => connection.ok !== true || connection.ssl !== true)
|
||||
.map((connection) => connection.database) ?? [],
|
||||
},
|
||||
roles: compactActionableSummary(roles, {
|
||||
passed: (item) => item.exists === true,
|
||||
missing: (item) => item.exists === false,
|
||||
actionable: (item) => item.exists !== true,
|
||||
project: (item) => item,
|
||||
}),
|
||||
databases: compactActionableSummary(databases, {
|
||||
passed: (item) => item.exists === true,
|
||||
missing: (item) => item.exists === false,
|
||||
actionable: (item) => item.exists !== true,
|
||||
project: (item) => item,
|
||||
}),
|
||||
appConnections: compactActionableSummary(appConnections, {
|
||||
passed: (item) => item.ok === true && item.ssl === true,
|
||||
missing: (item) => item.ok !== true || item.ssl !== true,
|
||||
actionable: (item) => item.ok !== true || item.ssl !== true,
|
||||
project: (item) => ({ user: item.user, database: item.database, ok: item.ok, ssl: item.ssl, error: item.error }),
|
||||
}),
|
||||
secrets: compactSecretInspection(secrets),
|
||||
exports: exports.map((item) => ({
|
||||
targetRef: item.targetRef,
|
||||
key: item.key,
|
||||
exists: item.exists,
|
||||
present: item.present,
|
||||
fingerprint: item.fingerprint,
|
||||
})),
|
||||
exports: compactActionableSummary(exports, {
|
||||
passed: (item) => item.present === true,
|
||||
missing: (item) => item.present !== true,
|
||||
actionable: (item) => item.present !== true,
|
||||
project: (item) => ({
|
||||
targetRef: item.targetRef,
|
||||
key: item.key,
|
||||
exists: item.exists,
|
||||
present: item.present,
|
||||
fingerprint: item.fingerprint,
|
||||
}),
|
||||
}),
|
||||
remote: compactPlanCapture(capture),
|
||||
next: {
|
||||
plan: `bun scripts/cli.ts platform-db postgres plan --config ${pg.configPath}`,
|
||||
@@ -1282,6 +1299,20 @@ function compactExportSecrets(
|
||||
ok: boolean,
|
||||
): Record<string, unknown> {
|
||||
const suffix = mode === "dry-run" ? " --dry-run" : " --confirm";
|
||||
const exports = localState.exports.map((item) => {
|
||||
const before = asRecord(item.before, "export before");
|
||||
const after = asRecord(item.after, "export after");
|
||||
return {
|
||||
name: item.name,
|
||||
sourceRef: item.sourceRef,
|
||||
targetRef: item.targetRef,
|
||||
key: item.key,
|
||||
before,
|
||||
after,
|
||||
action: item.action,
|
||||
desiredFingerprint: item.desiredFingerprint,
|
||||
};
|
||||
});
|
||||
return {
|
||||
ok,
|
||||
action: "platform-db-postgres-export-secrets",
|
||||
@@ -1297,16 +1328,12 @@ function compactExportSecrets(
|
||||
secretRoot: localState.inspection.root,
|
||||
},
|
||||
secrets: compactSecretInspection(localState.inspection),
|
||||
exports: localState.exports.map((item) => ({
|
||||
name: item.name,
|
||||
sourceRef: item.sourceRef,
|
||||
targetRef: item.targetRef,
|
||||
key: item.key,
|
||||
exists: item.exists,
|
||||
present: item.present,
|
||||
action: item.action,
|
||||
fingerprint: item.fingerprint,
|
||||
})),
|
||||
exports: compactActionableSummary(exports, {
|
||||
passed: (item) => item.action === "none" && item.after.present === true,
|
||||
missing: (item) => item.after.present !== true,
|
||||
actionable: (item) => item.action !== "none" || item.after.present !== true,
|
||||
project: (item) => item,
|
||||
}),
|
||||
next: {
|
||||
...(mode === "dry-run" ? { confirm: `bun scripts/cli.ts platform-db postgres export-secrets --config ${pg.configPath} --confirm` } : {}),
|
||||
full: `bun scripts/cli.ts platform-db postgres export-secrets --config ${pg.configPath}${suffix} --full`,
|
||||
@@ -1324,23 +1351,50 @@ function compactExportSecrets(
|
||||
}
|
||||
|
||||
function compactSecretInspection(secrets: SecretInspection): Record<string, unknown> {
|
||||
const entries = secrets.entries.map((entry) => ({
|
||||
sourceRef: entry.sourceRef,
|
||||
exists: entry.exists,
|
||||
presentKeys: entry.presentKeys,
|
||||
missingKeys: entry.missingKeys,
|
||||
action: entry.action,
|
||||
fingerprint: entry.fingerprint,
|
||||
}));
|
||||
return {
|
||||
ok: secrets.ok,
|
||||
root: secrets.root,
|
||||
entries: secrets.entries.map((entry) => ({
|
||||
sourceRef: entry.sourceRef,
|
||||
exists: entry.exists,
|
||||
keys: {
|
||||
present: entry.presentKeys,
|
||||
missing: entry.missingKeys,
|
||||
},
|
||||
action: entry.action,
|
||||
fingerprint: entry.fingerprint,
|
||||
})),
|
||||
...compactActionableSummary(entries, {
|
||||
passed: (item) => item.exists && item.missingKeys.length === 0 && item.action === "none",
|
||||
missing: (item) => !item.exists || item.missingKeys.length > 0,
|
||||
actionable: (item) => item.action !== "none" || !item.exists || item.missingKeys.length > 0,
|
||||
project: (item) => item,
|
||||
}),
|
||||
valuesPrinted: false,
|
||||
};
|
||||
}
|
||||
|
||||
function compactActionableSummary<T>(
|
||||
items: T[],
|
||||
selectors: {
|
||||
passed: (item: T) => boolean;
|
||||
missing: (item: T) => boolean;
|
||||
actionable: (item: T) => boolean;
|
||||
project: (item: T) => unknown;
|
||||
},
|
||||
): Record<string, unknown> {
|
||||
const actionableItems = items.filter(selectors.actionable);
|
||||
const visibleItems = actionableItems.slice(0, compactActionablePreviewLimit);
|
||||
return {
|
||||
total: items.length,
|
||||
passed: items.filter(selectors.passed).length,
|
||||
missing: items.filter(selectors.missing).length,
|
||||
actionable: actionableItems.length,
|
||||
listed: visibleItems.length,
|
||||
omitted: items.length - visibleItems.length,
|
||||
actionableOmitted: actionableItems.length - visibleItems.length,
|
||||
items: visibleItems.map(selectors.project),
|
||||
};
|
||||
}
|
||||
|
||||
function compactRemoteFacts(facts: RemoteFacts | null): Record<string, unknown> | null {
|
||||
if (facts === null) return null;
|
||||
return {
|
||||
@@ -1568,6 +1622,9 @@ function connectionStringExportState(pg: PostgresHostConfig, inspection: SecretI
|
||||
const exists = existsSync(targetPath);
|
||||
const existing = exists ? parseEnvFile(readFileSync(targetPath, "utf8")) : {};
|
||||
const before = existing[item.writeToSecretSource.key];
|
||||
const beforePresent = before !== undefined && before.length > 0;
|
||||
const beforeFingerprint = beforePresent ? fingerprintValues({ [item.writeToSecretSource.key]: before }, [item.writeToSecretSource.key]) : null;
|
||||
const desiredFingerprint = fingerprintValues({ [item.writeToSecretSource.key]: rendered }, [item.writeToSecretSource.key]);
|
||||
const next = { ...existing, [item.writeToSecretSource.key]: rendered };
|
||||
if (materialize) writeEnvFile(targetPath, next);
|
||||
return {
|
||||
@@ -1575,10 +1632,18 @@ function connectionStringExportState(pg: PostgresHostConfig, inspection: SecretI
|
||||
sourceRef: item.sourceSecretRef,
|
||||
targetRef: item.writeToSecretSource.sourceRef,
|
||||
key: item.writeToSecretSource.key,
|
||||
exists,
|
||||
present: before !== undefined && before.length > 0,
|
||||
before: {
|
||||
exists,
|
||||
present: beforePresent,
|
||||
fingerprint: beforeFingerprint,
|
||||
},
|
||||
after: {
|
||||
exists: materialize ? true : exists,
|
||||
present: materialize ? true : beforePresent,
|
||||
fingerprint: materialize ? desiredFingerprint : beforeFingerprint,
|
||||
},
|
||||
action: before === rendered ? "none" : before === undefined ? "create" : "update",
|
||||
fingerprint: fingerprintValues({ [item.writeToSecretSource.key]: rendered }, [item.writeToSecretSource.key]),
|
||||
desiredFingerprint,
|
||||
consumers: item.consumers,
|
||||
valuesPrinted: false,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user