75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
/**
|
||||
|
|
* 只对**单个域名**做「签发 + 部署」,别的域名一律不碰。
|
|||
|
|
*
|
|||
|
|
* 为什么需要它(2026-10-06 加):
|
|||
|
|
* 容器只有一个 `POST /renew`,而它调的是 `renewAll` —— **没有域名过滤**。
|
|||
|
|
* 想单独把一个域名提前换掉时,`{force:true}` 会把配置里**所有**域名
|
|||
|
|
* 一起重签一遍:多烧 2 个 CA 订单,还会把本来好好的 t-t.live / 200181.xyz
|
|||
|
|
* 一起换掉、增加无关的线上变更面。这个脚本把「只动一个域名」变成可选操作。
|
|||
|
|
*
|
|||
|
|
* 与 `redeploy.mjs` 的分工:
|
|||
|
|
* · `redeploy.mjs` —— **复用已签好的证书**,只重跑部署(不碰 ACME)
|
|||
|
|
* · `renew-one.mjs` —— 真的去 CA **签一张新的**,然后部署
|
|||
|
|
*
|
|||
|
|
* 用法:
|
|||
|
|
* docker exec cn-certkeeper node src/renew-one.mjs usj.cc
|
|||
|
|
* docker exec cn-certkeeper node src/renew-one.mjs usj.cc --no-deploy # 只签不部署
|
|||
|
|
* docker exec cn-certkeeper node src/renew-one.mjs usj.cc --dry # 只看会做什么
|
|||
|
|
*
|
|||
|
|
* ★ 默认 `force: true`(线上还剩 60 天也要换)—— 这正是本脚本的用途。
|
|||
|
|
* 想走「按阈值判断」请直接调 /renew。
|
|||
|
|
*/
|
|||
|
|
import path from 'node:path';
|
|||
|
|
import { createRequire } from 'node:module';
|
|||
|
|
import { fileURLToPath } from 'node:url';
|
|||
|
|
import { FileKV } from './kv-file.mjs';
|
|||
|
|
|
|||
|
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|||
|
|
const require = createRequire(import.meta.url);
|
|||
|
|
const lib = (n) => require(path.resolve(HERE, '../lib', `${n}.js`));
|
|||
|
|
|
|||
|
|
const argv = process.argv.slice(2);
|
|||
|
|
const NAME = argv.find((a) => !a.startsWith('--'));
|
|||
|
|
const DRY = argv.includes('--dry');
|
|||
|
|
const NO_DEPLOY = argv.includes('--no-deploy');
|
|||
|
|
if (!NAME) {
|
|||
|
|
console.error('用法:node src/renew-one.mjs <域名> [--no-deploy] [--dry]');
|
|||
|
|
process.exit(2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const kv = new FileKV(process.env.DATA_DIR || '/data');
|
|||
|
|
const env = {
|
|||
|
|
RSS_KV: kv,
|
|||
|
|
TOKEN_SECRET: String(process.env.TOKEN_SECRET || '').trim(),
|
|||
|
|
// 留空 → 探针直接走本机 node:tls,不再绕 editor-api
|
|||
|
|
EDITOR_API_BASE: '',
|
|||
|
|
EDITOR_TOKEN: '',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const { loadConfig } = lib('certstore');
|
|||
|
|
const { issueDomain, RENEW_BEFORE_DAYS } = lib('certissue');
|
|||
|
|
|
|||
|
|
const cfg = await loadConfig(env);
|
|||
|
|
const d = cfg.domains.find((x) => x.name === NAME);
|
|||
|
|
if (!d) {
|
|||
|
|
console.error(`配置里没有域名「${NAME}」(现有:${cfg.domains.map((x) => x.name).join(', ')})`);
|
|||
|
|
process.exit(2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log(`域名 ${NAME}`);
|
|||
|
|
console.log(` SAN : ${(d.san || []).join(', ')}`);
|
|||
|
|
console.log(` DNS 凭据 : ${d.dns}`);
|
|||
|
|
console.log(` 部署目标 : ${(d.deploy || []).join(', ')}`);
|
|||
|
|
console.log(` 1Panel 站点: ${(d.one_panel_sites || []).join(', ')}`);
|
|||
|
|
console.log(` 多吉云域名 : ${(d.dogecloud_domains || []).join(', ')}`);
|
|||
|
|
console.log(` 续期阈值 : ${RENEW_BEFORE_DAYS} 天(本脚本 force,忽略阈值)`);
|
|||
|
|
console.log(` 部署 : ${NO_DEPLOY ? '否(--no-deploy)' : '是'}`);
|
|||
|
|
if (DRY) {
|
|||
|
|
console.log('\n[dry] 不实际签发。');
|
|||
|
|
process.exit(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const out = await issueDomain(env, d, { force: true, noDeploy: NO_DEPLOY, by: 'renew-one' });
|
|||
|
|
console.log('\n=== 结果 ===');
|
|||
|
|
console.log(JSON.stringify(out, null, 2));
|
|||
|
|
if (!out.ok) process.exitCode = 1;
|