Upgrade ADF CLI to latest Commander library (#9473)

* build(deps-dev): bump commander from 6.2.1 to 12.0.0

Bumps [commander](https://github.com/tj/commander.js) from 6.2.1 to 12.0.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v6.2.1...v12.0.0)

---
updated-dependencies:
- dependency-name: commander
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: migrate CLI to latest commander library

* chore: migrate CLI to latest commander library [ci:force]

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Denys Vuika
2024-03-26 09:36:49 -04:00
committed by GitHub
parent 7cca017c12
commit 9d7608817d
13 changed files with 241 additions and 143 deletions

View File

@@ -15,14 +15,33 @@
* limitations under the License.
*/
import { AdminTenantsApi, AdminUsersApi, AlfrescoApi, TenantRepresentation, AppDefinitionsApi, RuntimeAppDefinitionsApi, UserRepresentation, AppDefinitionUpdateResultRepresentation } from '@alfresco/js-api';
import {
AdminTenantsApi,
AdminUsersApi,
AlfrescoApi,
TenantRepresentation,
AppDefinitionsApi,
RuntimeAppDefinitionsApi,
UserRepresentation,
AppDefinitionUpdateResultRepresentation
} from '@alfresco/js-api';
import { argv, exit } from 'node:process';
import { spawnSync } from 'node:child_process';
import { createReadStream } from 'node:fs';
const program = require('commander');
const path = require('path');
import { Command } from 'commander';
import * as path from 'path';
import { logger } from './logger';
const { throwError } = require('rxjs');
import { throwError } from 'rxjs';
interface InitApsEnvArgs {
host?: string;
clientId?: string;
username?: string;
password?: string;
license?: string;
}
const program = new Command();
const MAX_RETRY = 10;
let counter = 0;
const TIMEOUT = 6000;
@@ -37,7 +56,6 @@ let alfrescoJsApi: AlfrescoApi;
* Init APS command
*/
export default async function main() {
program
.version('0.1.0')
.option('--host [type]', 'Remote environment host')
@@ -47,23 +65,25 @@ export default async function main() {
.option('--license [type]', 'APS license S3 path ')
.parse(argv);
await checkEnv();
const opts = program.opts<InitApsEnvArgs>();
await checkEnv(opts);
logger.info(`***** Step 1 - Check License *****`);
let licenceUploaded = false;
const hasValidLicense = await hasLicense() ;
const hasValidLicense = await hasLicense(opts);
if (!hasValidLicense) {
logger.info(`Aps License missing`);
const isLicenseFileDownloaded = await downloadLicenseFile(program.license);
const isLicenseFileDownloaded = await downloadLicenseFile(opts.license);
if (isLicenseFileDownloaded) {
licenceUploaded = await updateLicense();
licenceUploaded = await updateLicense(opts);
}
} else {
licenceUploaded = true;
logger.info(`Aps License present`);
}
let tenantId;
let tenantId: number;
if (licenceUploaded) {
logger.info(`***** Step 2 - Check Tenant *****`);
logger.info(`is tenantId:${TENANT_DEFAULT_ID} with name:${TENANT_DEFAULT_NAME} present?`);
@@ -75,13 +95,13 @@ export default async function main() {
tenantId = await createDefaultTenant(TENANT_DEFAULT_NAME);
}
logger.info(`***** Step 3 - Add Content Repo *****`);
const isContentPresent = await isContentRepoPresent(TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME);
const isContentPresent = await isContentRepoPresent(opts, TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME);
if (!isContentPresent) {
logger.info(`No content repo with name ${CONTENT_DEFAULT_NAME} found`);
await addContentRepoWithBasic(TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME);
await addContentRepoWithBasic(opts, TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME);
}
logger.info(`***** Step 4 - Create users *****`);
const users = await getDefaultApsUsersFromRealm();
const users = await getDefaultApsUsersFromRealm(opts);
if (tenantId && users && users.length > 0) {
for (let i = 0; i < users.length; i++) {
await createUsers(tenantId, users[i]);
@@ -89,19 +109,17 @@ export default async function main() {
for (let i = 0; i < users.length; i++) {
logger.info('Impersonate user: ' + users[i].username);
await alfrescoJsApi.login(users[i].username, 'password');
await authorizeUserToContentRepo(users[i]);
await authorizeUserToContentRepo(opts, users[i]);
const defaultUser = 'hruser';
if (users[i].username.includes(defaultUser)) {
logger.info(`***** Step initialize APS apps for user ${defaultUser} *****`);
await initializeDefaultApps();
}
}
} else {
logger.info('Something went wrong. Was not able to create the users');
}
} catch (error) {
logger.info(`Aps something went wrong. Tenant id ${tenantId}`);
exit(1);
@@ -110,7 +128,6 @@ export default async function main() {
logger.info('APS license error: check the configuration');
exit(1);
}
}
/**
@@ -131,23 +148,25 @@ async function initializeDefaultApps() {
/**
* Check environment
*
* @param opts command options
*/
async function checkEnv() {
async function checkEnv(opts: InitApsEnvArgs) {
try {
alfrescoJsApi = new AlfrescoApi({
provider: 'ALL',
hostBpm: program.host,
hostEcm: program.host,
hostBpm: opts.host,
hostEcm: opts.host,
authType: 'OAUTH',
contextRoot: 'alfresco',
oauth2: {
host: `${program.host}/auth/realms/alfresco`,
clientId: `${program.clientId}`,
host: `${opts.host}/auth/realms/alfresco`,
clientId: `${opts.clientId}`,
scope: 'openid',
redirectUri: '/'
}
});
await alfrescoJsApi.login(program.username, program.password);
await alfrescoJsApi.login(opts.username, opts.password);
} catch (e) {
if (e.error.code === 'ETIMEDOUT') {
logger.error('The env is not reachable. Terminating');
@@ -161,7 +180,7 @@ async function checkEnv() {
} else {
logger.error(`Retry in 1 minute attempt N ${counter}`);
sleep(TIMEOUT);
await checkEnv();
await checkEnv(opts);
}
}
}
@@ -203,7 +222,7 @@ async function createDefaultTenant(tenantName: string) {
const tenantPost = {
active: true,
maxUsers: 10000,
name : tenantName
name: tenantName
};
try {
@@ -212,7 +231,7 @@ async function createDefaultTenant(tenantName: string) {
logger.info(`APS: Tenant ${tenantName} created with id: ${tenant.id}`);
return tenant.id;
} catch (error) {
logger.info(`APS: not able to create the default tenant: ${JSON.parse(error.message)}` );
logger.info(`APS: not able to create the default tenant: ${JSON.parse(error.message)}`);
return null;
}
}
@@ -242,19 +261,21 @@ async function createUsers(tenantId: number, user: any) {
logger.info(`APS: User ${userInfo.email} created with id: ${userInfo.id}`);
return user;
} catch (error) {
logger.info(`APS: not able to create the default user: ${error.message}` );
logger.info(`APS: not able to create the default user: ${error.message}`);
}
}
/**
* Update Activiti license
*
* @param opts command options
*/
async function updateLicense() {
async function updateLicense(opts: InitApsEnvArgs) {
const fileContent = createReadStream(path.join(__dirname, '/activiti.lic'));
try {
await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/license`,
`${opts.host}/activiti-app/app/rest/license`,
'POST',
{},
{},
@@ -283,7 +304,7 @@ async function isDefaultAppDeployed(appName: string): Promise<boolean> {
try {
const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi);
const availableApps = await runtimeAppDefinitionsApi.getAppDefinitions();
const defaultApp = availableApps.data?.filter(app => app.name?.includes(appName));
const defaultApp = availableApps.data?.filter((app) => app.name?.includes(appName));
return defaultApp && defaultApp.length > 0;
} catch (error) {
logger.error(`Aps app failed to import/Publish!`);
@@ -304,7 +325,7 @@ async function importPublishApp(appName: string): Promise<AppDefinitionUpdateRes
try {
const appDefinitionsApi = new AppDefinitionsApi(alfrescoJsApi);
const result = await appDefinitionsApi.importAndPublishApp(fileContent, {renewIdmEntries: true});
const result = await appDefinitionsApi.importAndPublishApp(fileContent, { renewIdmEntries: true });
logger.info(`Aps app imported and published!`);
return result;
} catch (error) {
@@ -321,7 +342,7 @@ async function importPublishApp(appName: string): Promise<AppDefinitionUpdateRes
async function deployApp(appDefinitionId: number) {
logger.info(`Deploy app with id ${appDefinitionId}`);
const body = {
appDefinitions: [{id: appDefinitionId}]
appDefinitions: [{ id: appDefinitionId }]
};
try {
@@ -335,11 +356,13 @@ async function deployApp(appDefinitionId: number) {
/**
* Checks if Activiti app has license
*
* @param opts command options
*/
async function hasLicense(): Promise<boolean> {
async function hasLicense(opts: InitApsEnvArgs): Promise<boolean> {
try {
const license = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/license`,
`${opts.host}/activiti-app/app/rest/license`,
'GET',
{},
{},
@@ -356,18 +379,20 @@ async function hasLicense(): Promise<boolean> {
logger.info(`Aps does NOT have a valid License!`);
return false;
} catch (error) {
logger.error(`Aps not able to check the license` );
logger.error(`Aps not able to check the license`);
return false;
}
}
/**
* Get default users from the realm
*
* @param opts command options
*/
async function getDefaultApsUsersFromRealm() {
async function getDefaultApsUsersFromRealm(opts: InitApsEnvArgs) {
try {
const users: any[] = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/auth/admin/realms/alfresco/users`,
`${opts.host}/auth/admin/realms/alfresco/users`,
'GET',
{},
{ max: 1000 },
@@ -378,11 +403,11 @@ async function getDefaultApsUsersFromRealm() {
['application/json']
);
const usernamesOfApsDefaultUsers = ['hruser', 'salesuser', 'superadminuser'];
const apsDefaultUsers = users.filter(user => usernamesOfApsDefaultUsers.includes(user.username));
const apsDefaultUsers = users.filter((user) => usernamesOfApsDefaultUsers.includes(user.username));
logger.info(`Keycloak found ${apsDefaultUsers.length} users`);
return apsDefaultUsers;
} catch (error) {
logger.error(`APS: not able to fetch user: ${error.message}` );
logger.error(`APS: not able to fetch user: ${error.message}`);
return null;
}
}
@@ -390,13 +415,14 @@ async function getDefaultApsUsersFromRealm() {
/**
* Validate that ACS repo for Activiti is present
*
* @param opts command options
* @param tenantId tenant id
* @param contentName content service name
*/
async function isContentRepoPresent(tenantId: number, contentName: string): Promise<boolean> {
async function isContentRepoPresent(opts: InitApsEnvArgs, tenantId: number, contentName: string): Promise<boolean> {
try {
const contentRepos = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/integration/alfresco?tenantId=${tenantId}`,
`${opts.host}/activiti-app/app/rest/integration/alfresco?tenantId=${tenantId}`,
'GET',
{},
{},
@@ -406,9 +432,9 @@ async function isContentRepoPresent(tenantId: number, contentName: string): Prom
['application/json'],
['application/json']
);
return !!contentRepos.data.find(repo => repo.name === contentName);
return !!contentRepos.data.find((repo) => repo.name === contentName);
} catch (error) {
logger.error(`APS: not able to create content: ${error.message}` );
logger.error(`APS: not able to create content: ${error.message}`);
return null;
}
}
@@ -416,18 +442,19 @@ async function isContentRepoPresent(tenantId: number, contentName: string): Prom
/**
* Add content service with basic auth
*
* @param opts command options
* @param tenantId tenant id
* @param name content name
*/
async function addContentRepoWithBasic(tenantId: number, name: string) {
async function addContentRepoWithBasic(opts: InitApsEnvArgs, tenantId: number, name: string) {
logger.info(`Create Content with name ${name} and basic auth`);
const body = {
alfrescoTenantId: '',
authenticationType: 'basic',
name,
repositoryUrl: `${program.host}/alfresco`,
shareUrl: `${program.host}/share`,
repositoryUrl: `${opts.host}/alfresco`,
shareUrl: `${opts.host}/share`,
// sitesFolder: '', not working on activiti 1.11.1.1
tenantId,
version: '6.1.1'
@@ -435,7 +462,7 @@ async function addContentRepoWithBasic(tenantId: number, name: string) {
try {
const content = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/integration/alfresco`,
`${opts.host}/activiti-app/app/rest/integration/alfresco`,
'POST',
{},
{},
@@ -448,20 +475,21 @@ async function addContentRepoWithBasic(tenantId: number, name: string) {
logger.info(`Content created!`);
return content;
} catch (error) {
logger.error(`APS: not able to create content: ${error.message}` );
logger.error(`APS: not able to create content: ${error.message}`);
}
}
/**
* Authorize activiti user to ACS repo
*
* @param opts command options
* @param user user object
*/
async function authorizeUserToContentRepo(user: any) {
async function authorizeUserToContentRepo(opts: InitApsEnvArgs, user: any) {
logger.info(`Authorize user ${user.email}`);
try {
const content = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/integration/alfresco`,
`${opts.host}/activiti-app/app/rest/integration/alfresco`,
'GET',
{},
{},
@@ -475,28 +503,29 @@ async function authorizeUserToContentRepo(user: any) {
if (content.data) {
for (let i = 0; i < content.data.length; i++) {
if (content.data[i].authenticationType === 'basic') {
await authorizeUserToContentWithBasic(user.username, content.data[i].id);
await authorizeUserToContentWithBasic(opts, user.username, content.data[i].id);
}
}
}
return;
} catch (error) {
logger.error(`APS: not able to authorize content: ${error.message}` );
logger.error(`APS: not able to authorize content: ${error.message}`);
}
}
/**
* Authorize user with content using basic auth
*
* @param opts command options
* @param username username
* @param contentId content id
*/
async function authorizeUserToContentWithBasic(username: string, contentId: string) {
async function authorizeUserToContentWithBasic(opts: InitApsEnvArgs, username: string, contentId: string) {
logger.info(`Authorize ${username} on contentId: ${contentId} in basic auth`);
try {
const body = {username, password: 'password'};
const body = { username, password: 'password' };
const content = await alfrescoJsApi.oauth2Auth.callCustomApi(
`${program.host}/activiti-app/app/rest/integration/alfresco/${contentId}/account`,
`${opts.host}/activiti-app/app/rest/integration/alfresco/${contentId}/account`,
'POST',
{},
{},
@@ -509,7 +538,7 @@ async function authorizeUserToContentWithBasic(username: string, contentId: stri
logger.info(`User authorized!`);
return content;
} catch (error) {
logger.error(`APS: not able to authorize content: ${error.message}` );
logger.error(`APS: not able to authorize content: ${error.message}`);
}
}
@@ -519,12 +548,7 @@ async function authorizeUserToContentWithBasic(username: string, contentId: stri
* @param apsLicensePath path to license file
*/
async function downloadLicenseFile(apsLicensePath: string) {
const args = [
`s3`,
`cp`,
apsLicensePath,
`./`
];
const args = [`s3`, `cp`, apsLicensePath, `./`];
const result = spawnSync(`aws`, args, {
cwd: path.resolve(__dirname, `./`),
shell: false
@@ -545,5 +569,5 @@ async function downloadLicenseFile(apsLicensePath: string) {
*/
function sleep(delay: number) {
const start = new Date().getTime();
while (new Date().getTime() < start + delay) { }
while (new Date().getTime() < start + delay) {}
}