cangku/backend/src/services/remoteEnrollmentService.js

68 lines
2.2 KiB
JavaScript

const fs = require('fs');
const os = require('os');
const path = require('path');
const { pathToFileURL } = require('url');
const REPOSITORY_ROOT = path.resolve(__dirname, '../../..');
const SETUP_MODULE_PATH = path.join(REPOSITORY_ROOT, 'scripts', 'setup-remote.mjs');
const RESTART_MARKER_PATH = path.join(REPOSITORY_ROOT, '.remote-access', 'restart-requested.json');
const DEFAULT_BOOTSTRAP_ENDPOINT = 'https://ck.yydd.ai:8443/v1/enroll';
function normalizeEndpoint(value) {
const endpoint = new URL(String(value || DEFAULT_BOOTSTRAP_ENDPOINT).trim());
if (endpoint.protocol !== 'https:' || endpoint.username || endpoint.password) {
throw new Error('配置请求地址必须是没有内嵌账号密码的 HTTPS 地址');
}
return endpoint.toString();
}
async function enrollRemoteInstallation(input = {}) {
const endpoint = normalizeEndpoint(input.endpoint);
const apiKey = String(input.apiKey || '').trim();
const label = String(input.label || os.hostname()).trim();
if (!apiKey) throw new Error('请输入部署 Key');
if (!label || label.length > 80) throw new Error('设备名称必须为 1 到 80 个字符');
const setupModule = await import(pathToFileURL(SETUP_MODULE_PATH).href);
const { enrollment, connection } = await setupModule.configureRemoteAccess({
endpoint,
key: apiKey,
label,
replace: false,
});
return {
installationId: enrollment.installation_id,
certificateValidUntil: enrollment.ssh.valid_until,
systemDatabase: {
host: '127.0.0.1',
port: connection.localDatabasePort,
database: enrollment.database.name,
},
redis: {
host: enrollment.redis.host,
port: Number(enrollment.redis.port),
tls: true,
},
adminUsername: enrollment.application_admin.username,
adminPassword: enrollment.application_admin.password,
};
}
function scheduleRemoteRestart() {
fs.mkdirSync(path.dirname(RESTART_MARKER_PATH), { recursive: true, mode: 0o700 });
fs.writeFileSync(
RESTART_MARKER_PATH,
`${JSON.stringify({ requestedAt: new Date().toISOString() })}\n`,
{ mode: 0o600 }
);
fs.chmodSync(RESTART_MARKER_PATH, 0o600);
}
module.exports = {
DEFAULT_BOOTSTRAP_ENDPOINT,
enrollRemoteInstallation,
normalizeEndpoint,
scheduleRemoteRestart,
};