feat(striker-ui-api): add /host, /host/connection

main
Tsu-ba-me 2 years ago
parent 5a9f936913
commit b576e799e2
  1. 14
      striker-ui-api/src/lib/buildIDCondition.ts
  2. 45
      striker-ui-api/src/lib/request_handlers/host/getHost.ts
  3. 135
      striker-ui-api/src/lib/request_handlers/host/getHostConnection.ts
  4. 2
      striker-ui-api/src/lib/request_handlers/host/index.ts
  5. 9
      striker-ui-api/src/routes/host.ts
  6. 2
      striker-ui-api/src/routes/index.ts
  7. 4
      striker-ui-api/src/types/HostOverview.d.ts

@ -0,0 +1,14 @@
import join from './join';
import { sanitizeQS } from './sanitizeQS';
export const buildIDCondition = (
ids: unknown,
field: string,
{ onFallback = () => '' }: { onFallback?: () => string },
): string =>
join(sanitizeQS(ids, { returnType: 'string[]' }), {
beforeReturn: (toReturn) =>
toReturn ? `${field} IN (${toReturn})` : onFallback.call(null),
elementWrapper: "'",
separator: ', ',
}) as string;

@ -0,0 +1,45 @@
import { getLocalHostUUID } from '../../accessModule';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildIDCondition } from '../../buildIDCondition';
export const getHost = buildGetRequestHandler((request, buildQueryOptions) => {
const { hostUUIDs } = request.query;
const hostUUIDField = 'hos.host_uuid';
const condHostUUIDs = buildIDCondition(hostUUIDs, hostUUIDField, {
onFallback: () => {
try {
return `${hostUUIDField} = '${getLocalHostUUID()}'`;
} catch (subError) {
throw new Error(`Failed to get local host UUID; CAUSE: ${subError}`);
}
},
});
process.stdout.write(`condHostUUIDs=[${condHostUUIDs}]`);
if (buildQueryOptions) {
buildQueryOptions.afterQueryReturn = (queryStdout) => {
let result = queryStdout;
if (queryStdout instanceof Array) {
result = queryStdout.reduce<Record<string, HostOverview>>(
(previous, [hostName, hostUUID]) => {
previous[hostUUID] = { hostName, hostUUID };
return previous;
},
{},
);
}
return result;
};
}
return `SELECT
hos.host_name,
hos.host_uuid
FROM hosts AS hos
WHERE ${condHostUUIDs};`;
});

@ -0,0 +1,135 @@
import { getAnvilData, getLocalHostUUID } from '../../accessModule';
import { buildIDCondition } from '../../buildIDCondition';
import buildGetRequestHandler from '../buildGetRequestHandler';
export const getHostConnection = buildGetRequestHandler(
(request, buildQueryOptions) => {
const { hostUUIDs } = request.query;
let localHostUUID: string;
let rawDatabases: {
[hostUUID: string]: {
host: string;
name: string;
password: string;
ping: string;
port: string;
user: string;
};
};
try {
localHostUUID = getLocalHostUUID();
} catch (subError) {
throw new Error(`Failed to get local host UUID; CAUSE: ${subError}`);
}
const hostUUIDField = 'ip_add.ip_address_host_uuid';
const condHostUUIDs = buildIDCondition(hostUUIDs, hostUUIDField, {
onFallback: () => `${hostUUIDField} = '${localHostUUID}'`,
});
process.stdout.write(`condHostUUIDs=[${condHostUUIDs}]\n`);
try {
({ database: rawDatabases } = getAnvilData({ database: true }));
} catch (subError) {
throw new Error(`Failed to get anvil data; CAUSE: ${subError}`);
}
const connections = Object.entries(rawDatabases).reduce<{
inbound: {
ipAddresses: {
[ipAddress: string]: {
hostUUID: string;
ipAddress: string;
ipAddressUUID: string;
networkLinkNumber: number;
networkNumber: number;
networkType: string;
};
};
port: number;
user: string;
};
peer: {
[ipAddress: string]: {
hostUUID: string;
ipAddress: string;
isPing: boolean;
port: number;
user: string;
};
};
}>(
(
previous,
[hostUUID, { host: ipAddress, ping, port: rawPort, user }],
) => {
const port = parseInt(rawPort);
if (hostUUID === localHostUUID) {
previous.inbound.port = port;
previous.inbound.user = user;
} else {
previous.peer[ipAddress] = {
hostUUID,
ipAddress,
isPing: ping === '1',
port,
user,
};
}
return previous;
},
{ inbound: { ipAddresses: {}, port: 5432, user: 'admin' }, peer: {} },
);
process.stdout.write(`Connections=[\n${JSON.stringify(connections)}\n]\n`);
if (buildQueryOptions) {
buildQueryOptions.afterQueryReturn = (queryStdout) => {
let result = queryStdout;
if (queryStdout instanceof Array) {
queryStdout.forEach(([ipAddressUUID, ipAddress, network]) => {
const [, networkType, networkNumber, networkLinkNumber] =
network.match(/^([^\s]+)(\d+)_[^\s]+(\d+)$/);
connections.inbound.ipAddresses[ipAddress] = {
hostUUID: localHostUUID,
ipAddress,
ipAddressUUID,
networkLinkNumber,
networkNumber,
networkType,
};
});
result = connections;
}
return result;
};
}
return `SELECT
ip_add.ip_address_uuid,
ip_add.ip_address_address,
CASE
WHEN ip_add.ip_address_on_type = 'interface'
THEN net_int.network_interface_name
ELSE bon.bond_active_interface
END AS network_name
FROM ip_addresses AS ip_add
LEFT JOIN network_interfaces AS net_int
ON ip_add.ip_address_on_uuid = net_int.network_interface_uuid
LEFT JOIN bridges AS bri
ON ip_add.ip_address_on_uuid = bri.bridge_uuid
LEFT JOIN bonds AS bon
ON bri.bridge_uuid = bon.bond_bridge_uuid
OR ip_add.ip_address_on_uuid = bon.bond_uuid
WHERE ${condHostUUIDs};`;
},
);

@ -0,0 +1,2 @@
export * from './getHost';
export * from './getHostConnection';

@ -0,0 +1,9 @@
import express from 'express';
import { getHost, getHostConnection } from '../lib/request_handlers/host';
const router = express.Router();
router.get('/', getHost).get('/connection', getHostConnection);
export default router;

@ -4,6 +4,7 @@ import anvilRouter from './anvil';
import commandRouter from './command';
import echoRouter from './echo';
import fileRouter from './file';
import hostRouter from './host';
import networkInterfaceRouter from './network-interface';
import serverRouter from './server';
@ -12,6 +13,7 @@ const routes: Readonly<Record<string, Router>> = {
command: commandRouter,
echo: echoRouter,
file: fileRouter,
host: hostRouter,
'network-interface': networkInterfaceRouter,
server: serverRouter,
};

@ -0,0 +1,4 @@
type HostOverview = {
hostName: string;
hostUUID: string;
};
Loading…
Cancel
Save