From 35e1fe8ecdd22554b92aa814bbfe06f583a6f2d2 Mon Sep 17 00:00:00 2001 From: Remie Bolte Date: Wed, 11 Dec 2024 21:44:10 +0100 Subject: [PATCH] fix: get download URL from API and accept username/password for installation --- src/apt/helpers/installApp.ts | 39 +++++++++++++++++++------- src/apt/helpers/runLuceneTimingTest.ts | 2 +- src/apt/helpers/runPerformanceTest.ts | 2 +- src/apt/helpers/runScalabilityTest.ts | 2 +- src/commands/install.ts | 8 +++--- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/apt/helpers/installApp.ts b/src/apt/helpers/installApp.ts index 330b527..e8b24bf 100644 --- a/src/apt/helpers/installApp.ts +++ b/src/apt/helpers/installApp.ts @@ -1,4 +1,4 @@ -import { confirm, input, select } from '@inquirer/prompts'; +import { confirm, input, password as passwordPrompt,select } from '@inquirer/prompts'; import axios from 'axios'; import { Presets, SingleBar } from 'cli-progress'; import { parse } from 'content-disposition'; @@ -29,9 +29,15 @@ const download = async (addonKey: string) => { let tmpFile = join(tmpDir, addonKey); mkdirSync(tmpDir, { recursive: true }); + let downloadUrl = `https://marketplace.atlassian.com/download/plugins/${addonKey}`; + const { data: listing } = await axios.get(`https://marketplace.atlassian.com/rest/2/addons/${addonKey}?hosting=datacenter&withVersion=true`).catch(() => ({ data: null })); + if (listing) { + downloadUrl = listing._embedded?.version?._embedded?.artifact?._links?.binary?.href || downloadUrl; + } + await axios({ method: 'get', - url: `https://marketplace.atlassian.com/download/plugins/${addonKey}`, + url: downloadUrl, responseType: 'stream' }).then(response => { const disposition = parse(response.headers['content-disposition']); @@ -44,7 +50,7 @@ const download = async (addonKey: string) => { return tmpFile; } -export const installApp = async (baseUrl: string, appKey?: string, license: string = app3hour, force?: boolean) => { +export const installApp = async (baseUrl: string, appKey?: string, license: string = app3hour, username: string = 'admin', password: string = 'admin', force?: boolean) => { // If we are in non-interactive mode, we will download it from MPAC if (force) { @@ -77,19 +83,19 @@ export const installApp = async (baseUrl: string, appKey?: string, license: stri timerId = setInterval(() => progressBar.increment(), 1000); // Upload it into the cluster using the UPM REST API - const isInstalled = await uploadToUPM(baseUrl, file, 'admin', 'admin', false); + const isInstalled = await uploadToUPM(baseUrl, file, username, password, false); if (!isInstalled) { throw new Error('Failed to install app into the cluster using the Universal Plugin Manager REST API'); } // Wait for the plugin to be enabled - const isEnabled = await waitForPluginToBeEnabled(appKey, baseUrl, 'admin', 'admin', false); + const isEnabled = await waitForPluginToBeEnabled(appKey, baseUrl, username, password, false); if (!isEnabled) { throw new Error('The app could not be enabled on the cluster, please refer to the application log files for more information'); } // Register the license (use the 3 hour timebomb in non-interactive mode) - const isLicensed = await registerLicense(appKey, license, baseUrl, 'admin', 'admin', false); + const isLicensed = await registerLicense(appKey, license, baseUrl, username, password, false); if (!isLicensed) { throw new Error('The license could not be applied for the app on the cluster, please refer to the application log files for more information'); } @@ -155,6 +161,19 @@ export const installApp = async (baseUrl: string, appKey?: string, license: stri required: true }); + // Ask them nicely for the username + const adminUsername = await input({ + message: 'Please provide the username of a system administrator', + default: username, + required: true + }); + + // Ask them nicely for the username + const adminPassword = await passwordPrompt({ + message: 'Please provide the username of a system administrator', + validate: item => typeof item === 'string' && item.length > 0 + }); + // Tell them we are starting console.log(` Installing the app (${addonKey}) into the cluster using the Universal Plugin Manager REST API`); @@ -167,19 +186,19 @@ export const installApp = async (baseUrl: string, appKey?: string, license: stri const file = await download(addonKey); // Upload it into the cluster using the UPM REST API - const isInstalled = await uploadToUPM(baseUrl, file, 'admin', 'admin', false); + const isInstalled = await uploadToUPM(baseUrl, file, adminUsername, adminPassword, false); if (!isInstalled) { throw new Error('Failed to install app into the cluster using the Universal Plugin Manager REST API'); } // Wait for the plugin to be enabled - const isEnabled = await waitForPluginToBeEnabled(addonKey, baseUrl, 'admin', 'admin', false); + const isEnabled = await waitForPluginToBeEnabled(addonKey, baseUrl, adminUsername, adminPassword, false); if (!isEnabled) { throw new Error('The app could not be enabled on the cluster, please refer to the application log files for more information'); } // Register the provided license - const isLicensed = await registerLicense(addonKey, appLicense, baseUrl, 'admin', 'admin', false); + const isLicensed = await registerLicense(addonKey, appLicense, baseUrl, adminUsername, adminPassword, false); if (!isLicensed) { throw new Error('The license could not be applied for the app on the cluster, please refer to the application log files for more information'); } @@ -200,7 +219,7 @@ export const installApp = async (baseUrl: string, appKey?: string, license: stri // Rub it in their face console.log(` You can now install the app manually into the cluster. - Please go to the following page (login with 'admin'/'admin'): + Please go to the following page: ${baseUrl}/plugins/servlet/upm?source=side_nav_manage_addons `); diff --git a/src/apt/helpers/runLuceneTimingTest.ts b/src/apt/helpers/runLuceneTimingTest.ts index 158c662..bd90e2c 100644 --- a/src/apt/helpers/runLuceneTimingTest.ts +++ b/src/apt/helpers/runLuceneTimingTest.ts @@ -56,7 +56,7 @@ export const runLuceneTimingTest = async (stage: TPerformanceTestTypes, options: const baseUrl = options.baseUrl || await getClusterURL(cwd, options.product); // Install the app into the cluster - await installApp(baseUrl, options.appKey, options.appLicense, options.force); + await installApp(baseUrl, options.appKey, options.appLicense, 'admin', 'admin', options.force); // Inform the user that we will now start the Lucene index test console.log(messages.startTest); diff --git a/src/apt/helpers/runPerformanceTest.ts b/src/apt/helpers/runPerformanceTest.ts index 734b8a6..160180c 100644 --- a/src/apt/helpers/runPerformanceTest.ts +++ b/src/apt/helpers/runPerformanceTest.ts @@ -108,7 +108,7 @@ export const runPerformanceTest = async (stage: TPerformanceTestTypes, options: if (stage === 'regression') { // Install the app into the cluster - await installApp(baseUrl, options.appKey, options.appLicense, options.force); + await installApp(baseUrl, options.appKey, options.appLicense, 'admin', 'admin', options.force); } diff --git a/src/apt/helpers/runScalabilityTest.ts b/src/apt/helpers/runScalabilityTest.ts index c773784..9ffaf5c 100644 --- a/src/apt/helpers/runScalabilityTest.ts +++ b/src/apt/helpers/runScalabilityTest.ts @@ -92,7 +92,7 @@ export const runScalabilityTest = async (stage: TScalabilityTestTypes, options: const baseUrl = await getClusterURL(cwd, options.product); // Install the app into the cluster - await installApp(baseUrl, options.appKey, options.appLicense, options.force); + await installApp(baseUrl, options.appKey, options.appLicense, 'admin', 'admin', options.force); // Allow users to set a different test duration (for validation purposes) const duration = await getDuration(options.force); diff --git a/src/commands/install.ts b/src/commands/install.ts index 998c52e..254fee3 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -36,7 +36,7 @@ const Command = () => { throw new InvalidOptionArgumentError('Missing argument "--appKey", required for installing from the Atlassian Marketplace'); } - await installApp(options.baseUrl, options.appKey, undefined, true); + await installApp(options.baseUrl, options.appKey, undefined, options.username, options.password, true); } else { @@ -91,10 +91,10 @@ If there is a running instance, it will try to install the plugin using QuickRel .showHelpAfterError(true) .addOption(new Option('-w, --watch', 'Watch for filesystem changes to JAR or OBR files in the current working directory').default(false)) .addOption(new Option('-o, --outputDirectory ', 'Output directory where to look for generated JAR or OBR files (defaults to `target`)')) - .addOption(new Option('--obr', 'Upload generated OBR file instead of JAR file when installing the app').default(false)) - .addOption(new Option('--username ', 'The username of the administrator (required with --obr)')) - .addOption(new Option('--password ', 'The password of the administrator (required with --obr)')) .addOption(new Option('-P, --activate-profiles ', 'Comma-delimited list of profiles to activate')) + .addOption(new Option('--obr', 'Upload generated OBR file instead of JAR file when installing the app').default(false)) + .addOption(new Option('--username ', 'The username of the administrator (required with --obr, optional for --mpac)')) + .addOption(new Option('--password ', 'The password of the administrator (required with --obr, optional for --mpac)')) .addOption(new Option('--mpac', 'Install the app from the Atlassian Marketplace')) .addOption(new Option('--baseUrl ', 'URL of the instance (required with --mpac)')) .addOption(new Option('--appKey ', 'The key of the app to be installed (required with --mpac)'))