Archived
125 lines
3.1 KiB
TypeScript
125 lines
3.1 KiB
TypeScript
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<CommandResult> {
|
|
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<Omit<CommandResult, 'code'>> {
|
|
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<CommandResult> {
|
|
return this.run(['status', '--json'], {
|
|
timeout: options.timeout ?? 12000
|
|
});
|
|
}
|
|
|
|
async ensureService(): Promise<boolean> {
|
|
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<void>(resolve => setTimeout(resolve, 500));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
connect(): Promise<CommandResult> {
|
|
return this.run([
|
|
'up',
|
|
'--management-url',
|
|
MANAGEMENT_URL,
|
|
'--admin-url',
|
|
MANAGEMENT_URL
|
|
], { timeout: 180000 });
|
|
}
|
|
|
|
disconnect(): Promise<CommandResult> {
|
|
return this.run([
|
|
'down',
|
|
'--management-url', MANAGEMENT_URL
|
|
], { timeout: 45000 });
|
|
}
|
|
|
|
async logout(): Promise<CommandResult> {
|
|
await this.run(
|
|
['down', '--management-url', MANAGEMENT_URL],
|
|
{ timeout: 30000 }
|
|
);
|
|
|
|
return this.run([
|
|
'deregister',
|
|
'--management-url',
|
|
MANAGEMENT_URL,
|
|
'--admin-url',
|
|
MANAGEMENT_URL
|
|
], { timeout: 60000 });
|
|
}
|
|
} |