Scrape certs from ALL resolvers

This commit is contained in:
Owen
2026-04-29 14:29:15 -07:00
parent 2ffe254879
commit a55842ffff
2 changed files with 27 additions and 15 deletions

View File

@@ -274,10 +274,7 @@ function detectWildcard(
return { wildcard: false, wildcardSan: null }; return { wildcard: false, wildcardSan: null };
} }
async function syncAcmeCerts( async function syncAcmeCerts(acmeJsonPath: string): Promise<void> {
acmeJsonPath: string,
resolver: string
): Promise<void> {
let raw: string; let raw: string;
try { try {
raw = fs.readFileSync(acmeJsonPath, "utf8"); raw = fs.readFileSync(acmeJsonPath, "utf8");
@@ -294,15 +291,32 @@ async function syncAcmeCerts(
return; return;
} }
const resolvers = Object.keys(acmeJson || {});
if (resolvers.length === 0) {
logger.debug(`acmeCertSync: no resolvers found in acme.json`);
return;
}
// Collect certificates from every resolver. If the same domain appears in
// multiple resolvers, the last one wins (resolvers iterated in object order).
const allCerts: AcmeCert[] = [];
for (const resolver of resolvers) {
const resolverData = acmeJson[resolver]; const resolverData = acmeJson[resolver];
if (!resolverData || !Array.isArray(resolverData.Certificates)) { if (!resolverData || !Array.isArray(resolverData.Certificates)) {
logger.debug( logger.debug(
`acmeCertSync: no certificates found for resolver "${resolver}"` `acmeCertSync: no certificates found for resolver "${resolver}"`
); );
return; continue;
}
logger.debug(
`acmeCertSync: found ${resolverData.Certificates.length} certificate(s) for resolver "${resolver}"`
);
for (const cert of resolverData.Certificates) {
allCerts.push(cert);
}
} }
for (const cert of resolverData.Certificates) { for (const cert of allCerts) {
const domain = cert?.domain?.main; const domain = cert?.domain?.main;
if (!domain || typeof domain !== "string") { if (!domain || typeof domain !== "string") {
@@ -531,20 +545,19 @@ export function initAcmeCertSync(): void {
const acmeJsonPath = const acmeJsonPath =
privateConfigData.acme?.acme_json_path ?? privateConfigData.acme?.acme_json_path ??
"config/letsencrypt/acme.json"; "config/letsencrypt/acme.json";
const resolver = privateConfigData.acme?.resolver ?? "letsencrypt";
const intervalMs = privateConfigData.acme?.sync_interval_ms ?? 5000; const intervalMs = privateConfigData.acme?.sync_interval_ms ?? 5000;
logger.debug( logger.debug(
`acmeCertSync: starting ACME cert sync from "${acmeJsonPath}" using resolver "${resolver}" every ${intervalMs}ms` `acmeCertSync: starting ACME cert sync from "${acmeJsonPath}" across all resolvers every ${intervalMs}ms`
); );
// Run immediately on init, then on the configured interval // Run immediately on init, then on the configured interval
syncAcmeCerts(acmeJsonPath, resolver).catch((err) => { syncAcmeCerts(acmeJsonPath).catch((err) => {
logger.error(`acmeCertSync: error during initial sync: ${err}`); logger.error(`acmeCertSync: error during initial sync: ${err}`);
}); });
setInterval(() => { setInterval(() => {
syncAcmeCerts(acmeJsonPath, resolver).catch((err) => { syncAcmeCerts(acmeJsonPath).catch((err) => {
logger.error(`acmeCertSync: error during sync: ${err}`); logger.error(`acmeCertSync: error during sync: ${err}`);
}); });
}, intervalMs); }, intervalMs);

View File

@@ -102,7 +102,6 @@ export const privateConfigSchema = z.object({
.string() .string()
.optional() .optional()
.default("config/letsencrypt/acme.json"), .default("config/letsencrypt/acme.json"),
resolver: z.string().optional().default("letsencrypt"),
sync_interval_ms: z.number().optional().default(5000) sync_interval_ms: z.number().optional().default(5000)
}) })
.optional(), .optional(),