40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
|
|
// lib/remote.ts
|
||
|
|
//
|
||
|
|
// Builds the SSH connection that @pulumi/command's remote.Command uses to run
|
||
|
|
// in-VM control-plane operations (docker exec over SSH) — ADR-007. It targets
|
||
|
|
// the SAME host the Docker provider does: the config VM coordinates, overridable
|
||
|
|
// by FOUNDATION_DOCKER_HOST (ssh://user@host[:port]) for local validation, with
|
||
|
|
// the private key read from SSH_PRIVATE_KEY_PATH (CONTRACT_001 §1) — never config.
|
||
|
|
import * as fs from "fs";
|
||
|
|
import * as pulumi from "@pulumi/pulumi";
|
||
|
|
import * as command from "@pulumi/command";
|
||
|
|
import { BaseCtx } from "./context";
|
||
|
|
|
||
|
|
/** Parsed `ssh://user@host:port` override, if FOUNDATION_DOCKER_HOST is set. */
|
||
|
|
function parseOverride():
|
||
|
|
| { host: string; user?: string; port?: number }
|
||
|
|
| undefined {
|
||
|
|
const o = process.env.FOUNDATION_DOCKER_HOST;
|
||
|
|
if (!o) return undefined;
|
||
|
|
const m = o.match(/^ssh:\/\/(?:([^@]+)@)?([^:/]+)(?::(\d+))?/);
|
||
|
|
if (!m) return undefined;
|
||
|
|
return { user: m[1], host: m[2], port: m[3] ? Number(m[3]) : undefined };
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The remote.Command connection to the foundation VM. The private key is read
|
||
|
|
* from disk and marked secret so it is redacted in logs and encrypted in state.
|
||
|
|
*/
|
||
|
|
export function vmConnection(
|
||
|
|
ctx: BaseCtx,
|
||
|
|
): command.types.input.remote.ConnectionArgs {
|
||
|
|
const ov = parseOverride();
|
||
|
|
const privateKey = pulumi.secret(fs.readFileSync(ctx.sshKeyPath, "utf8"));
|
||
|
|
return {
|
||
|
|
host: ov?.host ?? ctx.cfg.vm.host,
|
||
|
|
port: ov?.port ?? ctx.cfg.vm.sshPort,
|
||
|
|
user: ov?.user ?? ctx.cfg.vm.user,
|
||
|
|
privateKey,
|
||
|
|
};
|
||
|
|
}
|