From 2becce48f8a6dd8f782c15a9c18c60ece4f3ac22 Mon Sep 17 00:00:00 2001 From: Roman Nikitenko Date: Thu, 17 Aug 2023 14:06:40 +0300 Subject: [PATCH] Configure axios instance for the devWorkspaceGenerator lib Signed-off-by: Roman Nikitenko --- code/extensions/che-remote/package.json | 3 +- .../src/axios-certificate-authority.ts | 75 +++++++++++++++++++ code/extensions/che-remote/src/extension.ts | 4 +- code/extensions/che-remote/yarn.lock | 5 ++ 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 code/extensions/che-remote/src/axios-certificate-authority.ts diff --git a/code/extensions/che-remote/package.json b/code/extensions/che-remote/package.json index 90b685a0757..e51280ede11 100644 --- a/code/extensions/che-remote/package.json +++ b/code/extensions/che-remote/package.json @@ -32,7 +32,8 @@ "dependencies": { "vscode-nls": "^5.0.0", "axios": "0.21.2", - "@eclipse-che/che-devworkspace-generator": "0.0.1-96cdbb4" + "@eclipse-che/che-devworkspace-generator": "0.0.1-96cdbb4", + "https": "^1.0.0" }, "devDependencies": { "jest": "27.3.1", diff --git a/code/extensions/che-remote/src/axios-certificate-authority.ts b/code/extensions/che-remote/src/axios-certificate-authority.ts new file mode 100644 index 00000000000..defe75e6d1e --- /dev/null +++ b/code/extensions/che-remote/src/axios-certificate-authority.ts @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2023 Red Hat, Inc. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + ***********************************************************************/ + +/* eslint-disable header/header */ + +import * as axios from 'axios'; +import * as fs from 'fs-extra'; +import https from 'https'; +import path from 'path'; + +const DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH = '/public-certs'; +const CHE_SELF_SIGNED_MOUNT_PATH = process.env.CHE_SELF_SIGNED_MOUNT_PATH; + +const certificateAuthority = getCertificateAuthority( + CHE_SELF_SIGNED_MOUNT_PATH ? CHE_SELF_SIGNED_MOUNT_PATH : DEFAULT_CHE_SELF_SIGNED_MOUNT_PATH, +); + +export const axiosInstance = certificateAuthority + ? axios.default.create({ + httpsAgent: new https.Agent({ + ca: certificateAuthority, + }), + }) + : axios.default; + +function getCertificateAuthority(certPath: string): Buffer[] | undefined { + if (!fs.existsSync(certPath)) { + return undefined; + } + + const certificateAuthority: Buffer[] = []; + searchCertificate(certPath, certificateAuthority); + + return certificateAuthority.length > 0 ? certificateAuthority : undefined; +} + +function searchCertificate( + certPath: string, + certificateAuthority: Buffer[], + subdirLevel = 1, +): void { + const maxSubdirQuantity = 10; + const maxSubdirLevel = 5; + + const tmpPaths: string[] = []; + try { + const publicCertificates = fs.readdirSync(certPath); + for (const publicCertificate of publicCertificates) { + const newPath = path.join(certPath, publicCertificate); + if (fs.lstatSync(newPath).isDirectory()) { + if (tmpPaths.length < maxSubdirQuantity) { + tmpPaths.push(newPath); + } + } else { + const fullPath = path.join(certPath, publicCertificate); + certificateAuthority.push(fs.readFileSync(fullPath)); + } + } + } catch (e) { + // no-op + } + + if (subdirLevel < maxSubdirLevel) { + for (const path of tmpPaths) { + searchCertificate(path, certificateAuthority, ++subdirLevel); + } + } +} diff --git a/code/extensions/che-remote/src/extension.ts b/code/extensions/che-remote/src/extension.ts index af06539252b..54d6f61f29a 100644 --- a/code/extensions/che-remote/src/extension.ts +++ b/code/extensions/che-remote/src/extension.ts @@ -12,9 +12,9 @@ // local import to find the correct type import { Main as DevWorkspaceGenerator } from '@eclipse-che/che-devworkspace-generator/lib/main'; -import * as axios from 'axios'; import * as fs from 'fs-extra'; import * as vscode from 'vscode'; +import { axiosInstance } from './axios-certificate-authority'; const DEVFILE_NAME = 'devfile.yaml'; const DOT_DEVFILE_NAME = '.devfile.yaml'; @@ -120,7 +120,7 @@ async function updateDevfile(cheApi: any): Promise { const pluginRegistryUrl = process.env.CHE_PLUGIN_REGISTRY_INTERNAL_URL; console.info(`Using ${pluginRegistryUrl} to generate a new Devfile Context`); - const newContent = await devWorkspaceGenerator.generateDevfileContext({ devfilePath, editorContent: EDITOR_CONTENT_STUB, pluginRegistryUrl, projects: [] }, axios.default); + const newContent = await devWorkspaceGenerator.generateDevfileContext({ devfilePath, editorContent: EDITOR_CONTENT_STUB, pluginRegistryUrl, projects: [] }, axiosInstance); if (newContent) { newContent.devWorkspace.spec!.template!.projects = projects; await devfileService.updateDevfile(newContent.devWorkspace.spec?.template); diff --git a/code/extensions/che-remote/yarn.lock b/code/extensions/che-remote/yarn.lock index 564fd938cc0..f4f25543107 100644 --- a/code/extensions/che-remote/yarn.lock +++ b/code/extensions/che-remote/yarn.lock @@ -1654,6 +1654,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https/-/https-1.0.0.tgz#3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4" + integrity sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"