feat: add download command to retrieve PEM bundle from Key Vault

This commit is contained in:
2026-05-21 23:47:49 +02:00
parent a92bdabac3
commit 72e47e2a9d
3 changed files with 40 additions and 1 deletions
+19
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env node
import { writeFileSync } from 'node:fs';
import { Command } from 'commander';
import { loadConfig } from './lib/config.js';
import { domainToCertName, Provisioner } from './lib/provisioner.js';
@@ -119,6 +120,24 @@ sharedOptions(
if (result.errors.length > 0) process.exit(1);
});
sharedOptions(
program
.command('download <domain>')
.description('Download the PEM bundle (private key + certificate + chain) for a domain')
.option('--output <file>', 'Write to file instead of stdout')
).action(async (domain: string, options: Record<string, unknown>) => {
applyOverrides(options);
const config = loadConfig();
const provisioner = new Provisioner(config);
const pem = await provisioner.download(domain);
if (options['output']) {
writeFileSync(String(options['output']), pem, 'utf8');
console.log(`Certificate written to ${options['output']}`);
} else {
process.stdout.write(pem);
}
});
program.parseAsync(process.argv).catch((err: unknown) => {
console.error(err instanceof Error ? err.message : String(err));
process.exit(1);
+7
View File
@@ -131,6 +131,13 @@ export class Provisioner {
return result;
}
async download(domain: string): Promise<string> {
const certName = domainToCertName(domain);
const pem = await this.store.getSecret(certName);
if (!pem) throw new Error(`Certificate not found in KeyVault: ${certName}`);
return pem;
}
async scan(): Promise<DomainRecord[]> {
return scanDnsZones(this.credential, this.config);
}