diff --git a/bastion/package.json b/bastion/package.json index 29fb506..6ce9b42 100644 --- a/bastion/package.json +++ b/bastion/package.json @@ -1,34 +1,22 @@ { - "name": "lab-bastion", + "name": "lab", "version": "0.1.0", "private": true, "description": "PXE bastion server for discover-first bare-metal provisioning", "type": "module", - "bin": { - "bastion": "./dist/cli/index.js" - }, - "main": "./dist/server/main.js", "scripts": { - "build": "tsc", - "dev": "tsx src/cli/index.ts", - "start": "node dist/cli/index.js", + "build": "pnpm -r run build", "test": "vitest", "test:run": "vitest run", - "lint": "tsc --noEmit", - "clean": "rimraf dist" + "typecheck": "tsc --build", + "clean": "pnpm -r run clean && rimraf node_modules", + "lint": "eslint 'src/*/src/**/*.ts'" }, "engines": { "node": ">=20.0.0", "pnpm": ">=9.0.0" }, "packageManager": "pnpm@9.15.0", - "dependencies": { - "@fastify/static": "^8.0.0", - "commander": "^13.0.0", - "execa": "^9.5.0", - "fastify": "^5.0.0", - "winston": "^3.17.0" - }, "devDependencies": { "@types/node": "^22.10.0", "rimraf": "^6.0.0", diff --git a/bastion/pnpm-lock.yaml b/bastion/pnpm-lock.yaml index a437756..73fd88c 100644 --- a/bastion/pnpm-lock.yaml +++ b/bastion/pnpm-lock.yaml @@ -7,22 +7,6 @@ settings: importers: .: - dependencies: - '@fastify/static': - specifier: ^8.0.0 - version: 8.3.0 - commander: - specifier: ^13.0.0 - version: 13.1.0 - execa: - specifier: ^9.5.0 - version: 9.6.1 - fastify: - specifier: ^5.0.0 - version: 5.8.2 - winston: - specifier: ^3.17.0 - version: 3.19.0 devDependencies: '@types/node': specifier: ^22.10.0 @@ -40,6 +24,46 @@ importers: specifier: ^3.0.0 version: 3.2.4(@types/node@22.19.15)(tsx@4.21.0) + src/bastion: + dependencies: + '@fastify/static': + specifier: ^8.0.0 + version: 8.3.0 + '@lab/shared': + specifier: workspace:* + version: link:../shared + execa: + specifier: ^9.5.0 + version: 9.6.1 + fastify: + specifier: ^5.0.0 + version: 5.8.2 + winston: + specifier: ^3.17.0 + version: 3.19.0 + devDependencies: + '@types/node': + specifier: ^22.10.0 + version: 22.19.15 + + src/cli: + dependencies: + '@lab/bastion': + specifier: workspace:* + version: link:../bastion + '@lab/shared': + specifier: workspace:* + version: link:../shared + commander: + specifier: ^13.0.0 + version: 13.1.0 + devDependencies: + '@types/node': + specifier: ^22.10.0 + version: 22.19.15 + + src/shared: {} + packages: '@colors/colors@1.6.0': diff --git a/bastion/pnpm-workspace.yaml b/bastion/pnpm-workspace.yaml new file mode 100644 index 0000000..2ddfbd3 --- /dev/null +++ b/bastion/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "src/*" diff --git a/bastion/src/bastion/package.json b/bastion/src/bastion/package.json new file mode 100644 index 0000000..8326397 --- /dev/null +++ b/bastion/src/bastion/package.json @@ -0,0 +1,31 @@ +{ + "name": "@lab/bastion", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/main.js", + "types": "./dist/main.d.ts", + "exports": { + ".": { + "import": "./dist/main.js", + "types": "./dist/main.d.ts" + } + }, + "scripts": { + "build": "tsc --build", + "clean": "rimraf dist", + "dev": "tsx src/main.ts", + "test": "vitest", + "test:run": "vitest run" + }, + "dependencies": { + "@fastify/static": "^8.0.0", + "@lab/shared": "workspace:*", + "execa": "^9.5.0", + "fastify": "^5.0.0", + "winston": "^3.17.0" + }, + "devDependencies": { + "@types/node": "^22.10.0" + } +} diff --git a/bastion/src/server/config.ts b/bastion/src/bastion/src/config.ts similarity index 77% rename from bastion/src/server/config.ts rename to bastion/src/bastion/src/config.ts index 771bf33..1ec5fc3 100644 --- a/bastion/src/server/config.ts +++ b/bastion/src/bastion/src/config.ts @@ -1,31 +1,6 @@ // Configuration from environment variables with sensible defaults. -export interface BastionConfig { - fedoraVersion: string; - arch: string; - httpPort: number; - timezone: string; - locale: string; - bastionDir: string; - domain: string; - dhcpMode: "proxy" | "full"; - dhcpRangeStart: string; - dhcpRangeEnd: string; - // Flags - skipDnsmasq?: boolean; - skipArtifacts?: boolean; - // Derived at runtime - iface: string; - serverIp: string; - network: string; - gateway: string; - sshKeys: string[]; - adminUser: string; - fedoraMirror: string; - tftpDir: string; - httpDir: string; - stateFile: string; -} +import type { BastionConfig } from "@lab/shared"; export function loadConfig(overrides: Partial = {}): BastionConfig { const fedoraVersion = overrides.fedoraVersion ?? process.env["FEDORA_VERSION"] ?? "43"; diff --git a/bastion/src/server/main.ts b/bastion/src/bastion/src/main.ts similarity index 94% rename from bastion/src/server/main.ts rename to bastion/src/bastion/src/main.ts index 4e29d27..21b470e 100644 --- a/bastion/src/server/main.ts +++ b/bastion/src/bastion/src/main.ts @@ -3,12 +3,13 @@ import { mkdirSync, writeFileSync, existsSync, copyFileSync, symlinkSync } from "node:fs"; import { execSync } from "node:child_process"; -import { loadConfig, type BastionConfig } from "./config.js"; +import type { BastionConfig } from "@lab/shared"; +import { loadConfig } from "./config.js"; import { populateNetworkConfig } from "./services/network.js"; import { createApp } from "./server.js"; import { startDnsmasq, stopDnsmasq, generateDnsmasqConf } from "./services/dnsmasq.js"; import { generateDiscoverKickstart } from "./services/kickstart-generator.js"; -import { renderBootIpxe } from "../templates/boot.ipxe.js"; +import { renderBootIpxe } from "./templates/boot.ipxe.js"; import { logger } from "./services/logger.js"; function copyIfMissing(src: string, dest: string, label: string): void { @@ -179,8 +180,8 @@ function printBanner(config: BastionConfig): void { console.log(" \x1b[33mIt will be inventoried and rebooted automatically.\x1b[0m"); console.log(""); console.log(" Commands (from another terminal):"); - console.log(" \x1b[1mbastion list\x1b[0m -- show machines"); - console.log(" \x1b[1mbastion install \x1b[0m -- queue install"); + console.log(" \x1b[1mlab list\x1b[0m -- show machines"); + console.log(" \x1b[1mlab install \x1b[0m -- queue install"); console.log(""); console.log(" Press \x1b[1mCtrl-C\x1b[0m to stop."); console.log(""); diff --git a/bastion/src/server/routes/api.ts b/bastion/src/bastion/src/routes/api.ts similarity index 97% rename from bastion/src/server/routes/api.ts rename to bastion/src/bastion/src/routes/api.ts index b37ddb0..8133558 100644 --- a/bastion/src/server/routes/api.ts +++ b/bastion/src/bastion/src/routes/api.ts @@ -5,7 +5,8 @@ // /api/discover - receive hardware discovery reports from PXE-booted machines import type { FastifyInstance } from "fastify"; -import type { StateManager, HardwareInfo, InstalledInfo } from "../services/state.js"; +import type { HardwareInfo, InstalledInfo } from "@lab/shared"; +import type { StateManager } from "../services/state.js"; import { logger } from "../services/logger.js"; export function registerApiRoutes( diff --git a/bastion/src/server/routes/dispatch.ts b/bastion/src/bastion/src/routes/dispatch.ts similarity index 95% rename from bastion/src/server/routes/dispatch.ts rename to bastion/src/bastion/src/routes/dispatch.ts index a8fd91a..113119c 100644 --- a/bastion/src/server/routes/dispatch.ts +++ b/bastion/src/bastion/src/routes/dispatch.ts @@ -5,13 +5,13 @@ // - unknown -> discovery mode (collect hardware, POST to bastion) import type { FastifyInstance } from "fastify"; -import type { BastionConfig } from "../config.js"; +import type { BastionConfig } from "@lab/shared"; import type { StateManager } from "../services/state.js"; import { renderDiscoverIpxe, renderInstallIpxe, renderLocalBootIpxe, -} from "../../templates/boot.ipxe.js"; +} from "../templates/boot.ipxe.js"; import { logger } from "../services/logger.js"; export function registerDispatchRoutes( diff --git a/bastion/src/server/routes/kickstart.ts b/bastion/src/bastion/src/routes/kickstart.ts similarity index 95% rename from bastion/src/server/routes/kickstart.ts rename to bastion/src/bastion/src/routes/kickstart.ts index dc43261..62c67eb 100644 --- a/bastion/src/server/routes/kickstart.ts +++ b/bastion/src/bastion/src/routes/kickstart.ts @@ -2,7 +2,7 @@ // Serves per-MAC install kickstart and the static discovery kickstart. import type { FastifyInstance } from "fastify"; -import type { BastionConfig } from "../config.js"; +import type { BastionConfig } from "@lab/shared"; import type { StateManager } from "../services/state.js"; import { generateInstallKickstart, generateDiscoverKickstart } from "../services/kickstart-generator.js"; diff --git a/bastion/src/server/server.ts b/bastion/src/bastion/src/server.ts similarity index 97% rename from bastion/src/server/server.ts rename to bastion/src/bastion/src/server.ts index d7d2215..72df552 100644 --- a/bastion/src/server/server.ts +++ b/bastion/src/bastion/src/server.ts @@ -3,7 +3,7 @@ import Fastify from "fastify"; import fastifyStatic from "@fastify/static"; import { mkdirSync, existsSync } from "node:fs"; -import type { BastionConfig } from "./config.js"; +import type { BastionConfig } from "@lab/shared"; import { StateManager } from "./services/state.js"; import { logger } from "./services/logger.js"; import { registerDispatchRoutes } from "./routes/dispatch.js"; diff --git a/bastion/src/server/services/dnsmasq.ts b/bastion/src/bastion/src/services/dnsmasq.ts similarity index 94% rename from bastion/src/server/services/dnsmasq.ts rename to bastion/src/bastion/src/services/dnsmasq.ts index ce084fb..d1bfa87 100644 --- a/bastion/src/server/services/dnsmasq.ts +++ b/bastion/src/bastion/src/services/dnsmasq.ts @@ -4,8 +4,8 @@ import { writeFileSync, mkdirSync } from "node:fs"; import { dirname } from "node:path"; import type { ResultPromise } from "execa"; import { execa } from "execa"; -import type { BastionConfig } from "../config.js"; -import { renderDnsmasqConf } from "../../templates/dnsmasq.conf.js"; +import type { BastionConfig } from "@lab/shared"; +import { renderDnsmasqConf } from "../templates/dnsmasq.conf.js"; import { logger } from "./logger.js"; type DnsmasqProcess = ResultPromise<{ stdout: "pipe"; stderr: "pipe" }>; diff --git a/bastion/src/server/services/kickstart-generator.ts b/bastion/src/bastion/src/services/kickstart-generator.ts similarity index 87% rename from bastion/src/server/services/kickstart-generator.ts rename to bastion/src/bastion/src/services/kickstart-generator.ts index 821f9df..47e257e 100644 --- a/bastion/src/server/services/kickstart-generator.ts +++ b/bastion/src/bastion/src/services/kickstart-generator.ts @@ -1,9 +1,9 @@ // Generate kickstart content for discovery and install modes. // Uses template literal functions -- no external template engine. -import type { BastionConfig } from "../config.js"; -import { renderDiscoverKickstart } from "../../templates/discover.ks.js"; -import { renderInstallKickstart, type InstallKickstartParams } from "../../templates/install.ks.js"; +import type { BastionConfig } from "@lab/shared"; +import { renderDiscoverKickstart } from "../templates/discover.ks.js"; +import { renderInstallKickstart, type InstallKickstartParams } from "../templates/install.ks.js"; /** * Generate a discovery kickstart that collects hardware info and POSTs to bastion. diff --git a/bastion/src/server/services/logger.ts b/bastion/src/bastion/src/services/logger.ts similarity index 100% rename from bastion/src/server/services/logger.ts rename to bastion/src/bastion/src/services/logger.ts diff --git a/bastion/src/server/services/network.ts b/bastion/src/bastion/src/services/network.ts similarity index 99% rename from bastion/src/server/services/network.ts rename to bastion/src/bastion/src/services/network.ts index 8eafda2..b5dcbe9 100644 --- a/bastion/src/server/services/network.ts +++ b/bastion/src/bastion/src/services/network.ts @@ -4,7 +4,7 @@ import { execSync } from "node:child_process"; import { readFileSync, existsSync, mkdirSync } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; -import type { BastionConfig } from "../config.js"; +import type { BastionConfig } from "@lab/shared"; import { logger } from "./logger.js"; /** diff --git a/bastion/src/server/services/state.ts b/bastion/src/bastion/src/services/state.ts similarity index 61% rename from bastion/src/server/services/state.ts rename to bastion/src/bastion/src/services/state.ts index b48091f..01ca1f0 100644 --- a/bastion/src/server/services/state.ts +++ b/bastion/src/bastion/src/services/state.ts @@ -2,45 +2,10 @@ import { readFileSync, writeFileSync, renameSync, mkdirSync } from "node:fs"; import { dirname } from "node:path"; +import type { BastionState } from "@lab/shared"; -export interface HardwareInfo { - mac: string; - product: string; - board: string; - serial: string; - manufacturer: string; - cpu_model: string; - cpu_cores: number; - memory_gb: number; - arch: string; - disks: Array<{ name: string; size_gb: number; model: string }>; - nics: Array<{ name: string; mac: string; state: string }>; - first_seen: string; - last_seen: string; -} - -export interface InstallConfig { - hostname: string; - disk: string; - role: "worker" | "infra"; - queued_at: string; - progress?: string; - progress_at?: string; - progress_detail?: string; -} - -export interface InstalledInfo { - hostname: string; - role: string; - ip: string; - installed_at: string; -} - -export interface BastionState { - discovered: Record; - install_queue: Record; - installed: Record; -} +// Re-export types for consumers that import from this module +export type { HardwareInfo, InstallConfig, InstalledInfo, BastionState } from "@lab/shared"; const EMPTY_STATE: BastionState = { discovered: {}, diff --git a/bastion/src/templates/boot.ipxe.ts b/bastion/src/bastion/src/templates/boot.ipxe.ts similarity index 100% rename from bastion/src/templates/boot.ipxe.ts rename to bastion/src/bastion/src/templates/boot.ipxe.ts diff --git a/bastion/src/templates/discover.ks.ts b/bastion/src/bastion/src/templates/discover.ks.ts similarity index 100% rename from bastion/src/templates/discover.ks.ts rename to bastion/src/bastion/src/templates/discover.ks.ts diff --git a/bastion/src/templates/dnsmasq.conf.ts b/bastion/src/bastion/src/templates/dnsmasq.conf.ts similarity index 97% rename from bastion/src/templates/dnsmasq.conf.ts rename to bastion/src/bastion/src/templates/dnsmasq.conf.ts index f40c15d..b2e2b5a 100644 --- a/bastion/src/templates/dnsmasq.conf.ts +++ b/bastion/src/bastion/src/templates/dnsmasq.conf.ts @@ -2,7 +2,7 @@ // Supports proxy DHCP mode (alongside existing DHCP) and full DHCP mode. // Handles UEFI HTTP Boot, iPXE chainloading, and PXE service directives. -import type { BastionConfig } from "../server/config.js"; +import type { BastionConfig } from "@lab/shared"; export function renderDnsmasqConf(config: BastionConfig): string { const { diff --git a/bastion/src/templates/install.ks.ts b/bastion/src/bastion/src/templates/install.ks.ts similarity index 100% rename from bastion/src/templates/install.ks.ts rename to bastion/src/bastion/src/templates/install.ks.ts diff --git a/bastion/src/bastion/tsconfig.json b/bastion/src/bastion/tsconfig.json new file mode 100644 index 0000000..4c4fbfc --- /dev/null +++ b/bastion/src/bastion/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "references": [ + { "path": "../shared" } + ] +} diff --git a/bastion/src/bastion/vitest.config.ts b/bastion/src/bastion/vitest.config.ts new file mode 100644 index 0000000..aebf14f --- /dev/null +++ b/bastion/src/bastion/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineProject } from 'vitest/config'; + +export default defineProject({ + test: { + name: 'bastion', + include: ['tests/**/*.test.ts'], + }, +}); diff --git a/bastion/src/cli/package.json b/bastion/src/cli/package.json new file mode 100644 index 0000000..fbee854 --- /dev/null +++ b/bastion/src/cli/package.json @@ -0,0 +1,26 @@ +{ + "name": "@lab/cli", + "version": "0.1.0", + "private": true, + "type": "module", + "bin": { + "lab": "./dist/index.js" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc --build", + "clean": "rimraf dist", + "dev": "tsx src/index.ts", + "test": "vitest", + "test:run": "vitest run" + }, + "dependencies": { + "@lab/bastion": "workspace:*", + "@lab/shared": "workspace:*", + "commander": "^13.0.0" + }, + "devDependencies": { + "@types/node": "^22.10.0" + } +} diff --git a/bastion/src/cli/commands/install.ts b/bastion/src/cli/src/commands/install.ts similarity index 100% rename from bastion/src/cli/commands/install.ts rename to bastion/src/cli/src/commands/install.ts diff --git a/bastion/src/cli/commands/list.ts b/bastion/src/cli/src/commands/list.ts similarity index 97% rename from bastion/src/cli/commands/list.ts rename to bastion/src/cli/src/commands/list.ts index 9fdb7c2..68c9997 100644 --- a/bastion/src/cli/commands/list.ts +++ b/bastion/src/cli/src/commands/list.ts @@ -2,7 +2,7 @@ // Merged view of all known machines with hardware + install info. import type { Command } from "commander"; -import type { BastionState } from "../../server/services/state.js"; +import type { BastionState } from "@lab/shared"; const BOLD = "\x1b[1m"; const GREEN = "\x1b[0;32m"; diff --git a/bastion/src/cli/commands/reprovision.ts b/bastion/src/cli/src/commands/reprovision.ts similarity index 97% rename from bastion/src/cli/commands/reprovision.ts rename to bastion/src/cli/src/commands/reprovision.ts index eb33fec..e5ca203 100644 --- a/bastion/src/cli/commands/reprovision.ts +++ b/bastion/src/cli/src/commands/reprovision.ts @@ -3,7 +3,7 @@ import { execSync } from "node:child_process"; import type { Command } from "commander"; -import type { BastionState } from "../../server/services/state.js"; +import type { BastionState } from "@lab/shared"; export function registerReprovisionCommand(program: Command): void { program diff --git a/bastion/src/cli/commands/serve.ts b/bastion/src/cli/src/commands/serve.ts similarity index 96% rename from bastion/src/cli/commands/serve.ts rename to bastion/src/cli/src/commands/serve.ts index 1922d1a..4b60bac 100644 --- a/bastion/src/cli/commands/serve.ts +++ b/bastion/src/cli/src/commands/serve.ts @@ -2,7 +2,7 @@ // Start the bastion server (HTTP + dnsmasq). import type { Command } from "commander"; -import { startBastion } from "../../server/main.js"; +import { startBastion } from "@lab/bastion"; export function registerServeCommand(program: Command): void { program diff --git a/bastion/src/cli/index.ts b/bastion/src/cli/src/index.ts similarity index 90% rename from bastion/src/cli/index.ts rename to bastion/src/cli/src/index.ts index 408aa77..3a8f90e 100644 --- a/bastion/src/cli/index.ts +++ b/bastion/src/cli/src/index.ts @@ -3,6 +3,7 @@ // Commands: serve, install, list, reprovision import { Command } from "commander"; +import { APP_VERSION } from "@lab/shared"; import { registerServeCommand } from "./commands/serve.js"; import { registerInstallCommand } from "./commands/install.js"; import { registerListCommand } from "./commands/list.js"; @@ -11,9 +12,9 @@ import { registerReprovisionCommand } from "./commands/reprovision.js"; const program = new Command(); program - .name("bastion") + .name("lab") .description("Lab PXE Bastion -- discover-first bare-metal provisioning") - .version("0.1.0"); + .version(APP_VERSION); registerServeCommand(program); registerInstallCommand(program); diff --git a/bastion/src/cli/tsconfig.json b/bastion/src/cli/tsconfig.json new file mode 100644 index 0000000..2ee2ce9 --- /dev/null +++ b/bastion/src/cli/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "references": [ + { "path": "../shared" }, + { "path": "../bastion" } + ] +} diff --git a/bastion/src/cli/vitest.config.ts b/bastion/src/cli/vitest.config.ts new file mode 100644 index 0000000..1cbc8c8 --- /dev/null +++ b/bastion/src/cli/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineProject } from 'vitest/config'; + +export default defineProject({ + test: { + name: 'cli', + include: ['tests/**/*.test.ts'], + }, +}); diff --git a/bastion/src/shared/package.json b/bastion/src/shared/package.json new file mode 100644 index 0000000..55aee71 --- /dev/null +++ b/bastion/src/shared/package.json @@ -0,0 +1,20 @@ +{ + "name": "@lab/shared", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "scripts": { + "build": "tsc --build", + "clean": "rimraf dist", + "test": "vitest", + "test:run": "vitest run" + } +} diff --git a/bastion/src/shared/src/constants/index.ts b/bastion/src/shared/src/constants/index.ts new file mode 100644 index 0000000..fde2bb2 --- /dev/null +++ b/bastion/src/shared/src/constants/index.ts @@ -0,0 +1,4 @@ +// Application-wide constants. + +export const APP_NAME = "lab"; +export const APP_VERSION = "0.1.0"; diff --git a/bastion/src/shared/src/index.ts b/bastion/src/shared/src/index.ts new file mode 100644 index 0000000..b19c334 --- /dev/null +++ b/bastion/src/shared/src/index.ts @@ -0,0 +1,9 @@ +export type { + HardwareInfo, + InstallConfig, + InstalledInfo, + BastionState, + BastionConfig, +} from "./types/index.js"; + +export { APP_NAME, APP_VERSION } from "./constants/index.js"; diff --git a/bastion/src/shared/src/types/config.ts b/bastion/src/shared/src/types/config.ts new file mode 100644 index 0000000..7a4184e --- /dev/null +++ b/bastion/src/shared/src/types/config.ts @@ -0,0 +1,28 @@ +// Configuration types for the bastion server. + +export interface BastionConfig { + fedoraVersion: string; + arch: string; + httpPort: number; + timezone: string; + locale: string; + bastionDir: string; + domain: string; + dhcpMode: "proxy" | "full"; + dhcpRangeStart: string; + dhcpRangeEnd: string; + // Flags + skipDnsmasq?: boolean | undefined; + skipArtifacts?: boolean | undefined; + // Derived at runtime + iface: string; + serverIp: string; + network: string; + gateway: string; + sshKeys: string[]; + adminUser: string; + fedoraMirror: string; + tftpDir: string; + httpDir: string; + stateFile: string; +} diff --git a/bastion/src/shared/src/types/index.ts b/bastion/src/shared/src/types/index.ts new file mode 100644 index 0000000..a6f49bf --- /dev/null +++ b/bastion/src/shared/src/types/index.ts @@ -0,0 +1,8 @@ +export type { + HardwareInfo, + InstallConfig, + InstalledInfo, + BastionState, +} from "./state.js"; + +export type { BastionConfig } from "./config.js"; diff --git a/bastion/src/shared/src/types/state.ts b/bastion/src/shared/src/types/state.ts new file mode 100644 index 0000000..30e6761 --- /dev/null +++ b/bastion/src/shared/src/types/state.ts @@ -0,0 +1,40 @@ +// State types for discovered machines, install queue, and installed machines. + +export interface HardwareInfo { + mac: string; + product: string; + board: string; + serial: string; + manufacturer: string; + cpu_model: string; + cpu_cores: number; + memory_gb: number; + arch: string; + disks: Array<{ name: string; size_gb: number; model: string }>; + nics: Array<{ name: string; mac: string; state: string }>; + first_seen: string; + last_seen: string; +} + +export interface InstallConfig { + hostname: string; + disk: string; + role: "worker" | "infra"; + queued_at: string; + progress?: string; + progress_at?: string; + progress_detail?: string; +} + +export interface InstalledInfo { + hostname: string; + role: string; + ip: string; + installed_at: string; +} + +export interface BastionState { + discovered: Record; + install_queue: Record; + installed: Record; +} diff --git a/bastion/src/shared/tsconfig.json b/bastion/src/shared/tsconfig.json new file mode 100644 index 0000000..df59da5 --- /dev/null +++ b/bastion/src/shared/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts"] +} diff --git a/bastion/src/shared/vitest.config.ts b/bastion/src/shared/vitest.config.ts new file mode 100644 index 0000000..28c192f --- /dev/null +++ b/bastion/src/shared/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineProject } from 'vitest/config'; + +export default defineProject({ + test: { + name: 'shared', + include: ['tests/**/*.test.ts'], + }, +}); diff --git a/bastion/tsconfig.base.json b/bastion/tsconfig.base.json new file mode 100644 index 0000000..f535eb1 --- /dev/null +++ b/bastion/tsconfig.base.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2022"], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true, + "incremental": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "exactOptionalPropertyTypes": true, + "noUncheckedIndexedAccess": true, + "isolatedModules": true, + "resolveJsonModule": true + } +} diff --git a/bastion/tsconfig.json b/bastion/tsconfig.json index 6e4c9ce..a45b276 100644 --- a/bastion/tsconfig.json +++ b/bastion/tsconfig.json @@ -1,27 +1,8 @@ { - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "lib": ["ES2022"], - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "declaration": true, - "sourceMap": true, - "incremental": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedIndexedAccess": true, - "isolatedModules": true, - "resolveJsonModule": true, - "rootDir": "src", - "outDir": "dist", - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist"] + "files": [], + "references": [ + { "path": "src/shared" }, + { "path": "src/bastion" }, + { "path": "src/cli" } + ] } diff --git a/bastion/vitest.config.ts b/bastion/vitest.config.ts new file mode 100644 index 0000000..c1ce114 --- /dev/null +++ b/bastion/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + exclude: ['**/node_modules/**', '**/dist/**', '**/*.config.*'], + }, + include: ['src/*/tests/**/*.test.ts'], + exclude: ['**/node_modules/**'], + testTimeout: 10000, + }, +});