import { execFile } from 'child_process'; import { MANAGEMENT_URL } from './config'; export interface CommandResult { ok: boolean; code?: number; stdout: string; stderr: string; error: Error | null; } export class NetBirdClient { private executablePath: string; constructor(executablePath: string) { this.executablePath = executablePath; } run(args: string[], options: { timeout?: number } = {}): Promise { return new Promise(resolve => { execFile(this.executablePath, args, { windowsHide: true, timeout: options.timeout ?? 30000, }, (error, stdout, stderr) => { resolve({ ok: !error, code: error && typeof (error as NodeJS.ErrnoException).code === 'number' ? (error as NodeJS.ErrnoException).code : 0, stdout: stdout || '', stderr: stderr || '', error }) }); }); } /// Deprecated??? runElevated(args: string[]): Promise> { const quotedExe = this.executablePath.replace(/'/g, "''"); const quotedArgs = args.map(arg => `'${String(arg).replace(/'/g, "''")}'`).join(','); const script = `Start-Process -FilePath '${quotedExe}' -ArgumentList @(${quotedArgs}) -Verb RunAs -Wait`; return new Promise(resolve => { execFile( 'powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script], { windowsHide: true, timeout: 180000, }, (error, stdout, stderr) => { resolve({ ok: !error, stdout: stdout || '', stderr: stderr || '', error }); } ) }); } status(options: { timeout?: number } = {}): Promise { return this.run(['status', '--json'], { timeout: options.timeout ?? 12000 }); } async ensureService(): Promise { const status = await this.status({ timeout: 10000 }); if (status.ok) return true; await this.run([ 'service', 'install', '--management-url', MANAGEMENT_URL, '--admin-url', MANAGEMENT_URL, '--log-level', 'info' ]); await this.run(['service', 'start']); for (let index = 0; index < 20; index++) { const check = await this.status({ timeout: 8000 }); if (check.ok) return true; await new Promise(resolve => setTimeout(resolve, 500)); } return false; } connect(): Promise { return this.run([ 'up', '--management-url', MANAGEMENT_URL, '--admin-url', MANAGEMENT_URL ], { timeout: 180000 }); } disconnect(): Promise { return this.run([ 'down', '--management-url', MANAGEMENT_URL ], { timeout: 45000 }); } async logout(): Promise { await this.run( ['down', '--management-url', MANAGEMENT_URL], { timeout: 30000 } ); return this.run([ 'deregister', '--management-url', MANAGEMENT_URL, '--admin-url', MANAGEMENT_URL ], { timeout: 60000 }); } }