From f2b603f68e7bccb5094f9474833b3e82e5651903 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Wed, 29 Jan 2025 15:46:52 -0500 Subject: [PATCH] Add server commands to CLI plug-in Signed-off-by: Timothy Johnson --- packages/cli/src/Constants.ts | 6 +++- packages/cli/src/server/Server.definition.ts | 35 +++++++++++++++++++ .../src/server/install/Install.definition.ts | 32 +++++++++++++++++ .../cli/src/server/install/Install.handler.ts | 30 ++++++++++++++++ .../server/uninstall/Uninstall.definition.ts | 32 +++++++++++++++++ .../src/server/uninstall/Uninstall.handler.ts | 25 +++++++++++++ packages/sdk/src/ZSshClient.ts | 2 ++ packages/sdk/src/ZSshUtils.ts | 8 +++-- 8 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 packages/cli/src/server/Server.definition.ts create mode 100644 packages/cli/src/server/install/Install.definition.ts create mode 100644 packages/cli/src/server/install/Install.handler.ts create mode 100644 packages/cli/src/server/uninstall/Uninstall.definition.ts create mode 100644 packages/cli/src/server/uninstall/Uninstall.handler.ts diff --git a/packages/cli/src/Constants.ts b/packages/cli/src/Constants.ts index e7f2bf3..b33ce4c 100644 --- a/packages/cli/src/Constants.ts +++ b/packages/cli/src/Constants.ts @@ -9,15 +9,19 @@ * */ +import * as path from "node:path"; import type { ICommandOptionDefinition } from "@zowe/imperative"; +import { ZSshClient } from "zowe-native-proto-sdk"; // biome-ignore lint/complexity/noStaticOnlyClass: export class Constants { public static readonly OPT_SERVER_PATH: ICommandOptionDefinition = { name: "server-path", aliases: ["sp"], - description: "The remote path of the Zowe SSH server. Defaults to '~/.zowe-server'.", + description: `The remote path of the Zowe SSH server. Defaults to '${ZSshClient.DEFAULT_SERVER_PATH}'.`, type: "string", required: false, }; + + public static readonly ZSSH_BIN_DIR = path.join(__dirname, "..", "bin"); } diff --git a/packages/cli/src/server/Server.definition.ts b/packages/cli/src/server/Server.definition.ts new file mode 100644 index 0000000..43931af --- /dev/null +++ b/packages/cli/src/server/Server.definition.ts @@ -0,0 +1,35 @@ +/** + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + * + */ + +import type { ICommandDefinition } from "@zowe/imperative"; +import { SshSession } from "@zowe/zos-uss-for-zowe-sdk"; +import { Constants } from "../Constants"; +import { ServerInstallDefinition } from "./install/Install.definition"; +import { ServerUninstallDefinition } from "./uninstall/Uninstall.definition"; + +const ServerDefinition: ICommandDefinition = { + name: "server", + aliases: ["srv"], + summary: "Manage the Zowe SSH server", + description: "Manage the Zowe SSH server", + type: "group", + children: [ServerInstallDefinition, ServerUninstallDefinition], + passOn: [ + { + property: "options", + value: [...SshSession.SSH_CONNECTION_OPTIONS, Constants.OPT_SERVER_PATH], + merge: true, + ignoreNodes: [{ type: "group" }], + }, + ], +}; + +export = ServerDefinition; diff --git a/packages/cli/src/server/install/Install.definition.ts b/packages/cli/src/server/install/Install.definition.ts new file mode 100644 index 0000000..8208e53 --- /dev/null +++ b/packages/cli/src/server/install/Install.definition.ts @@ -0,0 +1,32 @@ +/** + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + * + */ + +import type { ICommandDefinition } from "@zowe/imperative"; + +export const ServerInstallDefinition: ICommandDefinition = { + handler: __dirname + "/Install.handler", + type: "command", + name: "install", + aliases: ["up"], + summary: "Install Zowe SSH server on z/OS host", + description: "Install Zowe SSH server on z/OS host", + examples: [ + { + description: "Install Zowe SSH server in the default location", + options: "", + }, + { + description: 'Install Zowe SSH server in the directory "/tmp/zowe-server"', + options: '--server-path "/tmp/zowe-server"', + }, + ], + profile: { optional: ["ssh"] }, +}; diff --git a/packages/cli/src/server/install/Install.handler.ts b/packages/cli/src/server/install/Install.handler.ts new file mode 100644 index 0000000..39d373a --- /dev/null +++ b/packages/cli/src/server/install/Install.handler.ts @@ -0,0 +1,30 @@ +/** + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + * + */ + +import { ConfigUtils, ICommandHandler, IHandlerParameters } from "@zowe/imperative"; +import { ZSshClient, ZSshUtils } from "zowe-native-proto-sdk"; +import { Constants } from "../../Constants"; + +export default class ServerInstallHandler implements ICommandHandler { + public async process(params: IHandlerParameters): Promise { + const session = ZSshUtils.buildSession(params.arguments); + const serverPath = params.arguments.serverPath ?? ZSshClient.DEFAULT_SERVER_PATH; + params.response.progress.startSpinner("Deploying Zowe SSH server..."); + try { + await ZSshUtils.installServer(session, serverPath, Constants.ZSSH_BIN_DIR); + } finally { + params.response.progress.endSpinner(); + } + params.response.console.log( + `Installed Zowe SSH server on ${ConfigUtils.getActiveProfileName("ssh", params.arguments)}`, + ); + } +} diff --git a/packages/cli/src/server/uninstall/Uninstall.definition.ts b/packages/cli/src/server/uninstall/Uninstall.definition.ts new file mode 100644 index 0000000..41d255c --- /dev/null +++ b/packages/cli/src/server/uninstall/Uninstall.definition.ts @@ -0,0 +1,32 @@ +/** + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + * + */ + +import type { ICommandDefinition } from "@zowe/imperative"; + +export const ServerUninstallDefinition: ICommandDefinition = { + handler: __dirname + "/Uninstall.handler", + type: "command", + name: "uninstall", + aliases: ["rm"], + summary: "Uninstall Zowe SSH server on z/OS host", + description: "Uninstall Zowe SSH server on z/OS host", + examples: [ + { + description: "Uninstall Zowe SSH server from the default location", + options: "", + }, + { + description: 'Uninstall Zowe SSH server from the directory "/tmp/zowe-server"', + options: '--server-path "/tmp/zowe-server"', + }, + ], + profile: { optional: ["ssh"] }, +}; diff --git a/packages/cli/src/server/uninstall/Uninstall.handler.ts b/packages/cli/src/server/uninstall/Uninstall.handler.ts new file mode 100644 index 0000000..d2645ce --- /dev/null +++ b/packages/cli/src/server/uninstall/Uninstall.handler.ts @@ -0,0 +1,25 @@ +/** + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + * + */ + +import { ConfigUtils, ICommandHandler, IHandlerParameters } from "@zowe/imperative"; +import { ZSshClient, ZSshUtils } from "zowe-native-proto-sdk"; +import { Constants } from "../../Constants"; + +export default class ServerUninstallHandler implements ICommandHandler { + public async process(params: IHandlerParameters): Promise { + const session = ZSshUtils.buildSession(params.arguments); + const serverPath = params.arguments.serverPath ?? ZSshClient.DEFAULT_SERVER_PATH; + await ZSshUtils.uninstallServer(session, serverPath, Constants.ZSSH_BIN_DIR); + params.response.console.log( + `Uninstalled Zowe SSH server from ${ConfigUtils.getActiveProfileName("ssh", params.arguments)}`, + ); + } +} diff --git a/packages/sdk/src/ZSshClient.ts b/packages/sdk/src/ZSshClient.ts index f1129f1..6175bfd 100644 --- a/packages/sdk/src/ZSshClient.ts +++ b/packages/sdk/src/ZSshClient.ts @@ -41,6 +41,8 @@ export class ZSshClient extends AbstractRpcClient implements Disposable { reject(err); } else { stream.stderr.on("data", (chunk: Buffer) => { + // const EBCDIC = require("ebcdic-ascii").default; + // chunk = Buffer.from(new EBCDIC("1047").toEBCDIC(chunk.toString("hex")), "hex"); console.log("STDERR:", chunk.toString()); }); resolve(stream); diff --git a/packages/sdk/src/ZSshUtils.ts b/packages/sdk/src/ZSshUtils.ts index d5255c8..4c2f632 100644 --- a/packages/sdk/src/ZSshUtils.ts +++ b/packages/sdk/src/ZSshUtils.ts @@ -57,7 +57,9 @@ export class ZSshUtils { if (err) { reject(err); } else { - ZSshUtils.uploadDir(sftp, localDir, serverPath.replace(/^~/, ".")).then(resolve, reject); + ZSshUtils.uploadDir(sftp, localDir, serverPath.replace(/^~/, ".")) + .then(resolve, reject) + .finally(() => client.end()); } }); }); @@ -73,7 +75,9 @@ export class ZSshUtils { if (err) { reject(err); } else { - ZSshUtils.safeRemoveDir(sftp, localDir, serverPath.replace(/^~/, ".")).then(resolve, reject); + ZSshUtils.safeRemoveDir(sftp, localDir, serverPath.replace(/^~/, ".")) + .then(resolve, reject) + .finally(() => client.end()); } }); });