From e4f8b4dbcff17949c59d6b3c84986092bbd1a411 Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Mon, 19 Aug 2024 20:10:58 +0100 Subject: [PATCH] moved taskGenerateGossipKeys from node.mjs to key_manager.mjs Signed-off-by: Jeromy Cannon --- src/commands/node.mjs | 106 ++------------------------------------- src/core/key_manager.mjs | 105 +++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 103 deletions(-) diff --git a/src/commands/node.mjs b/src/commands/node.mjs index 6cd8c9ffc..1bf91c0eb 100644 --- a/src/commands/node.mjs +++ b/src/commands/node.mjs @@ -24,7 +24,6 @@ import * as helpers from '../core/helpers.mjs' import { getNodeAccountMap, getNodeLogs, - getTmpDir, sleep, validatePath } from '../core/helpers.mjs' @@ -317,104 +316,7 @@ export class NodeCommand extends BaseCommand { } /** - * Return a list of subtasks to generate gossip keys - * - * WARNING: These tasks MUST run in sequence. - * - * @param keyFormat key format (pem | pfx) - * @param nodeIds node ids - * @param keysDir keys directory - * @param curDate current date - * @param allNodeIds includes the nodeIds to get new keys as well as existing nodeIds that will be included in the public.pfx file - * @return a list of subtasks - * @private - */ - // TODO: move to KeyManager - taskGenerateGossipKeys (keyFormat, nodeIds, keysDir, curDate = new Date(), allNodeIds = null) { - allNodeIds = allNodeIds || nodeIds - if (!Array.isArray(nodeIds) || !nodeIds.every((nodeId) => typeof nodeId === 'string')) { - throw new IllegalArgumentError('nodeIds must be an array of strings') - } - const self = this - const subTasks = [] - - switch (keyFormat) { - case constants.KEY_FORMAT_PFX: { - const tmpDir = getTmpDir() - const keytool = self.keytoolDepManager.getKeytool() - - subTasks.push({ - title: `Check keytool exists (Version: ${self.keytoolDepManager.getKeytoolVersion()})`, - task: async () => self.keytoolDepManager.checkVersion(true) - - }) - - subTasks.push({ - title: 'Backup old files', - task: () => helpers.backupOldPfxKeys(nodeIds, keysDir, curDate) - }) - - for (const nodeId of nodeIds) { - subTasks.push({ - title: `Generate ${Templates.renderGossipPfxPrivateKeyFile(nodeId)} for node: ${chalk.yellow(nodeId)}`, - task: async () => { - await self.keyManager.generatePrivatePfxKeys(keytool, nodeId, keysDir, tmpDir) - } - }) - } - - subTasks.push({ - title: `Generate ${constants.PUBLIC_PFX} file`, - task: async () => { - await self.keyManager.updatePublicPfxKey(keytool, allNodeIds, keysDir, tmpDir) - } - }) - - subTasks.push({ - title: 'Clean up temp files', - task: async () => { - if (fs.existsSync(tmpDir)) { - fs.rmSync(tmpDir, { recursive: true }) - } - } - }) - break - } - - case constants.KEY_FORMAT_PEM: { - subTasks.push({ - title: 'Backup old files', - task: () => helpers.backupOldPemKeys(nodeIds, keysDir, curDate) - } - ) - - for (const nodeId of nodeIds) { - subTasks.push({ - title: `Gossip ${keyFormat} key for node: ${chalk.yellow(nodeId)}`, - task: async () => { - const signingKey = await this.keyManager.generateSigningKey(nodeId) - const signingKeyFiles = await this.keyManager.storeSigningKey(nodeId, signingKey, keysDir) - this.logger.debug(`generated Gossip signing keys for node ${nodeId}`, { keyFiles: signingKeyFiles }) - - const agreementKey = await this.keyManager.generateAgreementKey(nodeId, signingKey) - const agreementKeyFiles = await this.keyManager.storeAgreementKey(nodeId, agreementKey, keysDir) - this.logger.debug(`generated Gossip agreement keys for node ${nodeId}`, { keyFiles: agreementKeyFiles }) - } - }) - } - - break - } - - default: - throw new FullstackTestingError(`unsupported key-format: ${keyFormat}`) - } - - return subTasks - } - - /** - * Return a list of subtasks to generate gRPC TLS keys + * Return a list of subtasks to generate gRPC TLS keys * * WARNING: These tasks should run in sequence * @@ -744,7 +646,7 @@ export class NodeCommand extends BaseCommand { task: async (ctx, parentTask) => { const config = /** @type {NodeSetupConfigClass} **/ ctx.config - const subTasks = self.taskGenerateGossipKeys(config.keyFormat, config.nodeIds, config.keysDir, config.curDate) + const subTasks = self.keyManager.taskGenerateGossipKeys(self.keytoolDepManager, config.keyFormat, config.nodeIds, config.keysDir, config.curDate) // set up the sub-tasks return parentTask.newListr(subTasks, { concurrent: false, @@ -1120,7 +1022,7 @@ export class NodeCommand extends BaseCommand { title: 'Generate gossip keys', task: async (ctx, parentTask) => { const config = ctx.config - const subTasks = self.taskGenerateGossipKeys(config.keyFormat, config.nodeIds, config.keysDir, config.curDate) + const subTasks = self.keyManager.taskGenerateGossipKeys(self.keytoolDepManager, config.keyFormat, config.nodeIds, config.keysDir, config.curDate) // set up the sub-tasks return parentTask.newListr(subTasks, { concurrent: false, @@ -1584,7 +1486,7 @@ export class NodeCommand extends BaseCommand { title: 'Generate Gossip key', task: async (ctx, parentTask) => { const config = /** @type {NodeAddConfigClass} **/ ctx.config - const subTasks = self.taskGenerateGossipKeys(config.keyFormat, [config.nodeId], config.keysDir, config.curDate, config.allNodeIds) + const subTasks = self.keyManager.taskGenerateGossipKeys(self.keytoolDepManager, config.keyFormat, [config.nodeId], config.keysDir, config.curDate, config.allNodeIds) // set up the sub-tasks return parentTask.newListr(subTasks, { concurrent: false, diff --git a/src/core/key_manager.mjs b/src/core/key_manager.mjs index bffba2578..9e0ae5491 100644 --- a/src/core/key_manager.mjs +++ b/src/core/key_manager.mjs @@ -18,11 +18,17 @@ import * as x509 from '@peculiar/x509' import crypto from 'crypto' import fs from 'fs' import path from 'path' -import { FullstackTestingError, MissingArgumentError } from './errors.mjs' +import { + FullstackTestingError, + IllegalArgumentError, + MissingArgumentError +} from './errors.mjs' import { getTmpDir } from './helpers.mjs' import { constants, Keytool } from './index.mjs' import { Logger } from './logging.mjs' import { Templates } from './templates.mjs' +import * as helpers from './helpers.mjs' +import chalk from 'chalk' x509.cryptoProvider.set(crypto) @@ -704,4 +710,101 @@ export class KeyManager { } } } + + /** + * Return a list of subtasks to generate gossip keys + * + * WARNING: These tasks MUST run in sequence. + * + * @param keytoolDepManager an instance of core/KeytoolDepManager + * @param keyFormat key format (pem | pfx) + * @param nodeIds node ids + * @param keysDir keys directory + * @param curDate current date + * @param allNodeIds includes the nodeIds to get new keys as well as existing nodeIds that will be included in the public.pfx file + * @return a list of subtasks + * @private + */ + taskGenerateGossipKeys (keytoolDepManager, keyFormat, nodeIds, keysDir, curDate = new Date(), allNodeIds = null) { + allNodeIds = allNodeIds || nodeIds + if (!Array.isArray(nodeIds) || !nodeIds.every((nodeId) => typeof nodeId === 'string')) { + throw new IllegalArgumentError('nodeIds must be an array of strings') + } + const self = this + const subTasks = [] + + switch (keyFormat) { + case constants.KEY_FORMAT_PFX: { + const tmpDir = getTmpDir() + const keytool = keytoolDepManager.getKeytool() + + subTasks.push({ + title: `Check keytool exists (Version: ${keytoolDepManager.getKeytoolVersion()})`, + task: async () => keytoolDepManager.checkVersion(true) + + }) + + subTasks.push({ + title: 'Backup old files', + task: () => helpers.backupOldPfxKeys(nodeIds, keysDir, curDate) + }) + + for (const nodeId of nodeIds) { + subTasks.push({ + title: `Generate ${Templates.renderGossipPfxPrivateKeyFile(nodeId)} for node: ${chalk.yellow(nodeId)}`, + task: async () => { + await self.generatePrivatePfxKeys(keytool, nodeId, keysDir, tmpDir) + } + }) + } + + subTasks.push({ + title: `Generate ${constants.PUBLIC_PFX} file`, + task: async () => { + await self.updatePublicPfxKey(keytool, allNodeIds, keysDir, tmpDir) + } + }) + + subTasks.push({ + title: 'Clean up temp files', + task: async () => { + if (fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true }) + } + } + }) + break + } + + case constants.KEY_FORMAT_PEM: { + subTasks.push({ + title: 'Backup old files', + task: () => helpers.backupOldPemKeys(nodeIds, keysDir, curDate) + } + ) + + for (const nodeId of nodeIds) { + subTasks.push({ + title: `Gossip ${keyFormat} key for node: ${chalk.yellow(nodeId)}`, + task: async () => { + const signingKey = await self.generateSigningKey(nodeId) + const signingKeyFiles = await self.storeSigningKey(nodeId, signingKey, keysDir) + this.logger.debug(`generated Gossip signing keys for node ${nodeId}`, { keyFiles: signingKeyFiles }) + + const agreementKey = await self.generateAgreementKey(nodeId, signingKey) + const agreementKeyFiles = await self.storeAgreementKey(nodeId, agreementKey, keysDir) + this.logger.debug(`generated Gossip agreement keys for node ${nodeId}`, { keyFiles: agreementKeyFiles }) + } + }) + } + + break + } + + default: + throw new FullstackTestingError(`unsupported key-format: ${keyFormat}`) + } + + return subTasks + } }