Skip to content

Commit

Permalink
fix: get download URL from API and accept username/password for insta…
Browse files Browse the repository at this point in the history
…llation
  • Loading branch information
remie committed Dec 11, 2024
1 parent 58ca8f9 commit 35e1fe8
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 17 deletions.
39 changes: 29 additions & 10 deletions src/apt/helpers/installApp.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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']);
Expand All @@ -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) {
Expand Down Expand Up @@ -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');
}
Expand Down Expand Up @@ -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`);
Expand All @@ -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');
}
Expand All @@ -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
`);
Expand Down
2 changes: 1 addition & 1 deletion src/apt/helpers/runLuceneTimingTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/apt/helpers/runPerformanceTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}

Expand Down
2 changes: 1 addition & 1 deletion src/apt/helpers/runScalabilityTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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 <directory>', '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 <username>', 'The username of the administrator (required with --obr)'))
.addOption(new Option('--password <password>', 'The password of the administrator (required with --obr)'))
.addOption(new Option('-P, --activate-profiles <arg>', '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 <username>', 'The username of the administrator (required with --obr, optional for --mpac)'))
.addOption(new Option('--password <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>', 'URL of the instance (required with --mpac)'))
.addOption(new Option('--appKey <key>', 'The key of the app to be installed (required with --mpac)'))
Expand Down

0 comments on commit 35e1fe8

Please sign in to comment.