feat: socle BDD (tâche 1.9 Phase 1-2) + moteur APT (tâche 2 SJ-0→3) + WIP capabilities/auth/Rust
Checkpoint multi-chantiers (arbre vert : tsc 0 erreur, 70 tests, build OK). - tâche 1.9 Phase 1 : schéma socle (machine_state/events/reports/raw_artifacts/ hardware/metrics + colonnes étendues) + wiring refresh/execute. Migration 0002. - tâche 1.9 Phase 2 : machine_credentials + machine_host_keys (non destructif, dual-read + backfill). Migration 0003. Fix séquence journal de migration. - tâche 2 : SJ-0 (types étendus rétro-compatibles, réducteur Docker, resolveTemplate), SJ-1 (update-analyze enrichi), SJ-2 (apply + diff dpkg + timeout inactivité SSH), SJ-3 (reboot vérifié boot_id). - WIP parallèle inclus : /api/capabilities, auth/apiTokens/apiClients, system metrics, scaffold app_rust, ajustements frontend. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { encryptSecret, decryptSecret } from "../crypto/secrets.js";
|
||||
import { env } from "../env.js";
|
||||
import { runPlain, type SshCreds } from "../ssh/client.js";
|
||||
import type { MachineView, OsFamily } from "@shared/types.js";
|
||||
import { writeCredentials, readCredentials, resolveCreds } from "./credentials.js";
|
||||
|
||||
export interface CreateMachineInput {
|
||||
name: string;
|
||||
@@ -37,12 +38,17 @@ function toView(m: MachineRow): MachineView {
|
||||
|
||||
export function getCreds(m: MachineRow): SshCreds {
|
||||
const key = env.requireMasterKey();
|
||||
const { encPassword, encSudoPassword } = resolveCreds(
|
||||
{ encPassword: m.encPassword, encSudoPassword: m.encSudoPassword },
|
||||
readCredentials(m.id),
|
||||
);
|
||||
if (!encPassword) throw new Error("Aucun secret pour cette machine");
|
||||
return {
|
||||
hostname: m.hostname,
|
||||
port: m.port,
|
||||
username: m.username,
|
||||
password: decryptSecret(m.encPassword, key),
|
||||
sudoPassword: m.encSudoPassword ? decryptSecret(m.encSudoPassword, key) : null,
|
||||
password: decryptSecret(encPassword, key),
|
||||
sudoPassword: encSudoPassword ? decryptSecret(encSudoPassword, key) : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,12 +88,19 @@ export async function createMachine(input: CreateMachineInput): Promise<MachineV
|
||||
};
|
||||
const os = await testConnection(creds); // lève si la connexion échoue
|
||||
const id = randomUUID();
|
||||
const now = new Date().toISOString();
|
||||
const row: MachineRow = {
|
||||
id,
|
||||
name: input.name,
|
||||
hostname: input.hostname,
|
||||
port: input.port,
|
||||
osFamily: os.family,
|
||||
osVersion: os.version || null,
|
||||
osCodename: null,
|
||||
arch: null,
|
||||
machineKind: null,
|
||||
virtualization: null,
|
||||
hardwareProfile: null,
|
||||
username: input.username,
|
||||
encPassword: encryptSecret(input.password, key),
|
||||
encSudoPassword: input.sudoPassword ? encryptSecret(input.sudoPassword, key) : null,
|
||||
@@ -95,9 +108,13 @@ export async function createMachine(input: CreateMachineInput): Promise<MachineV
|
||||
aptProxyUrl: input.aptProxyUrl ?? null,
|
||||
status: "unknown",
|
||||
lastCheckedAt: null,
|
||||
createdAt: new Date().toISOString(),
|
||||
lastSeenAt: null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
};
|
||||
db.insert(schema.machines).values(row).run();
|
||||
writeCredentials({ machineId: id, encPassword: row.encPassword, encSudoPassword: row.encSudoPassword });
|
||||
return toView(row);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user