perf: fetch SSH key list once before loop in ensureSshKey() (#2194)

Both Hetzner and DigitalOcean were calling GET /ssh_keys inside the
per-key loop, causing N redundant API round-trips when a user had
multiple local SSH keys. Move the fetch outside the loop so it runs
exactly once regardless of how many keys are being registered.

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
L 2026-03-04 14:47:21 -05:00 committed by GitHub
parent 711ed70b22
commit 846d655706
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 10 additions and 10 deletions

View file

@ -570,6 +570,11 @@ export async function ensureDoToken(): Promise<boolean> {
export async function ensureSshKey(): Promise<void> {
const selectedKeys = await ensureSshKeys();
// Fetch registered keys once before the loop to avoid N+1 API calls
const keysText = await doApi("GET", "/account/keys");
const data = parseJsonObj(keysText);
const keys = toObjectArray(data?.ssh_keys);
for (const key of selectedKeys) {
const fingerprint = getSshFingerprint(key.pubPath);
if (!fingerprint) {
@ -577,11 +582,6 @@ export async function ensureSshKey(): Promise<void> {
continue;
}
// Check if key is registered with DigitalOcean
const keysText = await doApi("GET", "/account/keys");
const data = parseJsonObj(keysText);
const keys = toObjectArray(data?.ssh_keys);
const found = keys.some((k: Record<string, unknown>) => {
const fp = k.fingerprint || "";
return fp === fingerprint;

View file

@ -182,15 +182,15 @@ export async function ensureHcloudToken(): Promise<void> {
export async function ensureSshKey(): Promise<void> {
const selectedKeys = await ensureSshKeys();
// Fetch registered keys once before the loop to avoid N+1 API calls
const resp = await hetznerApi("GET", "/ssh_keys");
const data = parseJsonObj(resp);
const sshKeys = toObjectArray(data?.ssh_keys);
for (const key of selectedKeys) {
const fingerprint = getSshFingerprint(key.pubPath);
const pubKey = readFileSync(key.pubPath, "utf-8").trim();
// Check if key is already registered
const resp = await hetznerApi("GET", "/ssh_keys");
const data = parseJsonObj(resp);
const sshKeys = toObjectArray(data?.ssh_keys);
const alreadyRegistered = sshKeys.some((k) => fingerprint && k.fingerprint === fingerprint);
if (alreadyRegistered) {