fix(striker-ui-api): disconnect vnc-related management, only fetch vnc info

main
Tsu-ba-me 1 year ago committed by Yanhao Lei
parent f08319f41b
commit 7058ef0f4a
  1. 43
      striker-ui-api/src/lib/accessModule.ts
  2. 1
      striker-ui-api/src/lib/consts/SERVER_PATHS.ts
  3. 1
      striker-ui-api/src/lib/request_handlers/command/index.ts
  4. 52
      striker-ui-api/src/lib/request_handlers/command/manageVncSshTunnel.ts
  5. 26
      striker-ui-api/src/lib/request_handlers/server/getServerDetail.ts
  6. 2
      striker-ui-api/src/routes/command.ts
  7. 13
      striker-ui-api/src/types/ApiServer.d.ts

@ -384,41 +384,22 @@ const getUpsSpec = async () => {
return getData<AnvilDataUPSHash>('ups_data'); return getData<AnvilDataUPSHash>('ups_data');
}; };
const vncpipe = async (serverUuid: string, open?: boolean) => { const getVncinfo = async (serverUuid: string): Promise<ServerDetailVncInfo> => {
const [output, rReturnCode]: [string, string] = await subroutine('call', { const rows: [[string]] = await query(
params: [ `SELECT variable_value FROM variables WHERE variable_name = 'server::${serverUuid}::vncinfo';`,
{ );
shell_call: `${
SERVER_PATHS.usr.sbin['anvil-manage-vnc-pipe'].self
} --server-uuid ${serverUuid} --component st${open ? ' --open' : ''}`,
},
],
pre: ['System'],
root: true,
});
const rcode = Number.parseInt(rReturnCode);
if (rcode !== 0) { if (rows.length) {
throw new Error(`VNC pipe call failed with code ${rcode}`); throw new Error('No record found');
} }
const lines = output.split('\n'); const [[vncinfo]] = rows;
const lastLine = lines[lines.length - 1]; const [domain, port] = vncinfo.split(':');
const rVncPipeProps = lastLine
.split(',')
.reduce<Record<string, string>>((previous, pair) => {
const [key, value] = pair.trim().split(/\s*:\s*/, 2);
previous[key] = value;
return previous;
}, {});
const forwardPort = Number.parseInt(rVncPipeProps.forward_port); const forwardPort = Number.parseInt(port);
const protocol = rVncPipeProps.protocol; const protocol = 'ws';
return { forwardPort, protocol }; return { domain, forwardPort, protocol };
}; };
export { export {
@ -438,8 +419,8 @@ export {
getNetworkData, getNetworkData,
getPeerData, getPeerData,
getUpsSpec, getUpsSpec,
getVncinfo,
query, query,
subroutine as sub, subroutine as sub,
vncpipe,
write, write,
}; };

@ -31,7 +31,6 @@ const EMPTY_SERVER_PATHS: ServerPath = {
'anvil-join-anvil': {}, 'anvil-join-anvil': {},
'anvil-manage-keys': {}, 'anvil-manage-keys': {},
'anvil-manage-power': {}, 'anvil-manage-power': {},
'anvil-manage-vnc-pipe': {},
'anvil-provision-server': {}, 'anvil-provision-server': {},
'anvil-safe-start': {}, 'anvil-safe-start': {},
'anvil-safe-stop': {}, 'anvil-safe-stop': {},

@ -1,7 +1,6 @@
export * from './getHostSSH'; export * from './getHostSSH';
export * from './joinAn'; export * from './joinAn';
export * from './leaveAn'; export * from './leaveAn';
export * from './manageVncSshTunnel';
export * from './poweroffStriker'; export * from './poweroffStriker';
export * from './rebootStriker'; export * from './rebootStriker';
export * from './runManifest'; export * from './runManifest';

@ -1,52 +0,0 @@
import assert from 'assert';
import { RequestHandler } from 'express';
import { REP_UUID } from '../../consts';
import { vncpipe } from '../../accessModule';
import { sanitize } from '../../sanitize';
import { stderr, stdoutVar } from '../../shell';
export const manageVncSshTunnel: RequestHandler<
unknown,
{ forwardPort: number; protocol: string },
{ open: boolean; serverUuid: string }
> = async (request, response) => {
const { body: { open: rOpen, serverUuid: rServerUuid } = {} } = request;
const isOpen = sanitize(rOpen, 'boolean');
const serverUuid = sanitize(rServerUuid, 'string');
try {
assert(
REP_UUID.test(serverUuid),
`Server UUID must be a valid UUIDv4; got: [${serverUuid}]`,
);
} catch (error) {
stderr(`Assert input failed when manage VNC SSH tunnel; CAUSE: ${error}`);
return response.status(400).send();
}
stdoutVar({ isOpen, serverUuid }, 'Manage VNC SSH tunnel params: ');
let operation = 'close';
if (isOpen) {
operation = 'open';
}
let rsbody: { forwardPort: number; protocol: string };
try {
rsbody = await vncpipe(serverUuid, isOpen);
} catch (error) {
stderr(
`Failed to ${operation} VNC SSH tunnel to server ${serverUuid}; CAUSE: ${error}`,
);
return response.status(500).send();
}
return response.json(rsbody);
};

@ -1,11 +1,12 @@
import assert from 'assert'; import assert from 'assert';
import { execSync } from 'child_process';
import { RequestHandler } from 'express'; import { RequestHandler } from 'express';
import { REP_UUID, SERVER_PATHS } from '../../consts'; import { REP_UUID, SERVER_PATHS } from '../../consts';
import { getVncinfo } from '../../accessModule';
import { sanitize } from '../../sanitize'; import { sanitize } from '../../sanitize';
import { stderr, stdout } from '../../shell'; import { stderr, stdout } from '../../shell';
import { execSync } from 'child_process';
export const getServerDetail: RequestHandler< export const getServerDetail: RequestHandler<
ServerDetailParamsDictionary, ServerDetailParamsDictionary,
@ -15,12 +16,13 @@ export const getServerDetail: RequestHandler<
> = async (request, response) => { > = async (request, response) => {
const { const {
params: { serverUUID: serverUuid }, params: { serverUUID: serverUuid },
query: { ss }, query: { ss: rSs, vnc: rVnc },
} = request; } = request;
const isScreenshot = sanitize(ss, 'boolean'); const ss = sanitize(rSs, 'boolean');
const vnc = sanitize(rVnc, 'boolean');
stdout(`serverUUID=[${serverUuid}],isScreenshot=[${isScreenshot}]`); stdout(`serverUUID=[${serverUuid}],isScreenshot=[${ss}]`);
try { try {
assert( assert(
@ -35,8 +37,8 @@ export const getServerDetail: RequestHandler<
return response.status(500).send(); return response.status(500).send();
} }
if (isScreenshot) { if (ss) {
const rsbody = { screenshot: '' }; const rsbody: ServerDetailScreenshot = { screenshot: '' };
try { try {
rsbody.screenshot = execSync( rsbody.screenshot = execSync(
@ -49,6 +51,18 @@ export const getServerDetail: RequestHandler<
return response.status(500).send(); return response.status(500).send();
} }
return response.send(rsbody);
} else if (vnc) {
let rsbody: ServerDetailVncInfo;
try {
rsbody = await getVncinfo(serverUuid);
} catch (error) {
stderr(`Failed to get server ${serverUuid} VNC info; CAUSE: ${error}`);
return response.status(500).send();
}
return response.send(rsbody); return response.send(rsbody);
} else { } else {
// For getting sever detail data. // For getting sever detail data.

@ -4,7 +4,6 @@ import {
getHostSSH, getHostSSH,
joinAn, joinAn,
leaveAn, leaveAn,
manageVncSshTunnel,
poweroffStriker, poweroffStriker,
rebootStriker, rebootStriker,
runManifest, runManifest,
@ -24,7 +23,6 @@ router
.put('/inquire-host', getHostSSH) .put('/inquire-host', getHostSSH)
.put('/join-an/:uuid', joinAn) .put('/join-an/:uuid', joinAn)
.put('/leave-an/:uuid', leaveAn) .put('/leave-an/:uuid', leaveAn)
.put('/vnc-pipe', manageVncSshTunnel)
.put('/poweroff-host', poweroffStriker) .put('/poweroff-host', poweroffStriker)
.put('/reboot-host', rebootStriker) .put('/reboot-host', rebootStriker)
.put('/run-manifest/:manifestUuid', runManifest) .put('/run-manifest/:manifestUuid', runManifest)

@ -12,6 +12,17 @@ type ServerDetailParamsDictionary = {
}; };
type ServerDetailParsedQs = { type ServerDetailParsedQs = {
ss: boolean | number | string;
resize: string; resize: string;
ss: boolean | number | string;
vnc: boolean | number | string;
};
type ServerDetailScreenshot = {
screenshot: string;
};
type ServerDetailVncInfo = {
domain: string;
forwardPort: number;
protocol: string;
}; };

Loading…
Cancel
Save