From e67e732fd8e3a2a4e8a04ec2a93a27ed7f0b5c01 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Wed, 9 Nov 2022 21:16:47 -0500 Subject: [PATCH] fix(striker-ui-api): split /ssh-key and /ssh-key/conflict --- striker-ui-api/src/lib/consts/SERVER_PATHS.ts | 1 + .../ssh-key/deleteSSHKeyConflict.ts | 39 ++++++++ .../lib/request_handlers/ssh-key/getSSHKey.ts | 90 ------------------- .../ssh-key/getSSHKeyConflict.ts | 66 ++++++++++++++ .../src/lib/request_handlers/ssh-key/index.ts | 3 +- striker-ui-api/src/routes/ssh-key.ts | 9 +- 6 files changed, 115 insertions(+), 93 deletions(-) create mode 100644 striker-ui-api/src/lib/request_handlers/ssh-key/deleteSSHKeyConflict.ts delete mode 100644 striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKey.ts create mode 100644 striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKeyConflict.ts diff --git a/striker-ui-api/src/lib/consts/SERVER_PATHS.ts b/striker-ui-api/src/lib/consts/SERVER_PATHS.ts index 9464cf75..ac60fbdb 100644 --- a/striker-ui-api/src/lib/consts/SERVER_PATHS.ts +++ b/striker-ui-api/src/lib/consts/SERVER_PATHS.ts @@ -18,6 +18,7 @@ const EMPTY_SERVER_PATHS: ServerPath = { 'anvil-access-module': {}, 'anvil-configure-host': {}, 'anvil-get-server-screenshot': {}, + 'anvil-manage-keys': {}, 'anvil-manage-power': {}, 'anvil-provision-server': {}, 'anvil-sync-shared': {}, diff --git a/striker-ui-api/src/lib/request_handlers/ssh-key/deleteSSHKeyConflict.ts b/striker-ui-api/src/lib/request_handlers/ssh-key/deleteSSHKeyConflict.ts new file mode 100644 index 00000000..07f84c30 --- /dev/null +++ b/striker-ui-api/src/lib/request_handlers/ssh-key/deleteSSHKeyConflict.ts @@ -0,0 +1,39 @@ +import { RequestHandler } from 'express'; + +import SERVER_PATHS from '../../consts/SERVER_PATHS'; + +import { job } from '../../accessModule'; +import { stderr } from '../../shell'; + +export const deleteSSHKeyConflict: RequestHandler< + unknown, + undefined, + { [hostUUID: string]: string[] } +> = (request, response) => { + const { body } = request; + const hostUUIDs = Object.keys(body); + + hostUUIDs.forEach((hostUUID) => { + const stateUUIDs = body[hostUUID]; + + try { + job({ + file: __filename, + job_command: SERVER_PATHS.usr.sbin['anvil-manage-keys'].self, + job_data: stateUUIDs.join(','), + job_description: 'job_0057', + job_host_uuid: hostUUID, + job_name: 'manage::broken_keys', + job_title: 'job_0056', + }); + } catch (subError) { + stderr(`Failed to delete bad SSH keys; CAUSE: ${subError}`); + + response.status(500).send(); + + return; + } + }); + + response.status(204).send(); +}; diff --git a/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKey.ts b/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKey.ts deleted file mode 100644 index 46094e72..00000000 --- a/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKey.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { getLocalHostUUID } from '../../accessModule'; -import buildGetRequestHandler from '../buildGetRequestHandler'; -import { buildQueryResultReducer } from '../../buildQueryResultModifier'; -import { toLocal } from '../../convertHostUUID'; -import { match } from '../../match'; -import { sanitizeQS } from '../../sanitizeQS'; - -type BuildQuerySubFunction = (result: Parameters[0]) => { - afterQueryReturn?: QueryResultModifierFunction; - query: string; -}; - -const HOST_KEY_CHANGED_PREFIX = 'host_key_changed::'; - -const MAP_TO_HANDLER: Record = { - conflict: () => { - const localHostUUID: string = getLocalHostUUID(); - - return { - afterQueryReturn: buildQueryResultReducer<{ - [hostUUID: string]: { - [stateUUID: string]: { - badFile: string; - badLine: number; - hostName: string; - hostUUID: string; - ipAddress: string; - stateUUID: string; - }; - }; - }>((previous, [hostName, hostUUID, stateName, stateNote, stateUUID]) => { - const hostUUIDKey = toLocal(hostUUID, localHostUUID); - - if (previous[hostUUIDKey] === undefined) { - previous[hostUUIDKey] = {}; - } - - const ipAddress = stateName.slice(HOST_KEY_CHANGED_PREFIX.length); - const [, badFile, badLine = '0'] = match( - stateNote, - /file=([^\s]+),line=(\d+)/, - ); - - previous[hostUUIDKey][stateUUID] = { - badFile, - badLine: parseInt(badLine), - hostName, - hostUUID, - ipAddress, - stateUUID, - }; - - return previous; - }, {}), - query: ` - SELECT - hos.host_name, - hos.host_uuid, - sta.state_name, - sta.state_note, - sta.state_uuid - FROM states AS sta - JOIN hosts AS hos - ON sta.state_host_uuid = hos.host_uuid - WHERE sta.state_name LIKE '${HOST_KEY_CHANGED_PREFIX}%';`, - }; - }, -}; - -export const getSSHKey = buildGetRequestHandler( - (request, buildQueryOptions) => { - const { type: rawType } = request.query; - - const type = sanitizeQS(rawType, { - modifierType: 'sql', - returnType: 'string', - }); - - const { afterQueryReturn, query } = MAP_TO_HANDLER[type]?.call( - null, - request, - ) ?? { query: '' }; - - if (buildQueryOptions) { - buildQueryOptions.afterQueryReturn = afterQueryReturn; - } - - return query; - }, -); diff --git a/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKeyConflict.ts b/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKeyConflict.ts new file mode 100644 index 00000000..912f6fc2 --- /dev/null +++ b/striker-ui-api/src/lib/request_handlers/ssh-key/getSSHKeyConflict.ts @@ -0,0 +1,66 @@ +import { getLocalHostUUID } from '../../accessModule'; +import buildGetRequestHandler from '../buildGetRequestHandler'; +import { buildQueryResultReducer } from '../../buildQueryResultModifier'; +import { toLocal } from '../../convertHostUUID'; +import { match } from '../../match'; + +const HOST_KEY_CHANGED_PREFIX = 'host_key_changed::'; + +export const getSSHKeyConflict = buildGetRequestHandler( + (request, buildQueryOptions) => { + const localHostUUID: string = getLocalHostUUID(); + + const query = ` + SELECT + hos.host_name, + hos.host_uuid, + sta.state_name, + sta.state_note, + sta.state_uuid + FROM states AS sta + JOIN hosts AS hos + ON sta.state_host_uuid = hos.host_uuid + WHERE sta.state_name LIKE '${HOST_KEY_CHANGED_PREFIX}%';`; + const afterQueryReturn = buildQueryResultReducer<{ + [hostUUID: string]: { + [stateUUID: string]: { + badFile: string; + badLine: number; + hostName: string; + hostUUID: string; + ipAddress: string; + stateUUID: string; + }; + }; + }>((previous, [hostName, hostUUID, stateName, stateNote, stateUUID]) => { + const hostUUIDKey = toLocal(hostUUID, localHostUUID); + + if (previous[hostUUIDKey] === undefined) { + previous[hostUUIDKey] = {}; + } + + const ipAddress = stateName.slice(HOST_KEY_CHANGED_PREFIX.length); + const [, badFile, badLine = '0'] = match( + stateNote, + /file=([^\s]+),line=(\d+)/, + ); + + previous[hostUUIDKey][stateUUID] = { + badFile, + badLine: parseInt(badLine), + hostName, + hostUUID, + ipAddress, + stateUUID, + }; + + return previous; + }, {}); + + if (buildQueryOptions) { + buildQueryOptions.afterQueryReturn = afterQueryReturn; + } + + return query; + }, +); diff --git a/striker-ui-api/src/lib/request_handlers/ssh-key/index.ts b/striker-ui-api/src/lib/request_handlers/ssh-key/index.ts index feebf33a..38eb96b7 100644 --- a/striker-ui-api/src/lib/request_handlers/ssh-key/index.ts +++ b/striker-ui-api/src/lib/request_handlers/ssh-key/index.ts @@ -1 +1,2 @@ -export * from './getSSHKey'; +export * from './deleteSSHKeyConflict'; +export * from './getSSHKeyConflict'; diff --git a/striker-ui-api/src/routes/ssh-key.ts b/striker-ui-api/src/routes/ssh-key.ts index 4fc8b8da..34c86f68 100644 --- a/striker-ui-api/src/routes/ssh-key.ts +++ b/striker-ui-api/src/routes/ssh-key.ts @@ -1,9 +1,14 @@ import express from 'express'; -import { getSSHKey } from '../lib/request_handlers/ssh-key'; +import { + deleteSSHKeyConflict, + getSSHKeyConflict, +} from '../lib/request_handlers/ssh-key'; const router = express.Router(); -router.get('/', getSSHKey); +router + .get('/conflict', getSSHKeyConflict) + .delete('/conflict', deleteSSHKeyConflict); export default router;